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_receiver_is_total_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_receiver_is_total_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 pub kind: InstanceKind,
24 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::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_receiver_is_total_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::Virtual { ref idx } => {
let mut __serde_state =
_serde::Serializer::serialize_struct_variant(__serializer,
"InstanceKind", 2u32, "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", 3u32, "Shim"),
}
}
}
};Serialize)]
30pub enum InstanceKind {
31 Item,
33 Intrinsic,
35 Virtual { idx: usize },
38 Shim,
40}
41
42impl Instance {
43 pub fn args(&self) -> GenericArgs {
45 with(|cx| cx.instance_args(self.def))
46 }
47
48 pub fn body(&self) -> Option<Body> {
54 with(|context| context.instance_body(self.def))
55 }
56
57 pub fn has_body(&self) -> bool {
67 with(|cx| cx.has_body(self.def.def_id()))
68 }
69
70 pub fn is_foreign_item(&self) -> bool {
71 with(|cx| cx.is_foreign_item(self.def.def_id()))
72 }
73
74 pub fn ty(&self) -> Ty {
76 with(|context| context.instance_ty(self.def))
77 }
78
79 pub fn fn_abi(&self) -> Result<FnAbi, Error> {
81 with(|cx| cx.instance_abi(self.def))
82 }
83
84 pub fn mangled_name(&self) -> Symbol {
88 with(|context| context.instance_mangled_name(self.def))
89 }
90
91 pub fn name(&self) -> Symbol {
95 with(|context| context.instance_name(self.def, false))
96 }
97
98 pub fn trimmed_name(&self) -> Symbol {
104 with(|context| context.instance_name(self.def, true))
105 }
106
107 pub fn intrinsic_name(&self) -> Option<Symbol> {
112 match self.kind {
113 InstanceKind::Intrinsic => {
114 Some(with(|context| context.intrinsic(self.def.def_id()).unwrap().fn_name()))
115 }
116 InstanceKind::Item | InstanceKind::Virtual { .. } | InstanceKind::Shim => None,
117 }
118 }
119
120 pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
122 with(|context| {
123 context.resolve_instance(def, args).ok_or_else(|| {
124 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:?}`"))
125 })
126 })
127 }
128
129 pub fn resolve_drop_in_place(ty: Ty) -> Instance {
131 with(|cx| cx.resolve_drop_in_place(ty))
132 }
133
134 pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
136 with(|context| {
137 context.resolve_for_fn_ptr(def, args).ok_or_else(|| {
138 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:?}`"))
139 })
140 })
141 }
142
143 pub fn resolve_closure(
145 def: ClosureDef,
146 args: &GenericArgs,
147 kind: ClosureKind,
148 ) -> Result<Instance, Error> {
149 with(|context| {
150 context.resolve_closure(def, args, kind).ok_or_else(|| {
151 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:?}`"))
152 })
153 })
154 }
155
156 pub fn is_empty_shim(&self) -> bool {
166 self.kind == InstanceKind::Shim && with(|cx| cx.is_empty_drop_shim(self.def))
167 }
168
169 pub fn try_const_eval(&self, const_ty: Ty) -> Result<Allocation, Error> {
174 with(|cx| cx.eval_instance(self.def, const_ty))
175 }
176
177 pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
179 if let Some(body) = self.body() { body.dump(w, &self.name()) } else { Ok(()) }
180 }
181}
182
183impl Debug for Instance {
184 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
185 f.debug_struct("Instance")
186 .field("kind", &self.kind)
187 .field("def", &self.mangled_name())
188 .field("args", &self.args())
189 .finish()
190 }
191}
192
193impl TryFrom<CrateItem> for Instance {
196 type Error = crate::Error;
197
198 fn try_from(item: CrateItem) -> Result<Self, Self::Error> {
199 with(|context| {
200 let def_id = item.def_id();
201 if !context.requires_monomorphization(def_id) {
202 Ok(context.mono_instance(def_id))
203 } else {
204 Err(bridge::Error::new("Item requires monomorphization".to_string()))
205 }
206 })
207 }
208}
209
210impl TryFrom<Instance> for CrateItem {
213 type Error = crate::Error;
214
215 fn try_from(value: Instance) -> Result<Self, Self::Error> {
216 with(|context| {
217 if value.kind == InstanceKind::Item && context.has_body(value.def.def_id()) {
218 Ok(CrateItem(context.instance_def_id(value.def)))
219 } else {
220 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)))
221 }
222 })
223 }
224}
225
226impl From<Instance> for MonoItem {
227 fn from(value: Instance) -> Self {
228 MonoItem::Fn(value)
229 }
230}
231
232impl From<StaticDef> for MonoItem {
233 fn from(value: StaticDef) -> Self {
234 MonoItem::Static(value)
235 }
236}
237
238impl From<StaticDef> for CrateItem {
239 fn from(value: StaticDef) -> Self {
240 CrateItem(value.0)
241 }
242}
243
244#[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_receiver_is_total_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)]
245pub struct InstanceDef(usize, ThreadLocalIndex);
246impl 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);
247
248impl CrateDef for InstanceDef {
249 fn def_id(&self) -> DefId {
250 with(|context| context.instance_def_id(*self))
251 }
252}
253
254#[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_receiver_is_total_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! {
255 #[derive(Serialize)]
257 pub StaticDef;
258}
259
260impl TryFrom<CrateItem> for StaticDef {
261 type Error = crate::Error;
262
263 fn try_from(value: CrateItem) -> Result<Self, Self::Error> {
264 if #[allow(non_exhaustive_omitted_patterns)] match value.kind() {
ItemKind::Static => true,
_ => false,
}matches!(value.kind(), ItemKind::Static) {
265 Ok(StaticDef(value.0))
266 } else {
267 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:?}")))
268 }
269 }
270}
271
272impl TryFrom<Instance> for StaticDef {
273 type Error = crate::Error;
274
275 fn try_from(value: Instance) -> Result<Self, Self::Error> {
276 StaticDef::try_from(CrateItem::try_from(value)?)
277 }
278}
279
280impl From<StaticDef> for Instance {
281 fn from(value: StaticDef) -> Self {
282 with(|cx| cx.mono_instance(value.def_id()))
284 }
285}
286
287impl StaticDef {
288 pub fn ty(&self) -> Ty {
290 with(|cx| cx.def_ty(self.0))
291 }
292
293 pub fn eval_initializer(&self) -> Result<Allocation, Error> {
295 with(|cx| cx.eval_static_initializer(*self))
296 }
297}