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