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 {
pub kind: InstanceKind,
pub def: InstanceDef,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum InstanceKind {
Item,
Intrinsic,
Virtual,
Shim,
}
impl Instance {
pub fn body(&self) -> Body {
with(|context| context.instance_body(self.def))
}
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))
}
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:?}`"))
})
})
}
}
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()))
}
})
}
}
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
}
}