diff options
Diffstat (limited to 'compiler/stable_mir/src/mir/mono.rs')
-rw-r--r-- | compiler/stable_mir/src/mir/mono.rs | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs new file mode 100644 index 000000000..8f5333498 --- /dev/null +++ b/compiler/stable_mir/src/mir/mono.rs @@ -0,0 +1,102 @@ +use crate::mir::Body; +use crate::ty::{FnDef, GenericArgs, IndexedVal, Ty}; +use crate::{with, CrateItem, DefId, Error, Opaque}; +use std::fmt::Debug; + +#[derive(Clone, Debug)] +pub enum MonoItem { + Fn(Instance), + Static(StaticDef), + GlobalAsm(Opaque), +} + +#[derive(Copy, Clone, Debug)] +pub struct Instance { + /// The type of instance. + pub kind: InstanceKind, + /// An ID used to get the instance definition from the compiler. + /// Do not use this field directly. + pub def: InstanceDef, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +pub enum InstanceKind { + /// A user defined item. + Item, + /// A compiler intrinsic function. + Intrinsic, + /// A virtual function definition stored in a VTable. + Virtual, + /// A compiler generated shim. + Shim, +} + +impl Instance { + /// Get the body of an Instance. The body will be eagerly monomorphized. + pub fn body(&self) -> Body { + with(|context| context.instance_body(self.def)) + } + + /// Get the instance type with generic substitutions applied and lifetimes erased. + pub fn ty(&self) -> Ty { + with(|context| context.instance_ty(self.def)) + } + + pub fn mangled_name(&self) -> String { + with(|context| context.instance_mangled_name(self.def)) + } + + /// Resolve an instance starting from a function definition and generic arguments. + pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> { + with(|context| { + context.resolve_instance(def, args).ok_or_else(|| { + crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")) + }) + }) + } +} + +/// Try to convert a crate item into an instance. +/// The item cannot be generic in order to be converted into an instance. +impl TryFrom<CrateItem> for Instance { + type Error = crate::Error; + + fn try_from(item: CrateItem) -> Result<Self, Self::Error> { + with(|context| { + if !context.requires_monomorphization(item.0) { + Ok(context.mono_instance(item)) + } else { + Err(Error::new("Item requires monomorphization".to_string())) + } + }) + } +} + +/// Try to convert an instance into a crate item. +/// Only user defined instances can be converted. +impl TryFrom<Instance> for CrateItem { + type Error = crate::Error; + + fn try_from(value: Instance) -> Result<Self, Self::Error> { + if value.kind == InstanceKind::Item { + Ok(CrateItem(with(|context| context.instance_def_id(value.def)))) + } else { + Err(Error::new(format!("Item kind `{:?}` cannot be converted", value.kind))) + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct InstanceDef(usize); + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct StaticDef(pub DefId); + +impl IndexedVal for InstanceDef { + fn to_val(index: usize) -> Self { + InstanceDef(index) + } + fn to_index(&self) -> usize { + self.0 + } +} |