diff options
Diffstat (limited to 'compiler/rustc_mir_dataflow/src/drop_flag_effects.rs')
-rw-r--r-- | compiler/rustc_mir_dataflow/src/drop_flag_effects.rs | 97 |
1 files changed, 46 insertions, 51 deletions
diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs index f102872cd..3224e13f7 100644 --- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs +++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs @@ -29,56 +29,6 @@ where None } -/// When enumerating the child fragments of a path, don't recurse into -/// paths (1.) past arrays, slices, and pointers, nor (2.) into a type -/// that implements `Drop`. -/// -/// Places behind references or arrays are not tracked by elaboration -/// and are always assumed to be initialized when accessible. As -/// references and indexes can be reseated, trying to track them can -/// only lead to trouble. -/// -/// Places behind ADT's with a Drop impl are not tracked by -/// elaboration since they can never have a drop-flag state that -/// differs from that of the parent with the Drop impl. -/// -/// In both cases, the contents can only be accessed if and only if -/// their parents are initialized. This implies for example that there -/// is no need to maintain separate drop flags to track such state. -// -// FIXME: we have to do something for moving slice patterns. -fn place_contents_drop_state_cannot_differ<'tcx>( - tcx: TyCtxt<'tcx>, - body: &Body<'tcx>, - place: mir::Place<'tcx>, -) -> bool { - let ty = place.ty(body, tcx).ty; - match ty.kind() { - ty::Array(..) => { - debug!( - "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false", - place, ty - ); - false - } - ty::Slice(..) | ty::Ref(..) | ty::RawPtr(..) => { - debug!( - "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} refd => true", - place, ty - ); - true - } - ty::Adt(def, _) if (def.has_dtor(tcx) && !def.is_box()) || def.is_union() => { - debug!( - "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} Drop => true", - place, ty - ); - true - } - _ => false, - } -} - pub fn on_lookup_result_bits<'tcx, F>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, @@ -105,13 +55,58 @@ pub fn on_all_children_bits<'tcx, F>( ) where F: FnMut(MovePathIndex), { + #[inline] fn is_terminal_path<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, move_data: &MoveData<'tcx>, path: MovePathIndex, ) -> bool { - place_contents_drop_state_cannot_differ(tcx, body, move_data.move_paths[path].place) + let place = move_data.move_paths[path].place; + + // When enumerating the child fragments of a path, don't recurse into + // paths (1.) past arrays, slices, and pointers, nor (2.) into a type + // that implements `Drop`. + // + // Places behind references or arrays are not tracked by elaboration + // and are always assumed to be initialized when accessible. As + // references and indexes can be reseated, trying to track them can + // only lead to trouble. + // + // Places behind ADT's with a Drop impl are not tracked by + // elaboration since they can never have a drop-flag state that + // differs from that of the parent with the Drop impl. + // + // In both cases, the contents can only be accessed if and only if + // their parents are initialized. This implies for example that there + // is no need to maintain separate drop flags to track such state. + // + // FIXME: we have to do something for moving slice patterns. + let ty = place.ty(body, tcx).ty; + match ty.kind() { + ty::Adt(def, _) if (def.has_dtor(tcx) && !def.is_box()) || def.is_union() => { + debug!( + "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} Drop => true", + place, ty + ); + true + } + ty::Array(..) => { + debug!( + "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} => false", + place, ty + ); + false + } + ty::Slice(..) | ty::Ref(..) | ty::RawPtr(..) => { + debug!( + "place_contents_drop_state_cannot_differ place: {:?} ty: {:?} refd => true", + place, ty + ); + true + } + _ => false, + } } fn on_all_children_bits<'tcx, F>( |