1use std::mem;
2
3use rustc_index::IndexVec;
4use rustc_middle::mir::*;
5use rustc_middle::ty::consts::ConstExt;
6use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
7use rustc_span::{bug, span_bug};
8use smallvec::{SmallVec, smallvec};
9use tracing::debug;
10
11use super::{
12 Init, InitIndex, InitKind, InitLocation, LocationMap, LookupResult, MoveData, MoveOut,
13 MoveOutIndex, MovePath, MovePathIndex, MovePathLookup, MoveSubPath, MoveSubPathResult,
14};
15
16struct MoveDataBuilder<'a, 'tcx, F> {
17 body: &'a Body<'tcx>,
18 loc: Location,
19 tcx: TyCtxt<'tcx>,
20 data: MoveData<'tcx>,
21 filter: F,
22}
23
24impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
25 fn new(body: &'a Body<'tcx>, tcx: TyCtxt<'tcx>, filter: F) -> Self {
26 let mut move_paths = IndexVec::new();
27 let mut move_out_path_map = IndexVec::new();
28 let mut init_path_map = IndexVec::new();
29
30 let locals = body
31 .local_decls
32 .iter_enumerated()
33 .map(|(i, l)| {
34 if l.is_deref_temp() {
35 return None;
36 }
37 if filter(l.ty) {
38 Some(new_move_path(
39 &mut move_paths,
40 &mut move_out_path_map,
41 &mut init_path_map,
42 None,
43 Place::from(i),
44 ))
45 } else {
46 None
47 }
48 })
49 .collect();
50
51 MoveDataBuilder {
52 body,
53 loc: Location::START,
54 tcx,
55 data: MoveData {
56 move_outs: IndexVec::new(),
57 move_out_loc_map: LocationMap::new(body),
58 rev_lookup: MovePathLookup {
59 locals,
60 projections: Default::default(),
61 un_derefer: Default::default(),
62 },
63 move_paths,
64 move_out_path_map,
65 inits: IndexVec::new(),
66 init_loc_map: LocationMap::new(body),
67 init_path_map,
68 },
69 filter,
70 }
71 }
72}
73
74fn new_move_path<'tcx>(
75 move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
76 move_out_path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
77 init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
78 parent: Option<MovePathIndex>,
79 place: Place<'tcx>,
80) -> MovePathIndex {
81 let move_path =
82 move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
83
84 if let Some(parent) = parent {
85 let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
86 move_paths[move_path].next_sibling = next_sibling;
87 }
88
89 let path_map_ent = move_out_path_map.push(::smallvec::SmallVec::new()smallvec![]);
90 {
match (&path_map_ent, &move_path) {
(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!(path_map_ent, move_path);
91
92 let init_path_map_ent = init_path_map.push(::smallvec::SmallVec::new()smallvec![]);
93 {
match (&init_path_map_ent, &move_path) {
(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!(init_path_map_ent, move_path);
94
95 move_path
96}
97
98impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
99 fn move_path_for<G>(&mut self, place: Place<'tcx>, mut on_move: G)
109 where
110 G: FnMut(&mut Self, MovePathIndex),
111 {
112 let data = &mut self.data;
113
114 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:114",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(114u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("lookup({0:?})",
place) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("lookup({:?})", place);
115 let Some(mut base) = data.rev_lookup.find_local(place.local) else {
116 return;
117 };
118
119 let mut union_path = None;
125
126 let mut iter = data.rev_lookup.un_derefer.iter_projections(place.as_ref());
127 while let Some((place_ref, elem)) = iter.next() {
128 let body = self.body;
129 let tcx = self.tcx;
130 let place_ty = place_ref.ty(body, tcx).ty;
131 if place_ty.references_error() {
132 return;
133 }
134
135 let res = MoveSubPath::of(elem.kind());
136
137 let move_elem = match res {
138 MoveSubPathResult::One(move_elem) => {
139 match move_elem {
140 MoveSubPath::Deref => match place_ty.kind() {
141 ty::Ref(..) | ty::RawPtr(..) => {
142 return;
143 }
144 ty::Adt(adt, _) => {
145 if !adt.is_box() {
146 ::rustc_span::macros::bug_impl(None,
format_args!("Adt should be a box type when Place is deref"),
Location::caller());bug!("Adt should be a box type when Place is deref");
147 }
148 }
149 ty::Bool
150 | ty::Char
151 | ty::Int(_)
152 | ty::Uint(_)
153 | ty::Float(_)
154 | ty::Foreign(_)
155 | ty::Str
156 | ty::Array(_, _)
157 | ty::Pat(_, _)
158 | ty::Slice(_)
159 | ty::FnDef(_, _)
160 | ty::FnPtr(..)
161 | ty::Dynamic(_, _)
162 | ty::Closure(..)
163 | ty::CoroutineClosure(..)
164 | ty::Coroutine(_, _)
165 | ty::CoroutineWitness(..)
166 | ty::Never
167 | ty::Tuple(_)
168 | ty::UnsafeBinder(_)
169 | ty::Alias(_, _)
170 | ty::Param(_)
171 | ty::Bound(_, _)
172 | ty::Infer(_)
173 | ty::Error(_)
174 | ty::Placeholder(_) => {
175 ::rustc_span::macros::bug_impl(None,
format_args!("When Place is Deref it\'s type shouldn\'t be {0:#?}",
place_ty), Location::caller())bug!("When Place is Deref it's type shouldn't be {place_ty:#?}")
176 }
177 },
178 MoveSubPath::Field(_) => match place_ty.kind() {
179 ty::Adt(adt, _) => {
180 if adt.has_dtor(tcx) {
181 return;
182 }
183 if adt.is_union() {
184 union_path.get_or_insert(base);
185 }
186 }
187 ty::Closure(..)
188 | ty::CoroutineClosure(..)
189 | ty::Coroutine(_, _)
190 | ty::Tuple(_) => (),
191 ty::Bool
192 | ty::Char
193 | ty::Int(_)
194 | ty::Uint(_)
195 | ty::Float(_)
196 | ty::Foreign(_)
197 | ty::Str
198 | ty::Array(_, _)
199 | ty::Pat(_, _)
200 | ty::Slice(_)
201 | ty::RawPtr(_, _)
202 | ty::Ref(_, _, _)
203 | ty::FnDef(_, _)
204 | ty::FnPtr(..)
205 | ty::Dynamic(_, _)
206 | ty::CoroutineWitness(..)
207 | ty::Never
208 | ty::UnsafeBinder(_)
209 | ty::Alias(_, _)
210 | ty::Param(_)
211 | ty::Bound(_, _)
212 | ty::Infer(_)
213 | ty::Error(_)
214 | ty::Placeholder(_) => ::rustc_span::macros::bug_impl(None,
format_args!("When Place contains ProjectionElem::Field its type shouldn\'t be {0:#?}",
place_ty), Location::caller())bug!(
215 "When Place contains ProjectionElem::Field its type shouldn't be {place_ty:#?}"
216 ),
217 },
218 MoveSubPath::ConstantIndex(_) => match place_ty.kind() {
219 ty::Slice(_) => {
220 return;
221 }
222 ty::Array(_, _) => (),
223 _ => ::rustc_span::macros::bug_impl(None,
format_args!("Unexpected type {0:#?}", place_ty.is_array()),
Location::caller())bug!("Unexpected type {:#?}", place_ty.is_array()),
224 },
225 MoveSubPath::Downcast(_) => (),
226 MoveSubPath::UnwrapUnsafeBinder => (),
227 };
228
229 move_elem
230 }
231
232 MoveSubPathResult::Subslice { from, to } => {
236 if !iter.all(|(_, elem)|
MoveSubPath::of(elem.kind()) == MoveSubPathResult::Skip) {
::core::panicking::panic("assertion failed: iter.all(|(_, elem)| MoveSubPath::of(elem.kind()) == MoveSubPathResult::Skip)")
};assert!(
237 iter.all(
238 |(_, elem)| MoveSubPath::of(elem.kind()) == MoveSubPathResult::Skip
239 )
240 );
241 drop(iter); let (&elem_ty, len) = match place_ty.kind() {
244 ty::Array(ty, size) => (
245 ty,
246 size.try_to_target_usize(self.tcx)
247 .expect("expected subslice projection on fixed-size array"),
248 ),
249 _ => ::rustc_span::macros::bug_impl(None,
format_args!("from_end: false slice pattern of non-array type"),
Location::caller())bug!("from_end: false slice pattern of non-array type"),
250 };
251
252 if !(self.filter)(elem_ty) {
253 return;
254 }
255
256 for offset in from..to {
257 let place_elem =
258 PlaceElem::ConstantIndex { offset, min_length: len, from_end: false };
259 let subpath_elem = MoveSubPath::ConstantIndex(offset);
260
261 let mpi = self.add_move_path(base, subpath_elem, |tcx| {
262 place_ref.project_deeper(&[place_elem], tcx)
263 });
264 on_move(self, mpi);
265 }
266
267 return;
268 }
269
270 MoveSubPathResult::Skip => continue,
271 MoveSubPathResult::Stop => return,
272 };
273
274 let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty;
275 if !(self.filter)(elem_ty) {
276 return;
277 }
278 if union_path.is_none() {
279 base = *data.rev_lookup.projections.entry((base, move_elem)).or_insert_with(|| {
281 new_move_path(
282 &mut data.move_paths,
283 &mut data.move_out_path_map,
284 &mut data.init_path_map,
285 Some(base),
286 place_ref.project_deeper(&[elem], tcx),
287 )
288 })
289 }
290 }
291
292 drop(iter); if let Some(base) = union_path {
295 on_move(self, base);
297 } else {
298 on_move(self, base);
299 }
300 }
301
302 fn add_move_path(
303 &mut self,
304 base: MovePathIndex,
305 elem: MoveSubPath,
306 mk_place: impl FnOnce(TyCtxt<'tcx>) -> Place<'tcx>,
307 ) -> MovePathIndex {
308 let MoveDataBuilder {
309 data: MoveData { rev_lookup, move_paths, move_out_path_map, init_path_map, .. },
310 tcx,
311 ..
312 } = self;
313 *rev_lookup.projections.entry((base, elem)).or_insert_with(move || {
314 new_move_path(move_paths, move_out_path_map, init_path_map, Some(base), mk_place(*tcx))
315 })
316 }
317
318 fn create_move_path(&mut self, place: Place<'tcx>) {
319 self.move_path_for(place, |_, _| ());
322 }
323
324 fn finalize(self) -> MoveData<'tcx> {
325 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:325",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(325u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("{0}",
{
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:326",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(326u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("moves for {0:?}:",
self.body.span) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
for (j, mo) in self.data.move_outs.iter_enumerated() {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:328",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(328u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!(" {0:?} = {1:?}",
j, mo) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
}
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:330",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(330u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("move paths for {0:?}:",
self.body.span) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
for (j, path) in self.data.move_paths.iter_enumerated() {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:332",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(332u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!(" {0:?} = {1:?}",
j, path) as &dyn ::tracing::field::Value))])
});
} else { ; }
};
}
"done dumping moves"
}) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("{}", {
326 debug!("moves for {:?}:", self.body.span);
327 for (j, mo) in self.data.move_outs.iter_enumerated() {
328 debug!(" {:?} = {:?}", j, mo);
329 }
330 debug!("move paths for {:?}:", self.body.span);
331 for (j, path) in self.data.move_paths.iter_enumerated() {
332 debug!(" {:?} = {:?}", j, path);
333 }
334 "done dumping moves"
335 });
336
337 self.data
338 }
339}
340
341pub(super) fn gather_moves<'tcx>(
342 body: &Body<'tcx>,
343 tcx: TyCtxt<'tcx>,
344 filter: impl Fn(Ty<'tcx>) -> bool,
345) -> MoveData<'tcx> {
346 let mut builder = MoveDataBuilder::new(body, tcx, filter);
347
348 builder.gather_args();
349
350 for (bb, block) in body.basic_blocks.iter_enumerated() {
351 for (i, stmt) in block.statements.iter().enumerate() {
352 builder.loc = Location { block: bb, statement_index: i };
353 builder.gather_statement(stmt);
354 }
355
356 builder.loc = Location { block: bb, statement_index: block.statements.len() };
357 builder.gather_terminator(block.terminator());
358 }
359
360 builder.finalize()
361}
362
363impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
364 fn gather_args(&mut self) {
365 for arg in self.body.args_iter() {
366 if let Some(path) = self.data.rev_lookup.find_local(arg) {
367 let init = self.data.inits.push(Init {
368 path,
369 kind: InitKind::Deep,
370 location: InitLocation::Argument(arg),
371 });
372
373 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:373",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(373u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("gather_args: adding init {0:?} of {1:?} for argument {2:?}",
init, path, arg) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("gather_args: adding init {:?} of {:?} for argument {:?}", init, path, arg);
374
375 self.data.init_path_map[path].push(init);
376 }
377 }
378 }
379
380 fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
381 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:381",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(381u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("gather_statement({0:?}, {1:?})",
self.loc, stmt) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("gather_statement({:?}, {:?})", self.loc, stmt);
382 match &stmt.kind {
383 StatementKind::Assign((place, Rvalue::CopyForDeref(reffed))) => {
384 let local = place.as_local().unwrap();
385 if !self.body.local_decls[local].is_deref_temp() {
::core::panicking::panic("assertion failed: self.body.local_decls[local].is_deref_temp()")
};assert!(self.body.local_decls[local].is_deref_temp());
386
387 let rev_lookup = &mut self.data.rev_lookup;
388
389 rev_lookup.un_derefer.insert(local, reffed.as_ref());
390 let base_local = rev_lookup.un_derefer.deref_chain(local).first().unwrap().local;
391 rev_lookup.locals[local] = rev_lookup.locals[base_local];
392 }
393 StatementKind::Assign((place, rval)) => {
394 self.create_move_path(*place);
395 self.gather_init(place.as_ref(), InitKind::Deep);
396 self.gather_rvalue(rval);
397 }
398 StatementKind::FakeRead((_, place)) => {
399 self.create_move_path(*place);
400 }
401 StatementKind::StorageLive(_) => {}
402 StatementKind::StorageDead(local) => {
403 if !self.body.local_decls[*local].is_deref_temp() {
405 self.gather_move(Place::from(*local));
406 }
407 }
408 StatementKind::SetDiscriminant { .. } => {
409 ::rustc_span::macros::bug_impl(Some(stmt.source_info.span),
format_args!("SetDiscriminant/Deinit should not exist during borrowck"),
Location::caller());span_bug!(
410 stmt.source_info.span,
411 "SetDiscriminant/Deinit should not exist during borrowck"
412 );
413 }
414 StatementKind::AscribeUserType(..)
415 | StatementKind::PlaceMention(..)
416 | StatementKind::Coverage(..)
417 | StatementKind::Intrinsic(..)
418 | StatementKind::ConstEvalCounter
419 | StatementKind::BackwardIncompatibleDropHint { .. }
420 | StatementKind::Nop => {}
421 }
422 }
423
424 fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
425 match *rvalue {
426 Rvalue::ThreadLocalRef(_) => {} Rvalue::Use(ref operand, _)
428 | Rvalue::Repeat(ref operand, _)
429 | Rvalue::Cast(_, ref operand, _)
430 | Rvalue::UnaryOp(_, ref operand)
431 | Rvalue::WrapUnsafeBinder(ref operand, _) => self.gather_operand(operand),
432 Rvalue::BinaryOp(ref _binop, (ref lhs, ref rhs)) => {
433 self.gather_operand(lhs);
434 self.gather_operand(rhs);
435 }
436 Rvalue::Aggregate(ref _kind, ref operands) => {
437 for operand in operands {
438 self.gather_operand(operand);
439 }
440 }
441 Rvalue::CopyForDeref(..) => ::core::panicking::panic("internal error: entered unreachable code")unreachable!(),
442 Rvalue::Ref(..)
443 | Rvalue::Reborrow(..)
444 | Rvalue::RawPtr(..)
445 | Rvalue::Discriminant(..) => {}
446 }
447 }
448
449 fn gather_terminator(&mut self, term: &Terminator<'tcx>) {
450 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:450",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(450u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("gather_terminator({0:?}, {1:?})",
self.loc, term) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("gather_terminator({:?}, {:?})", self.loc, term);
451 match term.kind {
452 TerminatorKind::Goto { target: _ }
453 | TerminatorKind::FalseEdge { .. }
454 | TerminatorKind::FalseUnwind { .. } => {}
455 TerminatorKind::Return
460 | TerminatorKind::UnwindResume
461 | TerminatorKind::UnwindTerminate(_)
462 | TerminatorKind::CoroutineDrop
463 | TerminatorKind::Unreachable
464 | TerminatorKind::Drop { .. } => {}
465
466 TerminatorKind::Assert { ref cond, .. } => {
467 self.gather_operand(cond);
468 }
469
470 TerminatorKind::SwitchInt { ref discr, .. } => {
471 self.gather_operand(discr);
472 }
473
474 TerminatorKind::Yield { ref value, resume_arg: place, .. } => {
475 self.gather_operand(value);
476 self.create_move_path(place);
477 self.gather_init(place.as_ref(), InitKind::Deep);
478 }
479 TerminatorKind::Call {
480 ref func,
481 ref args,
482 destination,
483 target,
484 unwind: _,
485 call_source: _,
486 fn_span: _,
487 } => {
488 self.gather_operand(func);
489 for arg in args {
490 self.gather_operand(&arg.node);
491 }
492 if let Some(_bb) = target {
493 self.create_move_path(destination);
494 self.gather_init(destination.as_ref(), InitKind::NonPanicPathOnly);
495 }
496 }
497 TerminatorKind::TailCall { ref func, ref args, .. } => {
498 self.gather_operand(func);
499 for arg in args {
500 self.gather_operand(&arg.node);
501 }
502 }
503 TerminatorKind::InlineAsm {
504 asm_macro: _,
505 template: _,
506 ref operands,
507 options: _,
508 line_spans: _,
509 targets: _,
510 unwind: _,
511 } => {
512 for op in operands {
513 match *op {
514 InlineAsmOperand::In { reg: _, ref value } => {
515 self.gather_operand(value);
516 }
517 InlineAsmOperand::Out { reg: _, late: _, place, .. } => {
518 if let Some(place) = place {
519 self.create_move_path(place);
520 self.gather_init(place.as_ref(), InitKind::Deep);
521 }
522 }
523 InlineAsmOperand::InOut { reg: _, late: _, ref in_value, out_place } => {
524 self.gather_operand(in_value);
525 if let Some(out_place) = out_place {
526 self.create_move_path(out_place);
527 self.gather_init(out_place.as_ref(), InitKind::Deep);
528 }
529 }
530 InlineAsmOperand::Const { value: _ }
531 | InlineAsmOperand::SymFn { value: _ }
532 | InlineAsmOperand::SymStatic { def_id: _ }
533 | InlineAsmOperand::Label { target_index: _ } => {}
534 }
535 }
536 }
537 }
538 }
539
540 fn gather_operand(&mut self, operand: &Operand<'tcx>) {
541 match *operand {
542 Operand::Constant(..) | Operand::Copy(..) | Operand::RuntimeChecks(_) => {}
544 Operand::Move(place) => {
546 self.gather_move(place);
547 }
548 }
549 }
550
551 fn gather_move(&mut self, place: Place<'tcx>) {
552 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:552",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(552u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("gather_move({0:?}, {1:?})",
self.loc, place) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("gather_move({:?}, {:?})", self.loc, place);
553 self.move_path_for(place, |this, mpi| this.record_move(place, mpi));
554 }
555
556 fn record_move(&mut self, place: Place<'tcx>, path: MovePathIndex) {
557 let move_out = self.data.move_outs.push(MoveOut { path, source: self.loc });
558 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:558",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(558u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("gather_move({0:?}, {1:?}): adding move {2:?} of {3:?}",
self.loc, place, move_out, path) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
559 "gather_move({:?}, {:?}): adding move {:?} of {:?}",
560 self.loc, place, move_out, path
561 );
562 self.data.move_out_path_map[path].push(move_out);
563 self.data.move_out_loc_map[self.loc].push(move_out);
564 }
565
566 fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) {
567 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:567",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(567u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("gather_init({0:?}, {1:?})",
self.loc, place) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("gather_init({:?}, {:?})", self.loc, place);
568
569 let mut place = place;
570
571 if let Some((place_base, ProjectionElem::Field(_, _))) = place.last_projection() {
574 if place_base.ty(self.body, self.tcx).ty.is_union() {
575 place = place_base;
576 }
577 }
578
579 if let LookupResult::Exact(path) = self.data.rev_lookup.find(place) {
580 let init = self.data.inits.push(Init {
581 location: InitLocation::Statement(self.loc),
582 path,
583 kind,
584 });
585
586 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event /rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs:586",
"rustc_mir_dataflow::move_paths::builder",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("/rustc-dev/5ceaf6608eb354c2f5bbb3b8d974caa367dac81c/compiler/rustc_mir_dataflow/src/move_paths/builder.rs"),
::tracing_core::__macro_support::Option::Some(586u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::move_paths::builder"),
::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!("gather_init({0:?}, {1:?}): adding init {2:?} of {3:?}",
self.loc, place, init, path) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!(
587 "gather_init({:?}, {:?}): adding init {:?} of {:?}",
588 self.loc, place, init, path
589 );
590
591 self.data.init_path_map[path].push(init);
592 self.data.init_loc_map[self.loc].push(init);
593 }
594 }
595}