Skip to main content

rustc_public/mir/
mono.rs

1use std::fmt::{Debug, Formatter};
2use std::io;
3
4use rustc_public_bridge::bridge;
5use serde::Serialize;
6
7use crate::abi::FnAbi;
8use crate::crate_def::CrateDef;
9use crate::mir::Body;
10use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, Ty, index_impl};
11use crate::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, ThreadLocalIndex, with};
12
13#[derive(#[automatically_derived]
impl ::core::clone::Clone for MonoItem {
    #[inline]
    fn clone(&self) -> MonoItem {
        match self {
            MonoItem::Fn(__self_0) =>
                MonoItem::Fn(::core::clone::Clone::clone(__self_0)),
            MonoItem::Static(__self_0) =>
                MonoItem::Static(::core::clone::Clone::clone(__self_0)),
            MonoItem::GlobalAsm(__self_0) =>
                MonoItem::GlobalAsm(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for MonoItem {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            MonoItem::Fn(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Fn",
                    &__self_0),
            MonoItem::Static(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Static",
                    &__self_0),
            MonoItem::GlobalAsm(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "GlobalAsm", &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for MonoItem {
    #[inline]
    fn eq(&self, other: &MonoItem) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (MonoItem::Fn(__self_0), MonoItem::Fn(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (MonoItem::Static(__self_0), MonoItem::Static(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (MonoItem::GlobalAsm(__self_0), MonoItem::GlobalAsm(__arg1_0))
                    => __self_0 == __arg1_0,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for MonoItem {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Instance>;
        let _: ::core::cmp::AssertParamIsEq<StaticDef>;
        let _: ::core::cmp::AssertParamIsEq<Opaque>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for MonoItem {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            MonoItem::Fn(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            MonoItem::Static(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            MonoItem::GlobalAsm(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for MonoItem {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    MonoItem::Fn(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "MonoItem", 0u32, "Fn", __field0),
                    MonoItem::Static(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "MonoItem", 1u32, "Static", __field0),
                    MonoItem::GlobalAsm(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "MonoItem", 2u32, "GlobalAsm", __field0),
                }
            }
        }
    };Serialize)]
14pub enum MonoItem {
15    Fn(Instance),
16    Static(StaticDef),
17    GlobalAsm(Opaque),
18}
19
20#[derive(#[automatically_derived]
impl ::core::marker::Copy for Instance { }Copy, #[automatically_derived]
impl ::core::clone::Clone for Instance {
    #[inline]
    fn clone(&self) -> Instance {
        let _: ::core::clone::AssertParamIsClone<InstanceKind>;
        let _: ::core::clone::AssertParamIsClone<InstanceDef>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Instance {
    #[inline]
    fn eq(&self, other: &Instance) -> bool {
        self.kind == other.kind && self.def == other.def
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Instance {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<InstanceKind>;
        let _: ::core::cmp::AssertParamIsEq<InstanceDef>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Instance {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.kind, state);
        ::core::hash::Hash::hash(&self.def, state)
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for Instance {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "Instance", false as usize + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "kind", &self.kind)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "def", &self.def)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize)]
21pub struct Instance {
22    /// The type of instance.
23    pub kind: InstanceKind,
24    /// An ID used to get the instance definition from the compiler.
25    /// Do not use this field directly.
26    pub def: InstanceDef,
27}
28
29#[derive(#[automatically_derived]
impl ::core::marker::Copy for InstanceKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for InstanceKind {
    #[inline]
    fn clone(&self) -> InstanceKind {
        let _: ::core::clone::AssertParamIsClone<usize>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for InstanceKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            InstanceKind::Item =>
                ::core::fmt::Formatter::write_str(f, "Item"),
            InstanceKind::Intrinsic =>
                ::core::fmt::Formatter::write_str(f, "Intrinsic"),
            InstanceKind::LlvmIntrinsic =>
                ::core::fmt::Formatter::write_str(f, "LlvmIntrinsic"),
            InstanceKind::Virtual { idx: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f,
                    "Virtual", "idx", &__self_0),
            InstanceKind::Shim =>
                ::core::fmt::Formatter::write_str(f, "Shim"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for InstanceKind {
    #[inline]
    fn eq(&self, other: &InstanceKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (InstanceKind::Virtual { idx: __self_0 },
                    InstanceKind::Virtual { idx: __arg1_0 }) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for InstanceKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<usize>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for InstanceKind {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            InstanceKind::Virtual { idx: __self_0 } =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for InstanceKind {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    InstanceKind::Item =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "InstanceKind", 0u32, "Item"),
                    InstanceKind::Intrinsic =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "InstanceKind", 1u32, "Intrinsic"),
                    InstanceKind::LlvmIntrinsic =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "InstanceKind", 2u32, "LlvmIntrinsic"),
                    InstanceKind::Virtual { ref idx } => {
                        let mut __serde_state =
                            _serde::Serializer::serialize_struct_variant(__serializer,
                                    "InstanceKind", 3u32, "Virtual", 0 + 1)?;
                        _serde::ser::SerializeStructVariant::serialize_field(&mut __serde_state,
                                "idx", idx)?;
                        _serde::ser::SerializeStructVariant::end(__serde_state)
                    }
                    InstanceKind::Shim =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "InstanceKind", 4u32, "Shim"),
                }
            }
        }
    };Serialize)]
30pub enum InstanceKind {
31    /// A user defined item.
32    Item,
33    /// A compiler intrinsic function.
34    Intrinsic,
35    /// An LLVM intrinsic function.
36    LlvmIntrinsic,
37    /// A virtual function definition stored in a VTable.
38    /// The `idx` field indicates the position in the VTable for this instance.
39    Virtual { idx: usize },
40    /// A compiler generated shim.
41    Shim,
42}
43
44impl Instance {
45    /// Get the arguments this instance was instantiated with.
46    pub fn args(&self) -> GenericArgs {
47        with(|cx| cx.instance_args(self.def))
48    }
49
50    /// Get the body of an Instance.
51    ///
52    /// The body will be eagerly monomorphized and all constants will already be evaluated.
53    ///
54    /// This method will return the intrinsic fallback body if one was defined.
55    pub fn body(&self) -> Option<Body> {
56        with(|context| context.instance_body(self.def))
57    }
58
59    /// Check whether this instance has a body available.
60    ///
61    /// For intrinsics with fallback body, this will return `true`. It is up to the user to decide
62    /// whether to specialize the intrinsic or to use its fallback body.
63    ///
64    /// For more information on fallback body, see <https://github.com/rust-lang/rust/issues/93145>.
65    ///
66    /// This call is much cheaper than `instance.body().is_some()`, since it doesn't try to build
67    /// the rustc_public's IR body.
68    pub fn has_body(&self) -> bool {
69        with(|cx| cx.has_body(self.def.def_id()))
70    }
71
72    pub fn is_foreign_item(&self) -> bool {
73        with(|cx| cx.is_foreign_item(self.def.def_id()))
74    }
75
76    /// Get the instance type with generic instantiations applied and lifetimes erased.
77    pub fn ty(&self) -> Ty {
78        with(|context| context.instance_ty(self.def))
79    }
80
81    /// Retrieve information about this instance binary interface.
82    pub fn fn_abi(&self) -> Result<FnAbi, Error> {
83        with(|cx| cx.instance_abi(self.def))
84    }
85
86    /// Retrieve the instance's mangled name used for calling the given instance.
87    ///
88    /// This will also look up the correct name of instances from upstream crates.
89    pub fn mangled_name(&self) -> Symbol {
90        with(|context| context.instance_mangled_name(self.def))
91    }
92
93    /// Retrieve the instance name for diagnostic messages.
94    ///
95    /// This will return the specialized name, e.g., `std::vec::Vec<u8>::new`.
96    pub fn name(&self) -> Symbol {
97        with(|context| context.instance_name(self.def, false))
98    }
99
100    /// Return a trimmed name of the given instance including its args.
101    ///
102    /// If a symbol name can only be imported from one place for a type, and as
103    /// long as it was not glob-imported anywhere in the current crate, we trim its
104    /// path and print only the name.
105    pub fn trimmed_name(&self) -> Symbol {
106        with(|context| context.instance_name(self.def, true))
107    }
108
109    /// Retrieve the plain intrinsic name of an instance if it's an intrinsic.
110    ///
111    /// The plain name does not include type arguments (as `trimmed_name` does),
112    /// which is more convenient to match with intrinsic symbols.
113    pub fn intrinsic_name(&self) -> Option<Symbol> {
114        match self.kind {
115            InstanceKind::Intrinsic => {
116                Some(with(|context| context.intrinsic(self.def.def_id()).unwrap().fn_name()))
117            }
118            InstanceKind::LlvmIntrinsic
119            | InstanceKind::Item
120            | InstanceKind::Virtual { .. }
121            | InstanceKind::Shim => None,
122        }
123    }
124
125    /// Resolve an instance starting from a function definition and generic arguments.
126    pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
127        with(|context| {
128            context.resolve_instance(def, args).ok_or_else(|| {
129                bridge::Error::new(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Failed to resolve `{0:?}` with `{1:?}`",
                def, args))
    })format!("Failed to resolve `{def:?}` with `{args:?}`"))
130            })
131        })
132    }
133
134    /// Resolve the drop in place for a given type.
135    pub fn resolve_drop_in_place(ty: Ty) -> Instance {
136        with(|cx| cx.resolve_drop_in_place(ty))
137    }
138
139    /// Resolve an instance for a given function pointer.
140    pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
141        with(|context| {
142            context.resolve_for_fn_ptr(def, args).ok_or_else(|| {
143                bridge::Error::new(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Failed to resolve `{0:?}` with `{1:?}`",
                def, args))
    })format!("Failed to resolve `{def:?}` with `{args:?}`"))
144            })
145        })
146    }
147
148    /// Resolve a closure with the expected kind.
149    pub fn resolve_closure(
150        def: ClosureDef,
151        args: &GenericArgs,
152        kind: ClosureKind,
153    ) -> Result<Instance, Error> {
154        with(|context| {
155            context.resolve_closure(def, args, kind).ok_or_else(|| {
156                bridge::Error::new(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Failed to resolve `{0:?}` with `{1:?}`",
                def, args))
    })format!("Failed to resolve `{def:?}` with `{args:?}`"))
157            })
158        })
159    }
160
161    /// Check whether this instance is an empty shim.
162    ///
163    /// Allow users to check if this shim can be ignored when called directly.
164    ///
165    /// We have decided not to export different types of Shims to rustc_public users, however, this
166    /// is a query that can be very helpful for users when processing DropGlue.
167    ///
168    /// When generating code for a Drop terminator, users can ignore an empty drop glue.
169    /// These shims are only needed to generate a valid Drop call done via VTable.
170    pub fn is_empty_shim(&self) -> bool {
171        self.kind == InstanceKind::Shim && with(|cx| cx.is_empty_drop_shim(self.def))
172    }
173
174    /// Try to constant evaluate the instance into a constant with the given type.
175    ///
176    /// This can be used to retrieve a constant that represents an intrinsic return such as
177    /// `type_id`.
178    pub fn try_const_eval(&self, const_ty: Ty) -> Result<Allocation, Error> {
179        with(|cx| cx.eval_instance(self.def, const_ty))
180    }
181
182    /// Emit the body of this instance if it has one.
183    pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
184        if let Some(body) = self.body() { body.dump(w, &self.name()) } else { Ok(()) }
185    }
186}
187
188impl Debug for Instance {
189    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
190        f.debug_struct("Instance")
191            .field("kind", &self.kind)
192            .field("def", &self.mangled_name())
193            .field("args", &self.args())
194            .finish()
195    }
196}
197
198/// Try to convert a crate item into an instance.
199/// The item cannot be generic in order to be converted into an instance.
200impl TryFrom<CrateItem> for Instance {
201    type Error = crate::Error;
202
203    fn try_from(item: CrateItem) -> Result<Self, Self::Error> {
204        with(|context| {
205            let def_id = item.def_id();
206            if !context.requires_monomorphization(def_id) {
207                Ok(context.mono_instance(def_id))
208            } else {
209                Err(bridge::Error::new("Item requires monomorphization".to_string()))
210            }
211        })
212    }
213}
214
215/// Try to convert an instance into a crate item.
216/// Only user defined instances can be converted.
217impl TryFrom<Instance> for CrateItem {
218    type Error = crate::Error;
219
220    fn try_from(value: Instance) -> Result<Self, Self::Error> {
221        with(|context| {
222            if value.kind == InstanceKind::Item && context.has_body(value.def.def_id()) {
223                Ok(CrateItem(context.instance_def_id(value.def)))
224            } else {
225                Err(bridge::Error::new(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Item kind `{0:?}` cannot be converted",
                value.kind))
    })format!("Item kind `{:?}` cannot be converted", value.kind)))
226            }
227        })
228    }
229}
230
231impl From<Instance> for MonoItem {
232    fn from(value: Instance) -> Self {
233        MonoItem::Fn(value)
234    }
235}
236
237impl From<StaticDef> for MonoItem {
238    fn from(value: StaticDef) -> Self {
239        MonoItem::Static(value)
240    }
241}
242
243impl From<StaticDef> for CrateItem {
244    fn from(value: StaticDef) -> Self {
245        CrateItem(value.0)
246    }
247}
248
249#[derive(#[automatically_derived]
impl ::core::clone::Clone for InstanceDef {
    #[inline]
    fn clone(&self) -> InstanceDef {
        let _: ::core::clone::AssertParamIsClone<usize>;
        let _: ::core::clone::AssertParamIsClone<ThreadLocalIndex>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InstanceDef { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for InstanceDef {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field2_finish(f, "InstanceDef",
            &self.0, &&self.1)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for InstanceDef {
    #[inline]
    fn eq(&self, other: &InstanceDef) -> bool {
        self.0 == other.0 && self.1 == other.1
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for InstanceDef {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<usize>;
        let _: ::core::cmp::AssertParamIsEq<ThreadLocalIndex>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for InstanceDef {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state);
        ::core::hash::Hash::hash(&self.1, state)
    }
}Hash)]
250pub struct InstanceDef(usize, ThreadLocalIndex);
251impl crate::IndexedVal for InstanceDef {
    fn to_val(index: usize) -> Self {
        InstanceDef(index, crate::ThreadLocalIndex)
    }
    fn to_index(&self) -> usize { self.0 }
}
impl ::serde::Serialize for InstanceDef {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where
        S: ::serde::Serializer {
        let n: usize = self.0;
        ::serde::Serialize::serialize(&n, serializer)
    }
}index_impl!(InstanceDef);
252
253impl CrateDef for InstanceDef {
254    fn def_id(&self) -> DefId {
255        with(|context| context.instance_def_id(*self))
256    }
257}
258
259#[automatically_derived]
impl ::core::clone::Clone for StaticDef {
    #[inline]
    fn clone(&self) -> StaticDef {
        let _: ::core::clone::AssertParamIsClone<DefId>;
        *self
    }
}
#[automatically_derived]
impl ::core::marker::Copy for StaticDef { }
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for StaticDef { }
#[automatically_derived]
impl ::core::cmp::PartialEq for StaticDef {
    #[inline]
    fn eq(&self, other: &StaticDef) -> bool { self.0 == other.0 }
}
#[automatically_derived]
impl ::core::cmp::Eq for StaticDef {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<DefId>;
    }
}
#[automatically_derived]
impl ::core::fmt::Debug for StaticDef {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "StaticDef",
            &&self.0)
    }
}
#[automatically_derived]
impl ::core::hash::Hash for StaticDef {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for StaticDef {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                _serde::Serializer::serialize_newtype_struct(__serializer,
                    "StaticDef", &self.0)
            }
        }
    };
impl CrateDef for StaticDef {
    fn def_id(&self) -> DefId { self.0 }
}crate_def! {
260    /// Holds information about a static variable definition.
261    #[derive(Serialize)]
262    pub StaticDef;
263}
264
265impl TryFrom<CrateItem> for StaticDef {
266    type Error = crate::Error;
267
268    fn try_from(value: CrateItem) -> Result<Self, Self::Error> {
269        if #[allow(non_exhaustive_omitted_patterns)] match value.kind() {
    ItemKind::Static => true,
    _ => false,
}matches!(value.kind(), ItemKind::Static) {
270            Ok(StaticDef(value.0))
271        } else {
272            Err(bridge::Error::new(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Expected a static item, but found: {0:?}",
                value))
    })format!("Expected a static item, but found: {value:?}")))
273        }
274    }
275}
276
277impl TryFrom<Instance> for StaticDef {
278    type Error = crate::Error;
279
280    fn try_from(value: Instance) -> Result<Self, Self::Error> {
281        StaticDef::try_from(CrateItem::try_from(value)?)
282    }
283}
284
285impl From<StaticDef> for Instance {
286    fn from(value: StaticDef) -> Self {
287        // A static definition should always be convertible to an instance.
288        with(|cx| cx.mono_instance(value.def_id()))
289    }
290}
291
292impl StaticDef {
293    /// Return the type of this static definition.
294    pub fn ty(&self) -> Ty {
295        with(|cx| cx.def_ty(self.0))
296    }
297
298    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.
299    pub fn eval_initializer(&self) -> Result<Allocation, Error> {
300        with(|cx| cx.eval_static_initializer(*self))
301    }
302}