1use std::assert_matches;
2
3use rustc_abi::VariantIdx;
4use rustc_index::Idx;
5use rustc_index::bit_set::{DenseBitSet, MixedBitSet};
6use rustc_middle::bug;
7use rustc_middle::mir::{
8 self, Body, CallReturnPlaces, Location, SwitchTargetValue, TerminatorEdges,
9};
10use rustc_middle::ty::util::Discr;
11use rustc_middle::ty::{self, TyCtxt};
12use smallvec::SmallVec;
13use tracing::{debug, instrument};
14
15use crate::drop_flag_effects::{DropFlagState, InactiveVariants};
16use crate::move_paths::{HasMoveData, InitIndex, InitKind, LookupResult, MoveData, MovePathIndex};
17use crate::{
18 Analysis, GenKill, MaybeReachable, drop_flag_effects, drop_flag_effects_for_function_entry,
19 drop_flag_effects_for_location, on_all_children_bits, on_lookup_result_bits,
20};
21
22pub struct MaybePlacesSwitchIntData<'tcx> {
24 enum_place: mir::Place<'tcx>,
25 discriminants: Vec<(VariantIdx, Discr<'tcx>)>,
26 index: usize,
27}
28
29impl<'tcx> MaybePlacesSwitchIntData<'tcx> {
30 fn variants(&mut self, targets: &mir::SwitchTargets) -> SmallVec<[VariantIdx; 4]> {
32 self.index = 0;
33 targets.all_values().iter().map(|value| self.next_discr(value.get())).collect()
34 }
35
36 fn next_discr(&mut self, value: u128) -> VariantIdx {
40 loop {
42 let (variant, discr) = self.discriminants[self.index];
43 self.index += 1;
44 if discr.val == value {
45 return variant;
46 }
47 }
48 }
49}
50
51impl<'tcx> MaybePlacesSwitchIntData<'tcx> {
52 fn new(
53 tcx: TyCtxt<'tcx>,
54 body: &Body<'tcx>,
55 block: mir::BasicBlock,
56 discr: &mir::Operand<'tcx>,
57 ) -> Option<Self> {
58 let Some(discr) = discr.place() else { return None };
59
60 let block_data = &body[block];
72 for statement in block_data.statements.iter().rev() {
73 match statement.kind {
74 mir::StatementKind::Assign(box (lhs, mir::Rvalue::Discriminant(enum_place)))
75 if lhs == discr =>
76 {
77 match enum_place.ty(body, tcx).ty.kind() {
78 ty::Adt(enum_def, _) => {
79 return Some(MaybePlacesSwitchIntData {
80 enum_place,
81 discriminants: enum_def.discriminants(tcx).collect(),
82 index: 0,
83 });
84 }
85
86 ty::Coroutine(..) => break,
90
91 t => ::rustc_middle::util::bug::bug_fmt(format_args!("`discriminant` called on unexpected type {0:?}",
t))bug!("`discriminant` called on unexpected type {:?}", t),
92 }
93 }
94 mir::StatementKind::Coverage(_) => continue,
95 _ => break,
96 }
97 }
98 None
99 }
100}
101
102pub struct MaybeInitializedPlaces<'a, 'tcx> {
139 tcx: TyCtxt<'tcx>,
140 body: &'a Body<'tcx>,
141 move_data: &'a MoveData<'tcx>,
142 exclude_inactive_in_otherwise: bool,
143 skip_unreachable_unwind: bool,
144}
145
146impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
147 pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
148 MaybeInitializedPlaces {
149 tcx,
150 body,
151 move_data,
152 exclude_inactive_in_otherwise: false,
153 skip_unreachable_unwind: false,
154 }
155 }
156
157 pub fn exclude_inactive_in_otherwise(mut self) -> Self {
160 self.exclude_inactive_in_otherwise = true;
161 self
162 }
163
164 pub fn skipping_unreachable_unwind(mut self) -> Self {
165 self.skip_unreachable_unwind = true;
166 self
167 }
168
169 pub fn is_unwind_dead(
170 &self,
171 place: mir::Place<'tcx>,
172 state: &<Self as Analysis<'tcx>>::Domain,
173 ) -> bool {
174 if let LookupResult::Exact(path) = self.move_data().rev_lookup.find(place.as_ref()) {
175 let mut maybe_live = false;
176 on_all_children_bits(self.move_data(), path, |child| {
177 maybe_live |= state.contains(child);
178 });
179 !maybe_live
180 } else {
181 false
182 }
183 }
184}
185
186impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
187 fn move_data(&self) -> &MoveData<'tcx> {
188 self.move_data
189 }
190}
191
192pub struct MaybeUninitializedPlaces<'a, 'tcx> {
229 tcx: TyCtxt<'tcx>,
230 body: &'a Body<'tcx>,
231 move_data: &'a MoveData<'tcx>,
232
233 mark_inactive_variants_as_uninit: bool,
234 include_inactive_in_otherwise: bool,
235 skip_unreachable_unwind: DenseBitSet<mir::BasicBlock>,
236}
237
238impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
239 pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
240 MaybeUninitializedPlaces {
241 tcx,
242 body,
243 move_data,
244 mark_inactive_variants_as_uninit: false,
245 include_inactive_in_otherwise: false,
246 skip_unreachable_unwind: DenseBitSet::new_empty(body.basic_blocks.len()),
247 }
248 }
249
250 pub fn mark_inactive_variants_as_uninit(mut self) -> Self {
256 self.mark_inactive_variants_as_uninit = true;
257 self
258 }
259
260 pub fn include_inactive_in_otherwise(mut self) -> Self {
263 self.include_inactive_in_otherwise = true;
264 self
265 }
266
267 pub fn skipping_unreachable_unwind(
268 mut self,
269 unreachable_unwind: DenseBitSet<mir::BasicBlock>,
270 ) -> Self {
271 self.skip_unreachable_unwind = unreachable_unwind;
272 self
273 }
274}
275
276impl<'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
277 fn move_data(&self) -> &MoveData<'tcx> {
278 self.move_data
279 }
280}
281
282pub struct EverInitializedPlaces<'a, 'tcx> {
315 body: &'a Body<'tcx>,
316 move_data: &'a MoveData<'tcx>,
317}
318
319impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> {
320 pub fn new(body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
321 EverInitializedPlaces { body, move_data }
322 }
323}
324
325impl<'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'_, 'tcx> {
326 fn move_data(&self) -> &MoveData<'tcx> {
327 self.move_data
328 }
329}
330
331impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
332 fn update_bits(
333 state: &mut <Self as Analysis<'tcx>>::Domain,
334 path: MovePathIndex,
335 dfstate: DropFlagState,
336 ) {
337 match dfstate {
338 DropFlagState::Absent => state.kill(path),
339 DropFlagState::Present => state.gen_(path),
340 }
341 }
342}
343
344impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> {
345 fn update_bits(
346 state: &mut <Self as Analysis<'tcx>>::Domain,
347 path: MovePathIndex,
348 dfstate: DropFlagState,
349 ) {
350 match dfstate {
351 DropFlagState::Absent => state.gen_(path),
352 DropFlagState::Present => state.kill(path),
353 }
354 }
355}
356
357impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
358 type Domain = MaybeReachable<MixedBitSet<MovePathIndex>>;
361
362 type SwitchIntData = MaybePlacesSwitchIntData<'tcx>;
363
364 const NAME: &'static str = "maybe_init";
365
366 fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
367 MaybeReachable::Unreachable
369 }
370
371 fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) {
372 *state =
373 MaybeReachable::Reachable(MixedBitSet::new_empty(self.move_data().move_paths.len()));
374 drop_flag_effects_for_function_entry(self.body, self.move_data, |path, s| {
375 if !(s == DropFlagState::Present) {
::core::panicking::panic("assertion failed: s == DropFlagState::Present")
};assert!(s == DropFlagState::Present);
376 state.gen_(path);
377 });
378 }
379
380 fn apply_primary_statement_effect(
381 &self,
382 state: &mut Self::Domain,
383 statement: &mir::Statement<'tcx>,
384 location: Location,
385 ) {
386 drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
387 Self::update_bits(state, path, s)
388 });
389
390 if self.tcx.sess.opts.unstable_opts.precise_enum_drop_elaboration
392 && let Some((_, rvalue)) = statement.kind.as_assign()
393 && let mir::Rvalue::Ref(_, mir::BorrowKind::Mut { .. }, place)
394 | mir::Rvalue::RawPtr(_, place) = rvalue
396 && let LookupResult::Exact(mpi) = self.move_data().rev_lookup.find(place.as_ref())
397 {
398 on_all_children_bits(self.move_data(), mpi, |child| {
399 state.gen_(child);
400 })
401 }
402 }
403
404 fn apply_primary_terminator_effect<'mir>(
405 &self,
406 state: &mut Self::Domain,
407 terminator: &'mir mir::Terminator<'tcx>,
408 location: Location,
409 ) -> TerminatorEdges<'mir, 'tcx> {
410 let mut edges = terminator.edges();
413 if self.skip_unreachable_unwind
414 && let mir::TerminatorKind::Drop {
415 target,
416 unwind,
417 place,
418 replace: _,
419 drop: _,
420 async_fut: _,
421 } = terminator.kind
422 && #[allow(non_exhaustive_omitted_patterns)] match unwind {
mir::UnwindAction::Cleanup(_) => true,
_ => false,
}matches!(unwind, mir::UnwindAction::Cleanup(_))
423 && self.is_unwind_dead(place, state)
424 {
425 edges = TerminatorEdges::Single(target);
426 }
427 drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
428 Self::update_bits(state, path, s)
429 });
430 edges
431 }
432
433 fn apply_call_return_effect(
434 &self,
435 state: &mut Self::Domain,
436 _block: mir::BasicBlock,
437 return_places: CallReturnPlaces<'_, 'tcx>,
438 ) {
439 return_places.for_each(|place| {
440 on_lookup_result_bits(
443 self.move_data(),
444 self.move_data().rev_lookup.find(place.as_ref()),
445 |mpi| {
446 state.gen_(mpi);
447 },
448 );
449 });
450 }
451
452 fn get_switch_int_data(
453 &self,
454 block: mir::BasicBlock,
455 discr: &mir::Operand<'tcx>,
456 ) -> Option<Self::SwitchIntData> {
457 if !self.tcx.sess.opts.unstable_opts.precise_enum_drop_elaboration {
458 return None;
459 }
460
461 MaybePlacesSwitchIntData::new(self.tcx, self.body, block, discr)
462 }
463
464 fn apply_switch_int_edge_effect(
465 &self,
466 data: &mut Self::SwitchIntData,
467 state: &mut Self::Domain,
468 value: SwitchTargetValue,
469 targets: &mir::SwitchTargets,
470 ) {
471 let inactive_variants = match value {
472 SwitchTargetValue::Normal(value) => InactiveVariants::Active(data.next_discr(value)),
473 SwitchTargetValue::Otherwise if self.exclude_inactive_in_otherwise => {
474 InactiveVariants::Inactives(data.variants(targets))
475 }
476 _ => return,
477 };
478
479 drop_flag_effects::on_all_inactive_variants(
482 self.move_data,
483 data.enum_place,
484 &inactive_variants,
485 |mpi| state.kill(mpi),
486 );
487 }
488}
489
490pub type MaybeUninitializedPlacesDomain = MixedBitSet<MovePathIndex>;
493
494impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
495 type Domain = MaybeUninitializedPlacesDomain;
496
497 type SwitchIntData = MaybePlacesSwitchIntData<'tcx>;
498
499 const NAME: &'static str = "maybe_uninit";
500
501 fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
502 MixedBitSet::new_empty(self.move_data().move_paths.len())
504 }
505
506 fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) {
508 state.insert_all();
510
511 drop_flag_effects_for_function_entry(self.body, self.move_data, |path, s| {
512 if !(s == DropFlagState::Present) {
::core::panicking::panic("assertion failed: s == DropFlagState::Present")
};assert!(s == DropFlagState::Present);
513 state.remove(path);
514 });
515 }
516
517 fn apply_primary_statement_effect(
518 &self,
519 state: &mut Self::Domain,
520 _statement: &mir::Statement<'tcx>,
521 location: Location,
522 ) {
523 drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
524 Self::update_bits(state, path, s)
525 });
526
527 }
530
531 fn apply_primary_terminator_effect<'mir>(
532 &self,
533 state: &mut Self::Domain,
534 terminator: &'mir mir::Terminator<'tcx>,
535 location: Location,
536 ) -> TerminatorEdges<'mir, 'tcx> {
537 drop_flag_effects_for_location(self.body, self.move_data, location, |path, s| {
538 Self::update_bits(state, path, s)
539 });
540 if self.skip_unreachable_unwind.contains(location.block) {
541 let mir::TerminatorKind::Drop { target, unwind, .. } = terminator.kind else { ::rustc_middle::util::bug::bug_fmt(format_args!("impossible case reached"))bug!() };
542 match unwind {
mir::UnwindAction::Cleanup(_) => {}
ref left_val => {
::core::panicking::assert_matches_failed(left_val,
"mir::UnwindAction::Cleanup(_)", ::core::option::Option::None);
}
};assert_matches!(unwind, mir::UnwindAction::Cleanup(_));
543 TerminatorEdges::Single(target)
544 } else {
545 terminator.edges()
546 }
547 }
548
549 fn apply_call_return_effect(
550 &self,
551 state: &mut Self::Domain,
552 _block: mir::BasicBlock,
553 return_places: CallReturnPlaces<'_, 'tcx>,
554 ) {
555 return_places.for_each(|place| {
556 on_lookup_result_bits(
559 self.move_data(),
560 self.move_data().rev_lookup.find(place.as_ref()),
561 |mpi| {
562 state.kill(mpi);
563 },
564 );
565 });
566 }
567
568 fn get_switch_int_data(
569 &self,
570 block: mir::BasicBlock,
571 discr: &mir::Operand<'tcx>,
572 ) -> Option<Self::SwitchIntData> {
573 if !self.tcx.sess.opts.unstable_opts.precise_enum_drop_elaboration {
574 return None;
575 }
576
577 if !self.mark_inactive_variants_as_uninit {
578 return None;
579 }
580
581 MaybePlacesSwitchIntData::new(self.tcx, self.body, block, discr)
582 }
583
584 fn apply_switch_int_edge_effect(
585 &self,
586 data: &mut Self::SwitchIntData,
587 state: &mut Self::Domain,
588 value: SwitchTargetValue,
589 targets: &mir::SwitchTargets,
590 ) {
591 let inactive_variants = match value {
592 SwitchTargetValue::Normal(value) => InactiveVariants::Active(data.next_discr(value)),
593 SwitchTargetValue::Otherwise if self.include_inactive_in_otherwise => {
594 InactiveVariants::Inactives(data.variants(targets))
595 }
596 _ => return,
597 };
598
599 drop_flag_effects::on_all_inactive_variants(
602 self.move_data,
603 data.enum_place,
604 &inactive_variants,
605 |mpi| state.gen_(mpi),
606 );
607 }
608}
609
610pub type EverInitializedPlacesDomain = MixedBitSet<InitIndex>;
613
614impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
615 type Domain = EverInitializedPlacesDomain;
616
617 const NAME: &'static str = "ever_init";
618
619 fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
620 MixedBitSet::new_empty(self.move_data().inits.len())
622 }
623
624 fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain) {
625 for arg_init in 0..body.arg_count {
626 state.insert(InitIndex::new(arg_init));
627 }
628 }
629
630 #[allow(clippy :: suspicious_else_formatting)]
{
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("apply_primary_statement_effect",
"rustc_mir_dataflow::impls::initialized",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_dataflow/src/impls/initialized.rs"),
::tracing_core::__macro_support::Option::Some(630u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::impls::initialized"),
::tracing_core::field::FieldSet::new(&["stmt", "location"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&stmt)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[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: () = loop {};
return __tracing_attr_fake_return;
}
{
let move_data = self.move_data();
let init_path_map = &move_data.init_path_map;
let init_loc_map = &move_data.init_loc_map;
let rev_lookup = &move_data.rev_lookup;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_dataflow/src/impls/initialized.rs:642",
"rustc_mir_dataflow::impls::initialized",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_dataflow/src/impls/initialized.rs"),
::tracing_core::__macro_support::Option::Some(642u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::impls::initialized"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("initializes move_indexes {0:?}",
init_loc_map[location]) as &dyn Value))])
});
} else { ; }
};
state.gen_all(init_loc_map[location].iter().copied());
if let mir::StatementKind::StorageDead(local) = stmt.kind &&
let Some(move_path_index) = rev_lookup.find_local(local) {
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_dataflow/src/impls/initialized.rs:650",
"rustc_mir_dataflow::impls::initialized",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_dataflow/src/impls/initialized.rs"),
::tracing_core::__macro_support::Option::Some(650u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::impls::initialized"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("clears the ever initialized status of {0:?}",
init_path_map[move_path_index]) as &dyn Value))])
});
} else { ; }
};
state.kill_all(init_path_map[move_path_index].iter().copied());
}
}
}
}#[instrument(skip(self, state), level = "debug")]
631 fn apply_primary_statement_effect(
632 &self,
633 state: &mut Self::Domain,
634 stmt: &mir::Statement<'tcx>,
635 location: Location,
636 ) {
637 let move_data = self.move_data();
638 let init_path_map = &move_data.init_path_map;
639 let init_loc_map = &move_data.init_loc_map;
640 let rev_lookup = &move_data.rev_lookup;
641
642 debug!("initializes move_indexes {:?}", init_loc_map[location]);
643 state.gen_all(init_loc_map[location].iter().copied());
644
645 if let mir::StatementKind::StorageDead(local) = stmt.kind
646 && let Some(move_path_index) = rev_lookup.find_local(local)
649 {
650 debug!("clears the ever initialized status of {:?}", init_path_map[move_path_index]);
651 state.kill_all(init_path_map[move_path_index].iter().copied());
652 }
653 }
654
655 #[allow(clippy :: suspicious_else_formatting)]
{
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("apply_primary_terminator_effect",
"rustc_mir_dataflow::impls::initialized",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_dataflow/src/impls/initialized.rs"),
::tracing_core::__macro_support::Option::Some(655u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::impls::initialized"),
::tracing_core::field::FieldSet::new(&["location"],
::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};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&location)
as &dyn Value))])
})
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[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: TerminatorEdges<'mir, 'tcx> =
loop {};
return __tracing_attr_fake_return;
}
{
let (body, move_data) = (self.body, self.move_data());
let term = body[location.block].terminator();
let init_loc_map = &move_data.init_loc_map;
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_dataflow/src/impls/initialized.rs:665",
"rustc_mir_dataflow::impls::initialized",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_dataflow/src/impls/initialized.rs"),
::tracing_core::__macro_support::Option::Some(665u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::impls::initialized"),
::tracing_core::field::FieldSet::new(&["term"],
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&debug(&term) as
&dyn Value))])
});
} else { ; }
};
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_mir_dataflow/src/impls/initialized.rs:666",
"rustc_mir_dataflow::impls::initialized",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_mir_dataflow/src/impls/initialized.rs"),
::tracing_core::__macro_support::Option::Some(666u32),
::tracing_core::__macro_support::Option::Some("rustc_mir_dataflow::impls::initialized"),
::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};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("initializes move_indexes {0:?}",
init_loc_map[location]) as &dyn Value))])
});
} else { ; }
};
state.gen_all(init_loc_map[location].iter().filter(|init_index|
{
move_data.inits[**init_index].kind !=
InitKind::NonPanicPathOnly
}).copied());
terminator.edges()
}
}
}#[instrument(skip(self, state, terminator), level = "debug")]
656 fn apply_primary_terminator_effect<'mir>(
657 &self,
658 state: &mut Self::Domain,
659 terminator: &'mir mir::Terminator<'tcx>,
660 location: Location,
661 ) -> TerminatorEdges<'mir, 'tcx> {
662 let (body, move_data) = (self.body, self.move_data());
663 let term = body[location.block].terminator();
664 let init_loc_map = &move_data.init_loc_map;
665 debug!(?term);
666 debug!("initializes move_indexes {:?}", init_loc_map[location]);
667 state.gen_all(
668 init_loc_map[location]
669 .iter()
670 .filter(|init_index| {
671 move_data.inits[**init_index].kind != InitKind::NonPanicPathOnly
672 })
673 .copied(),
674 );
675 terminator.edges()
676 }
677
678 fn apply_call_return_effect(
679 &self,
680 state: &mut Self::Domain,
681 block: mir::BasicBlock,
682 _return_places: CallReturnPlaces<'_, 'tcx>,
683 ) {
684 let move_data = self.move_data();
685 let init_loc_map = &move_data.init_loc_map;
686
687 let call_loc = self.body.terminator_loc(block);
688 for init_index in &init_loc_map[call_loc] {
689 state.gen_(*init_index);
690 }
691 }
692}