1use std::{assert_matches, fmt, iter};
2
3use rustc_abi::{ExternAbi, FIRST_VARIANT, FieldIdx, VariantIdx};
4use rustc_data_structures::thin_vec::ThinVec;
5use rustc_hir as hir;
6use rustc_hir::attrs::lang_items::LangItem;
7use rustc_hir::def_id::DefId;
8use rustc_index::{Idx, IndexVec};
9use rustc_middle::mir::visit::{MutVisitor, PlaceContext};
10use rustc_middle::mir::*;
11use rustc_middle::query::Providers;
12use rustc_middle::ty::{
13 self, CoroutineArgs, CoroutineArgsExt, EarlyBinder, GenericArgs, Ty, TyCtxt, Unnormalized,
14};
15use rustc_middle::{bug, span_bug};
16use rustc_span::{DUMMY_SP, Span, Spanned, dummy_spanned};
17use tracing::{debug, instrument};
18
19use crate::deref_separator::deref_finder;
20use crate::elaborate_drop::{DropElaborator, DropFlagMode, DropStyle, Unwind, elaborate_drop};
21use crate::patch::MirPatch;
22use crate::{
23 abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, inline, instsimplify,
24 mentioned_items, pass_manager as pm, remove_noop_landing_pads, run_optimization_passes,
25 simplify,
26};
27
28mod async_destructor_ctor;
29
30pub(super) fn provide(providers: &mut Providers) {
31 providers.mir_shims = make_shim;
32}
33
34fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> {
35 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:35",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(35u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_shim({0:?})",
shim) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("make_shim({:?})", shim);
36
37 let mut result = match shim {
38 ty::ShimKind::VTable(def_id) => {
39 let adjustment = Adjustment::Deref { source: DerefSource::MutPtr };
40 build_call_shim(tcx, shim, Some(adjustment), CallKind::Direct(def_id))
41 }
42 ty::ShimKind::FnPtr(def_id, ty) => {
43 let trait_ = tcx.parent(def_id);
44 let adjustment = match tcx
46 .fn_trait_kind_from_def_id(trait_)
47 .or_else(|| tcx.async_fn_trait_kind_from_def_id(trait_))
48 {
49 Some(ty::ClosureKind::FnOnce) => Adjustment::Identity,
50 Some(ty::ClosureKind::Fn) => Adjustment::Deref { source: DerefSource::ImmRef },
51 Some(ty::ClosureKind::FnMut) => Adjustment::Deref { source: DerefSource::MutRef },
52 None => ::rustc_middle::util::bug::bug_fmt(format_args!("fn pointer {0:?} is not an fn",
ty))bug!("fn pointer {:?} is not an fn", ty),
53 };
54
55 build_call_shim(tcx, shim, Some(adjustment), CallKind::Indirect(ty))
56 }
57 ty::ShimKind::Reify(def_id, _) => {
63 build_call_shim(tcx, shim, None, CallKind::Direct(def_id))
64 }
65 ty::ShimKind::ClosureOnce { call_once: _, closure: _, track_caller: _ } => {
66 let fn_mut = tcx.require_lang_item(LangItem::FnMut, DUMMY_SP);
67 let call_mut = tcx
68 .associated_items(fn_mut)
69 .in_definition_order()
70 .find(|it| it.is_fn())
71 .unwrap()
72 .def_id;
73
74 build_call_shim(tcx, shim, Some(Adjustment::RefMut), CallKind::Direct(call_mut))
75 }
76
77 ty::ShimKind::ConstructCoroutineInClosure { coroutine_closure_def_id, receiver_by_ref } => {
78 build_construct_coroutine_by_move_shim(tcx, coroutine_closure_def_id, receiver_by_ref)
79 }
80
81 ty::ShimKind::DropGlue(def_id, ty) => {
82 if let Some(&ty::Coroutine(coroutine_def_id, args)) = ty.map(Ty::kind) {
85 let coroutine_body = tcx.optimized_mir(coroutine_def_id);
86
87 let ty::Coroutine(_, id_args) = *tcx.type_of(coroutine_def_id).skip_binder().kind()
88 else {
89 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"))bug!()
90 };
91
92 let body = if id_args.as_coroutine().kind_ty() == args.as_coroutine().kind_ty() {
98 coroutine_body.coroutine_drop().unwrap()
99 } else {
100 {
match (&args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(),
&ty::ClosureKind::FnOnce) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(
101 args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap(),
102 ty::ClosureKind::FnOnce
103 );
104 tcx.optimized_mir(tcx.coroutine_by_move_body_def_id(coroutine_def_id))
105 .coroutine_drop()
106 .unwrap()
107 };
108
109 let mut body =
110 EarlyBinder::bind(tcx, body.clone()).instantiate(tcx, args).skip_norm_wip();
111 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:111",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(111u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_shim({0:?}) = {1:?}",
shim, body) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("make_shim({:?}) = {:?}", shim, body);
112
113 pm::run_passes(
114 tcx,
115 &mut body,
116 &[
117 &mentioned_items::MentionedItems,
118 &abort_unwinding_calls::AbortUnwindingCalls,
119 &add_call_guards::CriticalCallEdges,
120 ],
121 Some(MirPhase::Runtime(RuntimePhase::Optimized)),
122 );
123
124 return body;
125 }
126
127 build_drop_shim(tcx, def_id, ty, ty::TypingEnv::post_analysis(tcx, def_id))
128 }
129 ty::ShimKind::ThreadLocal(..) => build_thread_local_shim(tcx, shim),
130 ty::ShimKind::Clone(def_id, ty) => build_clone_shim(tcx, def_id, ty),
131 ty::ShimKind::FnPtrAsPtr(def_id, ty) => build_fn_ptr_as_ptr_shim(tcx, def_id, ty),
132 ty::ShimKind::FnPtrFromPtr(def_id, ty) => build_fn_ptr_from_ptr_shim(tcx, def_id, ty),
133 ty::ShimKind::FutureDropPoll(def_id, proxy_ty, impl_ty) => {
134 let mut body =
135 async_destructor_ctor::build_future_drop_poll_shim(tcx, def_id, proxy_ty, impl_ty);
136
137 pm::run_passes(
138 tcx,
139 &mut body,
140 &[
141 &mentioned_items::MentionedItems,
142 &abort_unwinding_calls::AbortUnwindingCalls,
143 &add_call_guards::CriticalCallEdges,
144 ],
145 Some(MirPhase::Runtime(RuntimePhase::PostCleanup)),
146 );
147 run_optimization_passes(tcx, &mut body);
148 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:148",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(148u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_shim({0:?}) = {1:?}",
shim, body) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("make_shim({:?}) = {:?}", shim, body);
149 return body;
150 }
151 ty::ShimKind::AsyncDropGlue(def_id, ty) => {
152 let mut body = async_destructor_ctor::build_async_drop_shim(tcx, def_id, ty);
153
154 pm::run_passes_no_validate(
158 tcx,
159 &mut body,
160 &[
161 &mentioned_items::MentionedItems,
162 &abort_unwinding_calls::AbortUnwindingCalls,
163 &add_call_guards::CriticalCallEdges,
164 &simplify::SimplifyCfg::MakeShim,
165 &crate::coroutine::StateTransform,
166 ],
167 Some(MirPhase::Runtime(RuntimePhase::PostCleanup)),
168 );
169 run_optimization_passes(tcx, &mut body);
170 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:170",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(170u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_shim({0:?}) = {1:?}",
shim, body) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("make_shim({:?}) = {:?}", shim, body);
171 return body;
172 }
173
174 ty::ShimKind::AsyncDropGlueCtor(def_id, ty) => {
175 let body = async_destructor_ctor::build_async_destructor_ctor_shim(tcx, def_id, ty);
176 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:176",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(176u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_shim({0:?}) = {1:?}",
shim, body) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("make_shim({:?}) = {:?}", shim, body);
177 return body;
178 }
179 };
180 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:180",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(180u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_shim({0:?}) = untransformed {1:?}",
shim, result) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("make_shim({:?}) = untransformed {:?}", shim, result);
181
182 deref_finder(tcx, &mut result, false);
183
184 pm::run_passes_no_validate(
189 tcx,
190 &mut result,
191 &[
192 &mentioned_items::MentionedItems,
193 &add_moves_for_packed_drops::AddMovesForPackedDrops,
194 &remove_noop_landing_pads::RemoveNoopLandingPads,
195 &simplify::SimplifyCfg::MakeShim,
196 &instsimplify::InstSimplify::BeforeInline,
197 &inline::ForceInline,
199 &abort_unwinding_calls::AbortUnwindingCalls,
200 &add_call_guards::CriticalCallEdges,
201 ],
202 Some(MirPhase::Runtime(RuntimePhase::Optimized)),
203 );
204
205 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:205",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(205u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("make_shim({0:?}) = {1:?}",
shim, result) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("make_shim({:?}) = {:?}", shim, result);
206
207 result
208}
209
210#[derive(#[automatically_derived]
impl ::core::marker::Copy for DerefSource { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DerefSource { }
#[automatically_derived]
impl ::core::clone::Clone for DerefSource {
#[inline]
fn clone(&self) -> DerefSource { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for DerefSource {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
DerefSource::ImmRef => "ImmRef",
DerefSource::MutRef => "MutRef",
DerefSource::MutPtr => "MutPtr",
})
}
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for DerefSource { }
#[automatically_derived]
impl ::core::cmp::PartialEq for DerefSource {
#[inline]
fn eq(&self, other: &DerefSource) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
211enum DerefSource {
212 ImmRef,
214 MutRef,
216 MutPtr,
218}
219
220#[derive(#[automatically_derived]
impl ::core::marker::Copy for Adjustment { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Adjustment { }
#[automatically_derived]
impl ::core::clone::Clone for Adjustment {
#[inline]
fn clone(&self) -> Adjustment {
let _: ::core::clone::AssertParamIsClone<DerefSource>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Adjustment {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Adjustment::Identity =>
::core::fmt::Formatter::write_str(f, "Identity"),
Adjustment::Deref { source: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Deref",
"source", &__self_0),
Adjustment::RefMut =>
::core::fmt::Formatter::write_str(f, "RefMut"),
}
}
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for Adjustment { }
#[automatically_derived]
impl ::core::cmp::PartialEq for Adjustment {
#[inline]
fn eq(&self, other: &Adjustment) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(Adjustment::Deref { source: __self_0 }, Adjustment::Deref {
source: __arg1_0 }) => __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq)]
221enum Adjustment {
222 Identity,
224
225 Deref { source: DerefSource },
230
231 RefMut,
236}
237
238#[derive(#[automatically_derived]
impl<'tcx> ::core::marker::Copy for CallKind<'tcx> { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl<'tcx> ::core::clone::TrivialClone for CallKind<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::clone::Clone for CallKind<'tcx> {
#[inline]
fn clone(&self) -> CallKind<'tcx> {
let _: ::core::clone::AssertParamIsClone<Ty<'tcx>>;
let _: ::core::clone::AssertParamIsClone<DefId>;
*self
}
}Clone, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for CallKind<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
CallKind::Indirect(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Indirect", &__self_0),
CallKind::Direct(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Direct",
&__self_0),
}
}
}Debug, #[automatically_derived]
impl<'tcx> ::core::marker::StructuralPartialEq for CallKind<'tcx> { }
#[automatically_derived]
impl<'tcx> ::core::cmp::PartialEq for CallKind<'tcx> {
#[inline]
fn eq(&self, other: &CallKind<'tcx>) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(CallKind::Indirect(__self_0), CallKind::Indirect(__arg1_0))
=> __self_0 == __arg1_0,
(CallKind::Direct(__self_0), CallKind::Direct(__arg1_0)) =>
__self_0 == __arg1_0,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq)]
239enum CallKind<'tcx> {
240 Indirect(Ty<'tcx>),
242
243 Direct(DefId),
245}
246
247fn local_decls_for_sig<'tcx>(
248 sig: &ty::FnSig<'tcx>,
249 span: Span,
250) -> IndexVec<Local, LocalDecl<'tcx>> {
251 iter::once(LocalDecl::new(sig.output(), span))
252 .chain(sig.inputs().iter().map(|ity| LocalDecl::new(*ity, span).immutable()))
253 .collect()
254}
255
256pub fn build_drop_shim<'tcx>(
261 tcx: TyCtxt<'tcx>,
262 def_id: DefId,
263 ty: Option<Ty<'tcx>>,
264 typing_env: ty::TypingEnv<'tcx>,
265) -> Body<'tcx> {
266 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:266",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(266u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("build_drop_shim(def_id={0:?}, ty={1:?})",
def_id, ty) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty);
267
268 if !!#[allow(non_exhaustive_omitted_patterns)] match ty {
Some(ty) if ty.is_coroutine() => true,
_ => false,
} {
::core::panicking::panic("assertion failed: !matches!(ty, Some(ty) if ty.is_coroutine())")
};assert!(!matches!(ty, Some(ty) if ty.is_coroutine()));
269
270 let args = if let Some(ty) = ty {
271 tcx.mk_args(&[ty.into()])
272 } else {
273 GenericArgs::identity_for_item(tcx, def_id)
274 };
275 let sig = tcx.fn_sig(def_id).instantiate(tcx, args).skip_norm_wip();
276 let sig = tcx.instantiate_bound_regions_with_erased(sig);
277 let span = tcx.def_span(def_id);
278
279 let source_info = SourceInfo::outermost(span);
280
281 let return_block = BasicBlock::new(1);
282 let mut blocks = IndexVec::with_capacity(2);
283 let block = |blocks: &mut IndexVec<_, _>, kind| {
284 blocks.push(BasicBlockData::new(
285 Some(Terminator { source_info, kind, attributes: ThinVec::new() }),
286 false,
287 ))
288 };
289 if ty.is_some() {
290 block(&mut blocks, TerminatorKind::Goto { target: return_block });
291 }
292 block(&mut blocks, TerminatorKind::Return);
293
294 let source = MirSource::from_shim(ty::ShimKind::DropGlue(def_id, ty));
295 let mut body =
296 new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
297
298 let Some(ty) = ty else {
299 return body;
300 };
301
302 let dropee_ptr = Place::from(Local::arg(0));
303
304 if let ty::Array(ety, _len) = *ty.kind() {
305 let slice_ty = Ty::new_slice(tcx, ety);
308 let mut_slice_ty = Ty::new_ref(tcx, tcx.lifetimes.re_erased, slice_ty, ty::Mutability::Mut);
309 let erased_local = body.local_decls.push(LocalDecl::new(mut_slice_ty, span));
310
311 let start = &mut body.basic_blocks_mut()[START_BLOCK];
312 start.statements.push(Statement::new(
313 source_info,
314 StatementKind::Assign(Box::new((
315 Place::from(erased_local),
316 Rvalue::Cast(
317 CastKind::PointerCoercion(
318 ty::adjustment::PointerCoercion::Unsize,
319 CoercionSource::Implicit,
320 ),
321 Operand::Move(dropee_ptr),
322 mut_slice_ty,
323 ),
324 ))),
325 ));
326 start.terminator = Some(Terminator {
327 source_info,
328 kind: TerminatorKind::Call {
329 func: Operand::function_handle(
330 tcx,
331 def_id,
332 &[ty::GenericArg::from(slice_ty)],
333 span,
334 ),
335 args: Box::new([Spanned { span, node: Operand::Move(Place::from(erased_local)) }]),
336 destination: Place::from(RETURN_PLACE),
337 target: Some(return_block),
338 unwind: UnwindAction::Continue,
339 call_source: CallSource::Misc,
340 fn_span: span,
341 },
342 attributes: ThinVec::new(),
343 });
344 } else {
345 let patch = {
346 let mut elaborator = DropShimElaborator {
347 body: &body,
348 patch: MirPatch::new(&body),
349 tcx,
350 typing_env,
351 produce_async_drops: false,
352 };
353 let dropee = tcx.mk_place_deref(dropee_ptr);
354 let resume_block = elaborator.patch.resume_block();
355 elaborate_drop(
356 &mut elaborator,
357 source_info,
358 dropee,
359 (),
360 return_block,
361 Unwind::To(resume_block),
362 START_BLOCK,
363 None,
364 );
365 elaborator.patch
366 };
367 patch.apply(&mut body);
368 }
369
370 body
371}
372
373fn new_body<'tcx>(
374 source: MirSource<'tcx>,
375 basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
376 local_decls: IndexVec<Local, LocalDecl<'tcx>>,
377 arg_count: usize,
378 span: Span,
379) -> Body<'tcx> {
380 let mut body = Body::new(
381 source,
382 basic_blocks,
383 IndexVec::from_elem_n(
384 SourceScopeData {
385 span,
386 parent_scope: None,
387 inlined: None,
388 inlined_parent_scope: None,
389 local_data: ClearCrossCrate::Clear,
390 },
391 1,
392 ),
393 local_decls,
394 IndexVec::new(),
395 arg_count,
396 ::alloc::vec::Vec::new()vec![],
397 span,
398 None,
399 None,
401 );
402 body.set_required_consts(Vec::new());
404 body
405}
406
407pub(super) struct DropShimElaborator<'a, 'tcx> {
408 pub body: &'a Body<'tcx>,
409 pub patch: MirPatch<'tcx>,
410 pub tcx: TyCtxt<'tcx>,
411 pub typing_env: ty::TypingEnv<'tcx>,
412 pub produce_async_drops: bool,
413}
414
415impl fmt::Debug for DropShimElaborator<'_, '_> {
416 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
417 f.debug_struct("DropShimElaborator").finish_non_exhaustive()
418 }
419}
420
421impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> {
422 type Path = ();
423
424 fn patch_ref(&self) -> &MirPatch<'tcx> {
425 &self.patch
426 }
427 fn patch(&mut self) -> &mut MirPatch<'tcx> {
428 &mut self.patch
429 }
430 fn body(&self) -> &'a Body<'tcx> {
431 self.body
432 }
433 fn tcx(&self) -> TyCtxt<'tcx> {
434 self.tcx
435 }
436 fn typing_env(&self) -> ty::TypingEnv<'tcx> {
437 self.typing_env
438 }
439
440 fn allow_async_drops(&self) -> bool {
441 self.produce_async_drops
442 }
443
444 fn drop_style(&self, _path: Self::Path, mode: DropFlagMode) -> DropStyle {
445 match mode {
446 DropFlagMode::Shallow => {
447 DropStyle::Static
450 }
451 DropFlagMode::Deep => {
452 DropStyle::Open
455 }
456 }
457 }
458
459 fn get_drop_flag(&mut self, _path: Self::Path) -> Option<Operand<'tcx>> {
460 None
461 }
462
463 fn drop_flags_for(&mut self, _path: Self::Path, _mode: DropFlagMode) -> Vec<Place<'tcx>> {
464 Vec::new()
465 }
466
467 fn field_subpath(&self, _path: Self::Path, _field: FieldIdx) -> Option<Self::Path> {
468 None
469 }
470 fn deref_subpath(&self, _path: Self::Path) -> Option<Self::Path> {
471 None
472 }
473 fn downcast_subpath(&self, _path: Self::Path, _variant: VariantIdx) -> Option<Self::Path> {
474 Some(())
475 }
476 fn array_subpath(&self, _path: Self::Path, _index: u64, _size: u64) -> Option<Self::Path> {
477 None
478 }
479}
480
481fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, shim: ty::ShimKind<'tcx>) -> Body<'tcx> {
482 let def_id = shim.def_id();
483
484 let span = tcx.def_span(def_id);
485 let source_info = SourceInfo::outermost(span);
486
487 let blocks = IndexVec::from_raw(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[BasicBlockData::new_stmts(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[Statement::new(source_info,
StatementKind::Assign(Box::new((Place::return_place(),
Rvalue::ThreadLocalRef(def_id)))))])),
Some(Terminator {
source_info,
kind: TerminatorKind::Return,
attributes: ThinVec::new(),
}), false)]))vec![BasicBlockData::new_stmts(
488 vec![Statement::new(
489 source_info,
490 StatementKind::Assign(Box::new((
491 Place::return_place(),
492 Rvalue::ThreadLocalRef(def_id),
493 ))),
494 )],
495 Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }),
496 false,
497 )]);
498
499 new_body(
500 MirSource::from_shim(shim),
501 blocks,
502 IndexVec::from_raw(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[LocalDecl::new(tcx.thread_local_ptr_ty(def_id), span)]))vec![LocalDecl::new(tcx.thread_local_ptr_ty(def_id), span)]),
503 0,
504 span,
505 )
506}
507
508fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> {
510 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:510",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(510u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("build_clone_shim(def_id={0:?})",
def_id) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("build_clone_shim(def_id={:?})", def_id);
511
512 let mut builder = CloneShimBuilder::new(tcx, def_id, self_ty);
513
514 let dest = Place::return_place();
515 let src = tcx.mk_place_deref(Place::from(Local::arg(0)));
516
517 match self_ty.kind() {
518 ty::FnDef(..) | ty::FnPtr(..) => builder.copy_shim(),
519 ty::Closure(_, args) => builder.tuple_like_shim(dest, src, args.as_closure().upvar_tys()),
520 ty::CoroutineClosure(_, args) => {
521 builder.tuple_like_shim(dest, src, args.as_coroutine_closure().upvar_tys())
522 }
523 ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()),
524 ty::Coroutine(coroutine_def_id, args) => {
525 {
match (&tcx.coroutine_movability(*coroutine_def_id),
&hir::Movability::Movable) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};assert_eq!(tcx.coroutine_movability(*coroutine_def_id), hir::Movability::Movable);
526 builder.coroutine_shim(dest, src, *coroutine_def_id, args.as_coroutine())
527 }
528 _ => ::rustc_middle::util::bug::bug_fmt(format_args!("clone shim for `{0:?}` which is not `Copy` and is not an aggregate",
self_ty))bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty),
529 };
530
531 builder.into_mir()
532}
533
534struct CloneShimBuilder<'tcx> {
535 tcx: TyCtxt<'tcx>,
536 def_id: DefId,
537 local_decls: IndexVec<Local, LocalDecl<'tcx>>,
538 blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
539 span: Span,
540 sig: ty::FnSig<'tcx>,
541}
542
543impl<'tcx> CloneShimBuilder<'tcx> {
544 fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Self {
545 let sig = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).skip_norm_wip();
549 let sig = tcx.instantiate_bound_regions_with_erased(sig);
550 let span = tcx.def_span(def_id);
551
552 CloneShimBuilder {
553 tcx,
554 def_id,
555 local_decls: local_decls_for_sig(&sig, span),
556 blocks: IndexVec::new(),
557 span,
558 sig,
559 }
560 }
561
562 fn into_mir(self) -> Body<'tcx> {
563 let source =
564 MirSource::from_shim(ty::ShimKind::Clone(self.def_id, self.sig.inputs_and_output[0]));
565 new_body(source, self.blocks, self.local_decls, self.sig.inputs().len(), self.span)
566 }
567
568 fn source_info(&self) -> SourceInfo {
569 SourceInfo::outermost(self.span)
570 }
571
572 fn block(
573 &mut self,
574 statements: Vec<Statement<'tcx>>,
575 kind: TerminatorKind<'tcx>,
576 is_cleanup: bool,
577 ) -> BasicBlock {
578 let source_info = self.source_info();
579 self.blocks.push(BasicBlockData::new_stmts(
580 statements,
581 Some(Terminator { source_info, kind, attributes: ThinVec::new() }),
582 is_cleanup,
583 ))
584 }
585
586 fn block_index_offset(&self, offset: usize) -> BasicBlock {
591 BasicBlock::new(self.blocks.len() + offset)
592 }
593
594 fn make_statement(&self, kind: StatementKind<'tcx>) -> Statement<'tcx> {
595 Statement::new(self.source_info(), kind)
596 }
597
598 fn copy_shim(&mut self) {
599 let rcvr = self.tcx.mk_place_deref(Place::from(Local::arg(0)));
600 let ret_statement = self.make_statement(StatementKind::Assign(Box::new((
601 Place::return_place(),
602 Rvalue::Use(Operand::Copy(rcvr), WithRetag::Yes),
603 ))));
604 self.block(::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[ret_statement]))vec![ret_statement], TerminatorKind::Return, false);
605 }
606
607 fn make_place(&mut self, mutability: Mutability, ty: Ty<'tcx>) -> Place<'tcx> {
608 let span = self.span;
609 let mut local = LocalDecl::new(ty, span);
610 if mutability.is_not() {
611 local = local.immutable();
612 }
613 Place::from(self.local_decls.push(local))
614 }
615
616 fn make_clone_call(
617 &mut self,
618 dest: Place<'tcx>,
619 src: Place<'tcx>,
620 ty: Ty<'tcx>,
621 next: BasicBlock,
622 cleanup: BasicBlock,
623 ) {
624 let tcx = self.tcx;
625
626 let func_ty = tcx.type_of(self.def_id).instantiate(tcx, &[ty.into()]).skip_norm_wip();
628 let func = Operand::Constant(Box::new(ConstOperand {
629 span: self.span,
630 user_ty: None,
631 const_: Const::zero_sized(func_ty),
632 }));
633
634 let ref_loc =
635 self.make_place(Mutability::Not, Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, ty));
636
637 let statement = self.make_statement(StatementKind::Assign(Box::new((
639 ref_loc,
640 Rvalue::Ref(tcx.lifetimes.re_erased, BorrowKind::Shared, src),
641 ))));
642
643 self.block(
645 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[statement]))vec![statement],
646 TerminatorKind::Call {
647 func,
648 args: [Spanned { node: Operand::Move(ref_loc), span: DUMMY_SP }].into(),
649 destination: dest,
650 target: Some(next),
651 unwind: UnwindAction::Cleanup(cleanup),
652 call_source: CallSource::Normal,
653 fn_span: self.span,
654 },
655 false,
656 );
657 }
658
659 fn clone_fields<I>(
660 &mut self,
661 dest: Place<'tcx>,
662 src: Place<'tcx>,
663 target: BasicBlock,
664 mut unwind: BasicBlock,
665 tys: I,
666 ) -> BasicBlock
667 where
668 I: IntoIterator<Item = Ty<'tcx>>,
669 {
670 for (i, ity) in tys.into_iter().enumerate() {
672 let field = FieldIdx::new(i);
683 let src_field = self.tcx.mk_place_field(src, field, ity);
684
685 let dest_field = self.tcx.mk_place_field(dest, field, ity);
686
687 let next_unwind = self.block_index_offset(1);
688 let next_block = self.block_index_offset(2);
689 self.make_clone_call(dest_field, src_field, ity, next_block, unwind);
690 self.block(
691 ::alloc::vec::Vec::new()vec![],
692 TerminatorKind::Drop {
693 place: dest_field,
694 target: unwind,
695 unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup),
696 replace: false,
697 drop: None,
698 },
699 true,
700 );
701 unwind = next_unwind;
702 }
703 self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::Goto { target }, false);
705 unwind
706 }
707
708 fn tuple_like_shim<I>(&mut self, dest: Place<'tcx>, src: Place<'tcx>, tys: I)
709 where
710 I: IntoIterator<Item = Ty<'tcx>>,
711 {
712 self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::Goto { target: self.block_index_offset(3) }, false);
713 let unwind = self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::UnwindResume, true);
714 let target = self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::Return, false);
715
716 let _final_cleanup_block = self.clone_fields(dest, src, target, unwind, tys);
717 }
718
719 fn coroutine_shim(
720 &mut self,
721 dest: Place<'tcx>,
722 src: Place<'tcx>,
723 coroutine_def_id: DefId,
724 args: CoroutineArgs<TyCtxt<'tcx>>,
725 ) {
726 self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::Goto { target: self.block_index_offset(3) }, false);
727 let unwind = self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::UnwindResume, true);
728 let switch = self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::Unreachable, false);
730 let unwind = self.clone_fields(dest, src, switch, unwind, args.upvar_tys());
731 let target = self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::Return, false);
732 let unreachable = self.block(::alloc::vec::Vec::new()vec![], TerminatorKind::Unreachable, false);
733 let mut cases = Vec::with_capacity(args.state_tys(coroutine_def_id, self.tcx).count());
734 for (index, state_tys) in args.state_tys(coroutine_def_id, self.tcx).enumerate() {
735 let variant_index = VariantIdx::new(index);
736 let dest = self.tcx.mk_place_downcast_unnamed(dest, variant_index);
737 let src = self.tcx.mk_place_downcast_unnamed(src, variant_index);
738 let clone_block = self.block_index_offset(1);
739 let start_block = self.block(
740 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[self.make_statement(StatementKind::SetDiscriminant {
place: Box::new(Place::return_place()),
variant_index,
})]))vec![self.make_statement(StatementKind::SetDiscriminant {
741 place: Box::new(Place::return_place()),
742 variant_index,
743 })],
744 TerminatorKind::Goto { target: clone_block },
745 false,
746 );
747 cases.push((index as u128, start_block));
748 let _final_cleanup_block = self.clone_fields(dest, src, target, unwind, state_tys);
749 }
750 let discr_ty = args.discr_ty(self.tcx);
751 let temp = self.make_place(Mutability::Mut, discr_ty);
752 let rvalue = Rvalue::Discriminant(src);
753 let statement = self.make_statement(StatementKind::Assign(Box::new((temp, rvalue))));
754 match &mut self.blocks[switch] {
755 BasicBlockData { statements, terminator: Some(Terminator { kind, .. }), .. } => {
756 statements.push(statement);
757 *kind = TerminatorKind::SwitchInt {
758 discr: Operand::Move(temp),
759 targets: SwitchTargets::new(cases.into_iter(), unreachable),
760 };
761 }
762 BasicBlockData { terminator: None, .. } => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
763 }
764 }
765}
766
767{}
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() || { false }
{
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("build_call_shim",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(769u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("shim")
}> =
::tracing::__macro_support::FieldName::new("shim");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("rcvr_adjustment")
}> =
::tracing::__macro_support::FieldName::new("rcvr_adjustment");
NAME.as_str()
},
{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("call_kind")
}> =
::tracing::__macro_support::FieldName::new("call_kind");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
meta.fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&shim)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&rcvr_adjustment)
as &dyn ::tracing::field::Value)),
(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&call_kind)
as &dyn ::tracing::field::Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[allow(clippy :: redundant_closure_call)]
let x =
(move ||
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy
:: needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Body<'tcx> = loop {};
return __tracing_attr_fake_return;
}
{
let (sig_args, untuple_args) =
if let ty::ShimKind::FnPtr(_, ty) = shim {
let sig =
tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx));
let untuple_args = sig.inputs();
let arg_tup = Ty::new_tup(tcx, untuple_args);
(Some([ty.into(), arg_tup.into()]), Some(untuple_args))
} else { (None, None) };
let def_id = shim.def_id();
let sig = tcx.fn_sig(def_id);
let sig =
sig.map_bound(|sig|
tcx.instantiate_bound_regions_with_erased(sig));
{
match (&sig_args.is_some(),
&!shim.has_polymorphic_mir_body()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
let mut sig =
if let Some(sig_args) = sig_args {
sig.instantiate(tcx, &sig_args).skip_norm_wip()
} else { sig.instantiate_identity().skip_norm_wip() };
if let CallKind::Indirect(fnty) = call_kind {
let mut inputs_and_output = sig.inputs_and_output.to_vec();
{
match (&inputs_and_output.len(), &3) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
let self_arg = &mut inputs_and_output[0];
*self_arg =
match rcvr_adjustment.unwrap() {
Adjustment::Identity => fnty,
Adjustment::Deref { source } =>
match source {
DerefSource::ImmRef =>
Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, fnty),
DerefSource::MutRef =>
Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fnty),
DerefSource::MutPtr => Ty::new_mut_ptr(tcx, fnty),
},
Adjustment::RefMut =>
::rustc_middle::util::bug::bug_fmt(format_args!("`RefMut` is never used with indirect calls: {0:?}",
shim)),
};
sig.inputs_and_output =
tcx.mk_type_list(&inputs_and_output);
}
if let ty::ShimKind::VTable(..) = shim {
let mut inputs_and_output = sig.inputs_and_output.to_vec();
let self_arg = &mut inputs_and_output[0];
if true {
if !(tcx.generics_of(def_id).has_self &&
*self_arg == tcx.types.self_param) {
::core::panicking::panic("assertion failed: tcx.generics_of(def_id).has_self && *self_arg == tcx.types.self_param")
};
};
*self_arg = Ty::new_mut_ptr(tcx, *self_arg);
sig.inputs_and_output =
tcx.mk_type_list(&inputs_and_output);
}
let span = tcx.def_span(def_id);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:844",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(844u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("sig")
}> =
::tracing::__macro_support::FieldName::new("sig");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&sig)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
let mut local_decls = local_decls_for_sig(&sig, span);
let source_info = SourceInfo::outermost(span);
let destination = Place::return_place();
let rcvr_place =
||
{
if !rcvr_adjustment.is_some() {
::core::panicking::panic("assertion failed: rcvr_adjustment.is_some()")
};
Place::from(Local::arg(0))
};
let mut statements = ::alloc::vec::Vec::new();
let rcvr =
rcvr_adjustment.map(|rcvr_adjustment|
match rcvr_adjustment {
Adjustment::Identity => Operand::Move(rcvr_place()),
Adjustment::Deref { source: _ } =>
Operand::Move(tcx.mk_place_deref(rcvr_place())),
Adjustment::RefMut => {
let ref_rcvr =
local_decls.push(LocalDecl::new(Ty::new_mut_ref(tcx,
tcx.lifetimes.re_erased, sig.inputs()[0]),
span).immutable());
let borrow_kind =
BorrowKind::Mut { kind: MutBorrowKind::Default };
statements.push(Statement::new(source_info,
StatementKind::Assign(Box::new((Place::from(ref_rcvr),
Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind,
rcvr_place()))))));
Operand::Move(Place::from(ref_rcvr))
}
});
let (callee, mut args) =
match call_kind {
CallKind::Indirect(_) =>
(rcvr.unwrap(), ::alloc::vec::Vec::new()),
CallKind::Direct(def_id) => {
let ty =
tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
(Operand::Constant(Box::new(ConstOperand {
span,
user_ty: None,
const_: Const::zero_sized(ty),
})), rcvr.into_iter().collect::<Vec<_>>())
}
};
let mut arg_range = 0..sig.inputs().len();
if rcvr_adjustment.is_some() { arg_range.start += 1; }
if untuple_args.is_some() { arg_range.end -= 1; }
args.extend(arg_range.map(|i|
Operand::Move(Place::from(Local::arg(i)))));
if let Some(untuple_args) = untuple_args {
let tuple_arg = Local::arg(sig.inputs().len() - 1);
args.extend(untuple_args.iter().enumerate().map(|(i, ity)|
{
Operand::Move(tcx.mk_place_field(Place::from(tuple_arg),
FieldIdx::new(i), *ity))
}));
}
let n_blocks =
if let Some(Adjustment::RefMut) = rcvr_adjustment {
5
} else { 2 };
let mut blocks = IndexVec::with_capacity(n_blocks);
let block =
|blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup|
{
blocks.push(BasicBlockData::new_stmts(statements,
Some(Terminator {
source_info,
kind,
attributes: ThinVec::new(),
}), is_cleanup))
};
let args =
args.into_iter().map(|a|
Spanned { node: a, span: DUMMY_SP }).collect();
block(&mut blocks, statements,
TerminatorKind::Call {
func: callee,
args,
destination,
target: Some(BasicBlock::new(1)),
unwind: if let Some(Adjustment::RefMut) = rcvr_adjustment {
UnwindAction::Cleanup(BasicBlock::new(3))
} else { UnwindAction::Continue },
call_source: CallSource::Misc,
fn_span: span,
}, false);
if let Some(Adjustment::RefMut) = rcvr_adjustment {
block(&mut blocks, ::alloc::vec::Vec::new(),
TerminatorKind::Drop {
place: rcvr_place(),
target: BasicBlock::new(2),
unwind: UnwindAction::Continue,
replace: false,
drop: None,
}, false);
}
let stmts = ::alloc::vec::Vec::new();
block(&mut blocks, stmts, TerminatorKind::Return, false);
if let Some(Adjustment::RefMut) = rcvr_adjustment {
block(&mut blocks, ::alloc::vec::Vec::new(),
TerminatorKind::Drop {
place: rcvr_place(),
target: BasicBlock::new(4),
unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup),
replace: false,
drop: None,
}, true);
block(&mut blocks, ::alloc::vec::Vec::new(),
TerminatorKind::UnwindResume, true);
}
let mut body =
new_body(MirSource::from_shim(shim), blocks, local_decls,
sig.inputs().len(), span);
if let ExternAbi::RustCall = sig.abi() {
body.spread_arg = Some(Local::new(sig.inputs().len()));
}
body
}
})();
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:769",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(769u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&[{
const NAME:
::tracing::__macro_support::FieldName<{
::tracing::__macro_support::FieldName::len("return")
}> =
::tracing::__macro_support::FieldName::new("return");
NAME.as_str()
}], ::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&::tracing::field::debug(&x)
as &dyn ::tracing::field::Value))])
});
} else { ; }
};
x;#[instrument(level = "debug", skip(tcx), ret)]
770fn build_call_shim<'tcx>(
771 tcx: TyCtxt<'tcx>,
772 shim: ty::ShimKind<'tcx>,
773 rcvr_adjustment: Option<Adjustment>,
774 call_kind: CallKind<'tcx>,
775) -> Body<'tcx> {
776 let (sig_args, untuple_args) = if let ty::ShimKind::FnPtr(_, ty) = shim {
780 let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx));
781
782 let untuple_args = sig.inputs();
783
784 let arg_tup = Ty::new_tup(tcx, untuple_args);
786
787 (Some([ty.into(), arg_tup.into()]), Some(untuple_args))
788 } else {
789 (None, None)
790 };
791
792 let def_id = shim.def_id();
793
794 let sig = tcx.fn_sig(def_id);
795 let sig = sig.map_bound(|sig| tcx.instantiate_bound_regions_with_erased(sig));
796
797 assert_eq!(sig_args.is_some(), !shim.has_polymorphic_mir_body());
798 let mut sig = if let Some(sig_args) = sig_args {
799 sig.instantiate(tcx, &sig_args).skip_norm_wip()
800 } else {
801 sig.instantiate_identity().skip_norm_wip()
802 };
803
804 if let CallKind::Indirect(fnty) = call_kind {
805 let mut inputs_and_output = sig.inputs_and_output.to_vec();
811
812 assert_eq!(inputs_and_output.len(), 3);
815
816 let self_arg = &mut inputs_and_output[0];
819 *self_arg = match rcvr_adjustment.unwrap() {
820 Adjustment::Identity => fnty,
821 Adjustment::Deref { source } => match source {
822 DerefSource::ImmRef => Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, fnty),
823 DerefSource::MutRef => Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, fnty),
824 DerefSource::MutPtr => Ty::new_mut_ptr(tcx, fnty),
825 },
826 Adjustment::RefMut => bug!("`RefMut` is never used with indirect calls: {shim:?}"),
827 };
828 sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
829 }
830
831 if let ty::ShimKind::VTable(..) = shim {
834 let mut inputs_and_output = sig.inputs_and_output.to_vec();
836 let self_arg = &mut inputs_and_output[0];
837 debug_assert!(tcx.generics_of(def_id).has_self && *self_arg == tcx.types.self_param);
838 *self_arg = Ty::new_mut_ptr(tcx, *self_arg);
839 sig.inputs_and_output = tcx.mk_type_list(&inputs_and_output);
840 }
841
842 let span = tcx.def_span(def_id);
843
844 debug!(?sig);
845
846 let mut local_decls = local_decls_for_sig(&sig, span);
847 let source_info = SourceInfo::outermost(span);
848
849 let destination = Place::return_place();
850
851 let rcvr_place = || {
852 assert!(rcvr_adjustment.is_some());
853 Place::from(Local::arg(0))
854 };
855 let mut statements = vec![];
856
857 let rcvr = rcvr_adjustment.map(|rcvr_adjustment| match rcvr_adjustment {
858 Adjustment::Identity => Operand::Move(rcvr_place()),
859 Adjustment::Deref { source: _ } => Operand::Move(tcx.mk_place_deref(rcvr_place())),
860 Adjustment::RefMut => {
861 let ref_rcvr = local_decls.push(
863 LocalDecl::new(
864 Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, sig.inputs()[0]),
865 span,
866 )
867 .immutable(),
868 );
869 let borrow_kind = BorrowKind::Mut { kind: MutBorrowKind::Default };
870 statements.push(Statement::new(
871 source_info,
872 StatementKind::Assign(Box::new((
873 Place::from(ref_rcvr),
874 Rvalue::Ref(tcx.lifetimes.re_erased, borrow_kind, rcvr_place()),
875 ))),
876 ));
877 Operand::Move(Place::from(ref_rcvr))
878 }
879 });
880
881 let (callee, mut args) = match call_kind {
882 CallKind::Indirect(_) => (rcvr.unwrap(), vec![]),
884
885 CallKind::Direct(def_id) => {
887 let ty = tcx.type_of(def_id).instantiate_identity().skip_norm_wip();
888 (
889 Operand::Constant(Box::new(ConstOperand {
890 span,
891 user_ty: None,
892 const_: Const::zero_sized(ty),
893 })),
894 rcvr.into_iter().collect::<Vec<_>>(),
895 )
896 }
897 };
898
899 let mut arg_range = 0..sig.inputs().len();
900
901 if rcvr_adjustment.is_some() {
903 arg_range.start += 1;
904 }
905
906 if untuple_args.is_some() {
908 arg_range.end -= 1;
909 }
910
911 args.extend(arg_range.map(|i| Operand::Move(Place::from(Local::arg(i)))));
913
914 if let Some(untuple_args) = untuple_args {
916 let tuple_arg = Local::arg(sig.inputs().len() - 1);
917 args.extend(untuple_args.iter().enumerate().map(|(i, ity)| {
918 Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), FieldIdx::new(i), *ity))
919 }));
920 }
921
922 let n_blocks = if let Some(Adjustment::RefMut) = rcvr_adjustment { 5 } else { 2 };
923 let mut blocks = IndexVec::with_capacity(n_blocks);
924 let block = |blocks: &mut IndexVec<_, _>, statements, kind, is_cleanup| {
925 blocks.push(BasicBlockData::new_stmts(
926 statements,
927 Some(Terminator { source_info, kind, attributes: ThinVec::new() }),
928 is_cleanup,
929 ))
930 };
931
932 let args = args.into_iter().map(|a| Spanned { node: a, span: DUMMY_SP }).collect();
934 block(
935 &mut blocks,
936 statements,
937 TerminatorKind::Call {
938 func: callee,
939 args,
940 destination,
941 target: Some(BasicBlock::new(1)),
942 unwind: if let Some(Adjustment::RefMut) = rcvr_adjustment {
943 UnwindAction::Cleanup(BasicBlock::new(3))
944 } else {
945 UnwindAction::Continue
946 },
947 call_source: CallSource::Misc,
948 fn_span: span,
949 },
950 false,
951 );
952
953 if let Some(Adjustment::RefMut) = rcvr_adjustment {
954 block(
956 &mut blocks,
957 vec![],
958 TerminatorKind::Drop {
959 place: rcvr_place(),
960 target: BasicBlock::new(2),
961 unwind: UnwindAction::Continue,
962 replace: false,
963 drop: None,
964 },
965 false,
966 );
967 }
968 let stmts = vec![];
970 block(&mut blocks, stmts, TerminatorKind::Return, false);
971 if let Some(Adjustment::RefMut) = rcvr_adjustment {
972 block(
974 &mut blocks,
975 vec![],
976 TerminatorKind::Drop {
977 place: rcvr_place(),
978 target: BasicBlock::new(4),
979 unwind: UnwindAction::Terminate(UnwindTerminateReason::InCleanup),
980 replace: false,
981 drop: None,
982 },
983 true,
984 );
985
986 block(&mut blocks, vec![], TerminatorKind::UnwindResume, true);
988 }
989
990 let mut body =
991 new_body(MirSource::from_shim(shim), blocks, local_decls, sig.inputs().len(), span);
992
993 if let ExternAbi::RustCall = sig.abi() {
994 body.spread_arg = Some(Local::new(sig.inputs().len()));
995 }
996
997 body
998}
999
1000pub(super) fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
1001 if true {
if !tcx.is_constructor(ctor_id) {
::core::panicking::panic("assertion failed: tcx.is_constructor(ctor_id)")
};
};debug_assert!(tcx.is_constructor(ctor_id));
1002
1003 let typing_env = ty::TypingEnv::post_analysis(tcx, ctor_id);
1004
1005 let sig = tcx
1007 .fn_sig(ctor_id)
1008 .instantiate_identity()
1009 .skip_norm_wip()
1010 .no_bound_vars()
1011 .expect("LBR in ADT constructor signature");
1012 let sig = tcx.normalize_erasing_regions(typing_env, Unnormalized::new_wip(sig));
1013
1014 let ty::Adt(adt_def, args) = sig.output().kind() else {
1015 ::rustc_middle::util::bug::bug_fmt(format_args!("unexpected type for ADT ctor {0:?}",
sig.output()));bug!("unexpected type for ADT ctor {:?}", sig.output());
1016 };
1017
1018 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:1018",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(1018u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("build_ctor: ctor_id={0:?} sig={1:?}",
ctor_id, sig) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("build_ctor: ctor_id={:?} sig={:?}", ctor_id, sig);
1019
1020 let span = tcx.def_span(ctor_id);
1021
1022 let local_decls = local_decls_for_sig(&sig, span);
1023
1024 let source_info = SourceInfo::outermost(span);
1025
1026 let variant_index =
1027 if adt_def.is_enum() { adt_def.variant_index_with_ctor_id(ctor_id) } else { FIRST_VARIANT };
1028
1029 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs:1035",
"rustc_mir_transform::shim", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/a69a63265cfd9e006d43137f98301b8d274ad4c9/compiler/rustc_mir_transform/src/shim.rs"),
::tracing_core::__macro_support::Option::Some(1035u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_transform::shim"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("build_ctor: variant_index={0:?}",
variant_index) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("build_ctor: variant_index={:?}", variant_index);
1036
1037 let kind = AggregateKind::Adt(adt_def.did(), variant_index, args, None, None);
1038 let variant = adt_def.variant(variant_index);
1039 let statement = Statement::new(
1040 source_info,
1041 StatementKind::Assign(Box::new((
1042 Place::return_place(),
1043 Rvalue::Aggregate(
1044 Box::new(kind),
1045 (0..variant.fields.len())
1046 .map(|idx| Operand::Move(Place::from(Local::arg(idx))))
1047 .collect(),
1048 ),
1049 ))),
1050 );
1051
1052 let start_block = BasicBlockData::new_stmts(
1053 ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[statement]))vec![statement],
1054 Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }),
1055 false,
1056 );
1057
1058 let source = MirSource::item(ctor_id);
1059 let mut body = new_body(
1060 source,
1061 IndexVec::from_elem_n(start_block, 1),
1062 local_decls,
1063 sig.inputs().len(),
1064 span,
1065 );
1066 body.set_mentioned_items(Vec::new());
1069
1070 pm::run_passes_no_validate(
1073 tcx,
1074 &mut body,
1075 &[],
1076 Some(MirPhase::Runtime(RuntimePhase::Optimized)),
1077 );
1078
1079 body
1080}
1081
1082fn build_fn_ptr_as_ptr_shim<'tcx>(
1090 tcx: TyCtxt<'tcx>,
1091 def_id: DefId,
1092 self_ty: Ty<'tcx>,
1093) -> Body<'tcx> {
1094 {
match self_ty.kind() {
ty::FnPtr(..) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"ty::FnPtr(..)",
::core::option::Option::Some(format_args!("expected fn ptr, found {0}",
self_ty)));
}
}
};assert_matches!(self_ty.kind(), ty::FnPtr(..), "expected fn ptr, found {self_ty}");
1095
1096 let span = tcx.def_span(def_id);
1097 let nonnull_did = tcx.require_lang_item(LangItem::NonNull, span);
1098 let code_did = tcx.require_lang_item(LangItem::Code, span);
1099 let nonnull_ty = tcx
1100 .type_of(nonnull_did)
1101 .instantiate(
1102 tcx,
1103 &[ty::GenericArg::from(tcx.type_of(code_did).instantiate_identity().skip_norm_wip())],
1104 )
1105 .skip_norm_wip();
1106
1107 let Some(sig) =
1108 tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).skip_norm_wip().no_bound_vars()
1109 else {
1110 ::rustc_middle::util::bug::span_bug_fmt(span,
format_args!("FnPtr::as_ptr with bound vars for `{0}`", self_ty));span_bug!(span, "FnPtr::as_ptr with bound vars for `{self_ty}`");
1111 };
1112 let mut locals = local_decls_for_sig(&sig, span);
1113
1114 let source_info = SourceInfo::outermost(span);
1115
1116 let mut statements = ::alloc::vec::Vec::new()vec![];
1117 let raw_unit_ptr = Ty::new_imm_ptr(tcx, tcx.types.unit);
1120 let cast_to_raw_rvalue =
1121 Rvalue::Cast(CastKind::FnPtrToPtr, Operand::Move(Place::from(Local::arg(0))), raw_unit_ptr);
1122 let raw_ptr = locals.push(LocalDecl::with_source_info(raw_unit_ptr, source_info)).into();
1123 statements.push(Statement::new(
1124 source_info,
1125 StatementKind::Assign(Box::new((raw_ptr, cast_to_raw_rvalue))),
1126 ));
1127
1128 let transmute_to_nonnull =
1129 Rvalue::Cast(CastKind::Transmute, Operand::Move(Place::from(raw_ptr)), nonnull_ty);
1130 statements.push(Statement::new(
1131 source_info,
1132 StatementKind::Assign(Box::new((Place::return_place(), transmute_to_nonnull))),
1133 ));
1134
1135 let start_block = BasicBlockData::new_stmts(
1136 statements,
1137 Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }),
1138 false,
1139 );
1140 let source = MirSource::from_shim(ty::ShimKind::FnPtrAsPtr(def_id, self_ty));
1141 new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span)
1142}
1143
1144fn build_fn_ptr_from_ptr_shim<'tcx>(
1145 tcx: TyCtxt<'tcx>,
1146 def_id: DefId,
1147 self_ty: Ty<'tcx>,
1148) -> Body<'tcx> {
1149 {
match self_ty.kind() {
ty::FnPtr(..) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"ty::FnPtr(..)",
::core::option::Option::Some(format_args!("expected fn ptr, found {0}",
self_ty)));
}
}
};assert_matches!(self_ty.kind(), ty::FnPtr(..), "expected fn ptr, found {self_ty}");
1150
1151 let span = tcx.def_span(def_id);
1152
1153 let Some(sig) =
1154 tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]).skip_norm_wip().no_bound_vars()
1155 else {
1156 ::rustc_middle::util::bug::span_bug_fmt(span,
format_args!("FnPtr::as_ptr with bound vars for `{0}`", self_ty));span_bug!(span, "FnPtr::as_ptr with bound vars for `{self_ty}`");
1157 };
1158 let locals = local_decls_for_sig(&sig, span);
1159
1160 let source_info = SourceInfo::outermost(span);
1161
1162 let mut statements = ::alloc::vec::Vec::new()vec![];
1163 let transmute_to_self =
1164 Rvalue::Cast(CastKind::Transmute, Operand::Move(Place::from(Local::arg(0))), self_ty);
1165 statements.push(Statement::new(
1166 source_info,
1167 StatementKind::Assign(Box::new((Place::return_place(), transmute_to_self))),
1168 ));
1169
1170 let start_block = BasicBlockData::new_stmts(
1171 statements,
1172 Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }),
1173 false,
1174 );
1175 let source = MirSource::from_shim(ty::ShimKind::FnPtrFromPtr(def_id, self_ty));
1176 new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span)
1177}
1178
1179fn build_construct_coroutine_by_move_shim<'tcx>(
1180 tcx: TyCtxt<'tcx>,
1181 coroutine_closure_def_id: DefId,
1182 receiver_by_ref: bool,
1183) -> Body<'tcx> {
1184 let mut self_ty = tcx.type_of(coroutine_closure_def_id).instantiate_identity().skip_norm_wip();
1185 let mut self_local: Place<'tcx> = Local::arg(0).into();
1186 let ty::CoroutineClosure(_, args) = *self_ty.kind() else {
1187 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"));bug!();
1188 };
1189
1190 if receiver_by_ref {
1196 self_local = tcx.mk_place_deref(self_local);
1197 self_ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, self_ty);
1198 }
1199
1200 let poly_sig = args.as_coroutine_closure().coroutine_closure_sig().map_bound(|sig| {
1201 tcx.mk_fn_sig(
1202 [self_ty].into_iter().chain(sig.tupled_inputs_ty.tuple_fields()),
1203 sig.to_coroutine_given_kind_and_upvars(
1204 tcx,
1205 args.as_coroutine_closure().parent_args(),
1206 tcx.coroutine_for_closure(coroutine_closure_def_id),
1207 ty::ClosureKind::FnOnce,
1208 tcx.lifetimes.re_erased,
1209 args.as_coroutine_closure().tupled_upvars_ty(),
1210 args.as_coroutine_closure().coroutine_captures_by_ref_ty(),
1211 ),
1212 sig.fn_sig_kind,
1213 )
1214 });
1215 let sig = tcx.liberate_late_bound_regions(coroutine_closure_def_id, poly_sig);
1216 let ty::Coroutine(coroutine_def_id, coroutine_args) = *sig.output().kind() else {
1217 ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"));bug!();
1218 };
1219
1220 let span = tcx.def_span(coroutine_closure_def_id);
1221 let locals = local_decls_for_sig(&sig, span);
1222
1223 let mut fields = ::alloc::vec::Vec::new()vec![];
1224
1225 for idx in 1..sig.inputs().len() {
1227 fields.push(Operand::Move(Local::arg(idx).into()));
1228 }
1229
1230 for (idx, ty) in args.as_coroutine_closure().upvar_tys().iter().enumerate() {
1231 if receiver_by_ref {
1232 if !#[allow(non_exhaustive_omitted_patterns)] match ty.kind() {
ty::Ref(_, _, hir::Mutability::Not) => true,
_ => false,
}matches!(ty.kind(), ty::Ref(_, _, hir::Mutability::Not)) {
1236 tcx.dcx().delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("field should be captured by immutable ref if we have an `Fn` instance, but it was: {0}",
ty))
})format!(
1240 "field should be captured by immutable ref if we have \
1241 an `Fn` instance, but it was: {ty}"
1242 ));
1243 }
1244 fields.push(Operand::Copy(tcx.mk_place_field(
1245 self_local,
1246 FieldIdx::from_usize(idx),
1247 ty,
1248 )));
1249 } else {
1250 fields.push(Operand::Move(tcx.mk_place_field(
1251 self_local,
1252 FieldIdx::from_usize(idx),
1253 ty,
1254 )));
1255 }
1256 }
1257
1258 let source_info = SourceInfo::outermost(span);
1259 let rvalue = Rvalue::Aggregate(
1260 Box::new(AggregateKind::Coroutine(coroutine_def_id, coroutine_args)),
1261 IndexVec::from_raw(fields),
1262 );
1263 let stmt = Statement::new(
1264 source_info,
1265 StatementKind::Assign(Box::new((Place::return_place(), rvalue))),
1266 );
1267 let statements = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[stmt]))vec![stmt];
1268 let start_block = BasicBlockData::new_stmts(
1269 statements,
1270 Some(Terminator { source_info, kind: TerminatorKind::Return, attributes: ThinVec::new() }),
1271 false,
1272 );
1273
1274 let source = MirSource::from_shim(ty::ShimKind::ConstructCoroutineInClosure {
1275 coroutine_closure_def_id,
1276 receiver_by_ref,
1277 });
1278
1279 let body =
1280 new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span);
1281
1282 let pass_name =
1283 if receiver_by_ref { "coroutine_closure_by_ref" } else { "coroutine_closure_by_move" };
1284 if let Some(dumper) = MirDumper::new(tcx, pass_name, &body) {
1285 dumper.dump_mir(&body);
1286 }
1287
1288 body
1289}