diff --git a/compiler/rustc_borrowck/src/invalidation.rs b/compiler/rustc_borrowck/src/invalidation.rs index 0425c53d9dc3c..8317206c69adb 100644 --- a/compiler/rustc_borrowck/src/invalidation.rs +++ b/compiler/rustc_borrowck/src/invalidation.rs @@ -289,6 +289,10 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> { | Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => { self.consume_operand(location, operand) } + Rvalue::VirtualRef(ref place) => { + let op = &Operand::Copy(*place); + self.consume_operand(location, op); + } Rvalue::Len(place) | Rvalue::Discriminant(place) => { let af = match *rvalue { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8ef2974c37232..9d8c5fe6d41d2 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1224,6 +1224,23 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { | Rvalue::ShallowInitBox(ref operand, _ /*ty*/) => { self.consume_operand(location, (operand, span), flow_state) } + Rvalue::VirtualRef(place) => { + self.access_place( + location, + (place, span), + (Deep, Read(ReadKind::Copy)), + LocalMutationIsAllowed::No, + flow_state, + ); + + // Finally, check if path was already moved. + self.check_if_path_or_subpath_is_moved( + location, + InitializationRequiringAction::Use, + (place.as_ref(), span), + flow_state, + ); + } Rvalue::Len(place) | Rvalue::Discriminant(place) => { let af = match *rvalue { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 355254fe9429b..ed72f17740d3c 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -2278,6 +2278,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Rvalue::Use(operand) | Rvalue::UnaryOp(_, operand) => { self.check_operand(operand, location); } + Rvalue::VirtualRef(place) => { + let op = &Operand::Copy(*place); + self.check_operand(op, location); + } Rvalue::BinaryOp(_, box (left, right)) | Rvalue::CheckedBinaryOp(_, box (left, right)) => { @@ -2308,6 +2312,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { | Rvalue::BinaryOp(..) | Rvalue::CheckedBinaryOp(..) | Rvalue::NullaryOp(..) + | Rvalue::VirtualRef(..) | Rvalue::UnaryOp(..) | Rvalue::Discriminant(..) => None, diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index fbe830b2b1030..9f40b5264576c 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -503,6 +503,11 @@ fn codegen_stmt<'tcx>( let val = codegen_operand(fx, operand); lval.write_cvalue(fx, val); } + Rvalue::VirtualRef(place) => { + let cplace = codegen_place(fx, place); + let val = cplace.to_cvalue(fx); + lval.write_cvalue(fx, val) + } Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => { let place = codegen_place(fx, place); let ref_ = place.place_ref(fx, lval.layout()); diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 81c1897694ce6..30fc4db6e89bf 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -8,6 +8,7 @@ use crate::traits::*; use crate::MemFlags; use rustc_middle::mir; +use rustc_middle::mir::Operand; use rustc_middle::ty::cast::{CastTy, IntTy}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; @@ -401,6 +402,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.codegen_place_to_pointer(bx, place, mk_ref) } + mir::Rvalue::VirtualRef(place) => { + let operand = self.codegen_operand(&mut bx, &Operand::Copy(place)); + (bx, operand) + } mir::Rvalue::AddressOf(mutability, place) => { let mk_ptr = move |tcx: TyCtxt<'tcx>, ty: Ty<'tcx>| { tcx.mk_ptr(ty::TypeAndMut { ty, mutbl: mutability }) @@ -755,6 +760,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool { match *rvalue { mir::Rvalue::Ref(..) | + mir::Rvalue::VirtualRef(..) | mir::Rvalue::AddressOf(..) | mir::Rvalue::Len(..) | mir::Rvalue::Cast(..) | // (*) diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 98f69456e49aa..06a2f40daef4f 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -172,6 +172,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.copy_op(&op, &dest)?; } + VirtualRef(ref place) => { + let op = self.eval_place_to_op(*place, Some(dest.layout))?; + self.copy_op(&op, &dest)?; + } + BinaryOp(bin_op, box (ref left, ref right)) => { let layout = binop_left_homogeneous(bin_op).then_some(dest.layout); let left = self.read_immediate(&self.eval_operand(left, layout)?)?; diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 069fbed36ee3a..d216cde9d2886 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -445,6 +445,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { Rvalue::ThreadLocalRef(_) => self.check_op(ops::ThreadLocalAccess), Rvalue::Use(_) + | Rvalue::VirtualRef(..) | Rvalue::Repeat(..) | Rvalue::Discriminant(..) | Rvalue::Len(_) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs index 6e5a0c813ac20..84eddbb355cfa 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs @@ -260,6 +260,8 @@ where in_place::(cx, in_local, place.as_ref()) } + Rvalue::VirtualRef(place) => in_place::(cx, in_local, place.as_ref()), + Rvalue::Use(operand) | Rvalue::Repeat(operand, _) | Rvalue::UnaryOp(_, operand) diff --git a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs index fd7febc17a3a7..e6c9f57e0d8c8 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/resolver.rs @@ -199,6 +199,7 @@ where mir::Rvalue::Cast(..) | mir::Rvalue::ShallowInitBox(..) | mir::Rvalue::Use(..) + | mir::Rvalue::VirtualRef(..) | mir::Rvalue::ThreadLocalRef(..) | mir::Rvalue::Repeat(..) | mir::Rvalue::Len(..) diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 3595a488d0c5b..2b4bdf5b5f28a 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -494,6 +494,10 @@ impl<'tcx> Validator<'_, 'tcx> { Rvalue::Use(operand) | Rvalue::Repeat(operand, _) => { self.validate_operand(operand)?; } + Rvalue::VirtualRef(place) => { + let op = &Operand::Copy(*place); + self.validate_operand(op)? + } Rvalue::Discriminant(place) | Rvalue::Len(place) => { self.validate_place(place.as_ref())? diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 3f5b16d5ea5f7..6684745c8cfa2 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -159,6 +159,8 @@ pub enum MirPhase { /// of the `mir_promoted` query), these promoted elements are available in the `promoted_mir` /// query. ConstsPromoted = 2, + /// After this projections may only contain deref projections as the first element. + Derefered = 3, /// Beginning with this phase, the following variants are disallowed: /// * [`TerminatorKind::DropAndReplace`](terminator::TerminatorKind::DropAndReplace) /// * [`TerminatorKind::FalseUnwind`](terminator::TerminatorKind::FalseUnwind) @@ -173,9 +175,7 @@ pub enum MirPhase { /// Furthermore, `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop` /// terminator means that the auto-generated drop glue will be invoked. Also, `Copy` operands /// are allowed for non-`Copy` types. - DropsLowered = 3, - /// After this projections may only contain deref projections as the first element. - Derefered = 4, + DropsLowered = 4, /// Beginning with this phase, the following variant is disallowed: /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array` /// @@ -1174,6 +1174,15 @@ impl<'tcx> LocalDecl<'tcx> { } } + /// Returns `true` if this is a DerefTemp + pub fn is_deref_temp(&self) -> bool { + match self.local_info { + Some(box LocalInfo::DerefTemp) => return true, + _ => (), + } + return false; + } + /// Returns `true` is the local is from a compiler desugaring, e.g., /// `__next` from a `for` loop. #[inline] @@ -2616,6 +2625,15 @@ pub enum Rvalue<'tcx> { /// initialized but its content as uninitialized. Like other pointer casts, this in general /// affects alias analysis. ShallowInitBox(Operand<'tcx>, Ty<'tcx>), + + /// A virtual ref is equivalent to a read from a reference/pointer at the + /// codegen level, but is treated specially by drop elaboration. When such a read happens, it + /// is guaranteed that the only use of the returned value is a deref operation, immediately + /// followed by one or more projections. Drop elaboration treats this virtual ref as if the + /// read never happened and just projects further. This allows simplifying various MIR + /// optimizations and codegen backends that previously had to handle deref operations anywhere + /// in a place. + VirtualRef(Place<'tcx>), } #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] @@ -2632,6 +2650,7 @@ impl<'tcx> Rvalue<'tcx> { Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false, Rvalue::Use(_) + | Rvalue::VirtualRef(_) | Rvalue::Repeat(_, _) | Rvalue::Ref(_, _, _) | Rvalue::ThreadLocalRef(_) @@ -2809,6 +2828,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { }; write!(fmt, "&{}{}{:?}", region, kind_str, place) } + VirtualRef(ref place) => write!(fmt, "virt {:#?}", place), AddressOf(mutability, ref place) => { let kind_str = match mutability { diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index c93b7a9550229..8ec04e61a2e0b 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -211,6 +211,7 @@ impl<'tcx> Rvalue<'tcx> { } }, Rvalue::ShallowInitBox(_, ty) => tcx.mk_box(ty), + Rvalue::VirtualRef(ref place) => place.ty(local_decls, tcx).ty, } } diff --git a/compiler/rustc_middle/src/mir/type_foldable.rs b/compiler/rustc_middle/src/mir/type_foldable.rs index 4201b2d11ce2a..f20c0101d9fd5 100644 --- a/compiler/rustc_middle/src/mir/type_foldable.rs +++ b/compiler/rustc_middle/src/mir/type_foldable.rs @@ -184,6 +184,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { Ref(region, bk, place) => { Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?) } + VirtualRef(place) => VirtualRef(place.try_fold_with(folder)?), AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?), Len(place) => Len(place.try_fold_with(folder)?), Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?), @@ -235,6 +236,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { region.visit_with(visitor)?; place.visit_with(visitor) } + VirtualRef(ref place) => place.visit_with(visitor), AddressOf(_, ref place) => place.visit_with(visitor), Len(ref place) => place.visit_with(visitor), Cast(_, ref op, ty) => { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 5ce92d127f3db..9aea4ae61d44a 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -670,6 +670,13 @@ macro_rules! make_mir_visitor { }; self.visit_place(path, ctx, location); } + Rvalue::VirtualRef(place) => { + self.visit_place( + place, + PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect), + location + ); + } Rvalue::AddressOf(m, path) => { let ctx = match m { diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index 627fe3f7f576b..4681f942f92ff 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -102,7 +102,8 @@ where | mir::Rvalue::NullaryOp(..) | mir::Rvalue::UnaryOp(..) | mir::Rvalue::Discriminant(..) - | mir::Rvalue::Aggregate(..) => {} + | mir::Rvalue::Aggregate(..) + | mir::Rvalue::VirtualRef(..) => {} } } diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index e4c130f0807dd..5793a286bd03d 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -38,6 +38,7 @@ pub mod impls; pub mod move_paths; pub mod rustc_peek; pub mod storage; +pub mod un_derefer; pub(crate) mod indexes { pub(crate) use super::move_paths::MovePathIndex; diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs index b08cb50f77aed..75b0a68e65802 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs @@ -1,3 +1,4 @@ +use crate::un_derefer::UnDerefer; use rustc_index::vec::IndexVec; use rustc_middle::mir::tcx::RvalueInitializationState; use rustc_middle::mir::*; @@ -19,6 +20,7 @@ struct MoveDataBuilder<'a, 'tcx> { param_env: ty::ParamEnv<'tcx>, data: MoveData<'tcx>, errors: Vec<(Place<'tcx>, MoveError<'tcx>)>, + un_derefer: UnDerefer<'tcx>, } impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { @@ -32,6 +34,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> { tcx, param_env, errors: Vec::new(), + un_derefer: UnDerefer { tcx: tcx, derefer_sidetable: Default::default() }, data: MoveData { moves: IndexVec::new(), loc_map: LocationMap::new(body), @@ -94,6 +97,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { /// /// Maybe we should have separate "borrowck" and "moveck" modes. fn move_path_for(&mut self, place: Place<'tcx>) -> Result> { + if let Some(new_place) = self.builder.un_derefer.derefer(place.as_ref()) { + return self.move_path_for(new_place); + } + debug!("lookup({:?})", place); let mut base = self.builder.data.rev_lookup.locals[place.local]; @@ -224,6 +231,8 @@ pub(super) fn gather_moves<'tcx>( param_env: ty::ParamEnv<'tcx>, ) -> Result, (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>)> { let mut builder = MoveDataBuilder::new(body, tcx, param_env); + let mut un_derefer = UnDerefer { tcx: tcx, derefer_sidetable: Default::default() }; + un_derefer.ref_finder(body); builder.gather_args(); @@ -276,6 +285,10 @@ struct Gatherer<'b, 'a, 'tcx> { impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { fn gather_statement(&mut self, stmt: &Statement<'tcx>) { match &stmt.kind { + StatementKind::Assign(box (place, Rvalue::VirtualRef(reffed))) => { + assert!(place.projection.is_empty()); + self.builder.un_derefer.derefer_sidetable.insert(place.local, *reffed); + } StatementKind::Assign(box (place, rval)) => { self.create_move_path(*place); if let RvalueInitializationState::Shallow = rval.initialization_state() { @@ -294,7 +307,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } StatementKind::StorageLive(_) => {} StatementKind::StorageDead(local) => { - self.gather_move(Place::from(*local)); + // DerefTemp locals (results of VirtualRef) don't actually move anything. + if !self.builder.un_derefer.derefer_sidetable.contains_key(&local) { + self.gather_move(Place::from(*local)); + } } StatementKind::SetDiscriminant { .. } | StatementKind::Deinit(..) => { span_bug!( @@ -328,6 +344,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { self.gather_operand(operand); } } + Rvalue::VirtualRef(..) => unreachable!(), Rvalue::Ref(..) | Rvalue::AddressOf(..) | Rvalue::Discriminant(..) @@ -439,6 +456,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { fn gather_move(&mut self, place: Place<'tcx>) { debug!("gather_move({:?}, {:?})", self.loc, place); + if let Some(new_place) = self.builder.un_derefer.derefer(place.as_ref()) { + self.gather_move(new_place); + return; + } if let [ref base @ .., ProjectionElem::Subslice { from, to, from_end: false }] = **place.projection @@ -494,6 +515,11 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) { debug!("gather_init({:?}, {:?})", self.loc, place); + if let Some(new_place) = self.builder.un_derefer.derefer(place) { + self.gather_init(new_place.as_ref(), kind); + return; + } + let mut place = place; // Check if we are assigning into a field of a union, if so, lookup the place diff --git a/compiler/rustc_mir_dataflow/src/un_derefer.rs b/compiler/rustc_mir_dataflow/src/un_derefer.rs new file mode 100644 index 0000000000000..4c45d385707b1 --- /dev/null +++ b/compiler/rustc_mir_dataflow/src/un_derefer.rs @@ -0,0 +1,31 @@ +use rustc_data_structures::stable_map::FxHashMap; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; + +/// Used for reverting changes made by `DerefSeparator` +pub struct UnDerefer<'tcx> { + pub tcx: TyCtxt<'tcx>, + pub derefer_sidetable: FxHashMap>, +} + +impl<'tcx> UnDerefer<'tcx> { + pub fn derefer(&self, place: PlaceRef<'tcx>) -> Option> { + let reffed = self.derefer_sidetable.get(&place.local)?; + + let new_place = reffed.project_deeper(place.projection, self.tcx); + Some(new_place) + } + + pub fn ref_finder(&mut self, body: &Body<'tcx>) { + for (_bb, data) in body.basic_blocks().iter_enumerated() { + for stmt in data.statements.iter() { + match stmt.kind { + StatementKind::Assign(box (place, Rvalue::VirtualRef(reffed))) => { + self.derefer_sidetable.insert(place.local, reffed); + } + _ => (), + } + } + } + } +} diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 0495439385bee..000abbee51e38 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -57,17 +57,6 @@ fn may_be_reference(ty: Ty<'_>) -> bool { } } -/// Determines whether or not this LocalDecl is temp, if not it needs retagging. -fn is_not_temp<'tcx>(local_decl: &LocalDecl<'tcx>) -> bool { - if let Some(local_info) = &local_decl.local_info { - match local_info.as_ref() { - LocalInfo::DerefTemp => return false, - _ => (), - }; - } - return true; -} - impl<'tcx> MirPass<'tcx> for AddRetag { fn is_enabled(&self, sess: &rustc_session::Session) -> bool { sess.opts.debugging_opts.mir_emit_retag @@ -84,7 +73,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag { // a temporary and retag on that. is_stable(place.as_ref()) && may_be_reference(place.ty(&*local_decls, tcx).ty) - && is_not_temp(&local_decls[place.local]) + && !local_decls[place.local].is_deref_temp() }; let place_base_raw = |place: &Place<'tcx>| { // If this is a `Deref`, get the type of what we are deref'ing. diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 412a5b4fc9104..8b17b70e196f8 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -616,6 +616,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // There's no other checking to do at this time. Rvalue::Aggregate(..) | Rvalue::Use(..) + | Rvalue::VirtualRef(..) | Rvalue::Repeat(..) | Rvalue::Len(..) | Rvalue::Cast(..) diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 15ad13009e59a..b29440f17e45f 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -683,6 +683,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // There's no other checking to do at this time. Rvalue::Aggregate(..) | Rvalue::Use(..) + | Rvalue::VirtualRef(..) | Rvalue::Repeat(..) | Rvalue::Len(..) | Rvalue::Cast(..) diff --git a/compiler/rustc_mir_transform/src/deref_separator.rs b/compiler/rustc_mir_transform/src/deref_separator.rs index bfb3ad1be2734..badb092fb25db 100644 --- a/compiler/rustc_mir_transform/src/deref_separator.rs +++ b/compiler/rustc_mir_transform/src/deref_separator.rs @@ -35,6 +35,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> { last_deref_idx = idx; } } + for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() { if !p_ref.projection.is_empty() && p_elem == ProjectionElem::Deref { let ty = p_ref.ty(&self.local_decls, self.tcx).ty; @@ -54,7 +55,7 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> { self.patcher.add_assign( loc, Place::from(temp), - Rvalue::Use(Operand::Move(deref_place)), + Rvalue::VirtualRef(deref_place), ); place_local = temp; last_len = p_ref.projection.len(); diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index e0e27c53f1822..d11f514ee1ae2 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -1,3 +1,4 @@ +use crate::deref_separator::deref_finder; use crate::MirPass; use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::BitSet; @@ -9,6 +10,7 @@ use rustc_mir_dataflow::elaborate_drops::{DropElaborator, DropFlagMode, DropStyl use rustc_mir_dataflow::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; use rustc_mir_dataflow::on_lookup_result_bits; +use rustc_mir_dataflow::un_derefer::UnDerefer; use rustc_mir_dataflow::MoveDataParamEnv; use rustc_mir_dataflow::{on_all_children_bits, on_all_drop_children_bits}; use rustc_mir_dataflow::{Analysis, ResultsCursor}; @@ -26,6 +28,8 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { debug!("elaborate_drops({:?} @ {:?})", body.source, body.span); + let mut un_derefer = UnDerefer { tcx: tcx, derefer_sidetable: Default::default() }; + un_derefer.ref_finder(body); let def_id = body.source.def_id(); let param_env = tcx.param_env_reveal_all_normalized(def_id); let move_data = match MoveData::gather_moves(body, tcx, param_env) { @@ -41,7 +45,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { let elaborate_patch = { let body = &*body; let env = MoveDataParamEnv { move_data, param_env }; - let dead_unwinds = find_dead_unwinds(tcx, body, &env); + let dead_unwinds = find_dead_unwinds(tcx, body, &env, &un_derefer); let inits = MaybeInitializedPlaces::new(tcx, body, &env) .into_engine(tcx, body) @@ -65,10 +69,12 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops { init_data: InitializationData { inits, uninits }, drop_flags: Default::default(), patch: MirPatch::new(body), + un_derefer: un_derefer, } .elaborate() }; elaborate_patch.apply(body); + deref_finder(tcx, body); } } @@ -79,6 +85,7 @@ fn find_dead_unwinds<'tcx>( tcx: TyCtxt<'tcx>, body: &Body<'tcx>, env: &MoveDataParamEnv<'tcx>, + und: &UnDerefer<'tcx>, ) -> BitSet { debug!("find_dead_unwinds({:?})", body.span); // We only need to do this pass once, because unwind edges can only @@ -92,7 +99,9 @@ fn find_dead_unwinds<'tcx>( for (bb, bb_data) in body.basic_blocks().iter_enumerated() { let place = match bb_data.terminator().kind { TerminatorKind::Drop { ref place, unwind: Some(_), .. } - | TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => place, + | TerminatorKind::DropAndReplace { ref place, unwind: Some(_), .. } => { + und.derefer(place.as_ref()).unwrap_or(*place) + } _ => continue, }; @@ -256,6 +265,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> { init_data: InitializationData<'a, 'tcx>, drop_flags: FxHashMap, patch: MirPatch<'tcx>, + un_derefer: UnDerefer<'tcx>, } impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { @@ -298,7 +308,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let terminator = data.terminator(); let place = match terminator.kind { TerminatorKind::Drop { ref place, .. } - | TerminatorKind::DropAndReplace { ref place, .. } => place, + | TerminatorKind::DropAndReplace { ref place, .. } => { + self.un_derefer.derefer(place.as_ref()).unwrap_or(*place) + } _ => continue, }; @@ -312,12 +324,17 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { LookupResult::Parent(None) => continue, LookupResult::Parent(Some(parent)) => { let (_maybe_live, maybe_dead) = self.init_data.maybe_live_dead(parent); + + if self.body.local_decls[place.local].is_deref_temp() { + continue; + } + if maybe_dead { self.tcx.sess.delay_span_bug( terminator.source_info.span, &format!( "drop of untracked, uninitialized value {:?}, place {:?} ({:?})", - bb, place, path, + bb, place, path ), ); } @@ -348,7 +365,11 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let resume_block = self.patch.resume_block(); match terminator.kind { - TerminatorKind::Drop { place, target, unwind } => { + TerminatorKind::Drop { mut place, target, unwind } => { + if let Some(new_place) = self.un_derefer.derefer(place.as_ref()) { + place = new_place; + } + self.init_data.seek_before(loc); match self.move_data().rev_lookup.find(place.as_ref()) { LookupResult::Exact(path) => elaborate_drop( @@ -372,9 +393,12 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { } } } - TerminatorKind::DropAndReplace { place, ref value, target, unwind } => { + TerminatorKind::DropAndReplace { mut place, ref value, target, unwind } => { assert!(!data.is_cleanup); + if let Some(new_place) = self.un_derefer.derefer(place.as_ref()) { + place = new_place; + } self.elaborate_replace(loc, place, value, target, unwind); } _ => continue, diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index b7caa61ef07a7..37014497c6887 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -415,6 +415,7 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc &remove_noop_landing_pads::RemoveNoopLandingPads, &cleanup_post_borrowck::CleanupNonCodegenStatements, &simplify::SimplifyCfg::new("early-opt"), + &deref_separator::Derefer, // These next passes must be executed together &add_call_guards::CriticalCallEdges, &elaborate_drops::ElaborateDrops, @@ -427,7 +428,6 @@ fn run_post_borrowck_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tc &add_moves_for_packed_drops::AddMovesForPackedDrops, // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late, // but before optimizations begin. - &deref_separator::Derefer, &elaborate_box_derefs::ElaborateBoxDerefs, &add_retag::AddRetag, &lower_intrinsics::LowerIntrinsics, diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index 33ea1c4ba2f59..ec4bff30f95cd 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -218,6 +218,7 @@ fn is_likely_const<'tcx>(mut tracked_place: Place<'tcx>, block: &BasicBlockData< // These rvalues move the place to track Rvalue::Cast(_, Operand::Copy(place) | Operand::Move(place), _) | Rvalue::Use(Operand::Copy(place) | Operand::Move(place)) + | Rvalue::VirtualRef(place) | Rvalue::UnaryOp(_, Operand::Copy(place) | Operand::Move(place)) | Rvalue::Discriminant(place) => tracked_place = place, } @@ -279,6 +280,7 @@ fn find_determining_place<'tcx>( // that may be const in the predecessor Rvalue::Use(Operand::Move(new) | Operand::Copy(new)) | Rvalue::UnaryOp(_, Operand::Copy(new) | Operand::Move(new)) + | Rvalue::VirtualRef(new) | Rvalue::Cast(_, Operand::Move(new) | Operand::Copy(new), _) | Rvalue::Repeat(Operand::Move(new) | Operand::Copy(new), _) | Rvalue::Discriminant(new) diff --git a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff index f5eabf8696796..75b301016d76e 100644 --- a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff +++ b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff @@ -69,7 +69,7 @@ StorageLive(_12); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 - _12 = (*((_7 as Some).0: &i32)); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 + StorageLive(_15); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 -+ _15 = move ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 ++ _15 = virt ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 + _12 = (*_15); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 + StorageDead(_15); // scope 2 at $DIR/derefer_complex_case.rs:4:34: 4:37 StorageLive(_13); // scope 2 at $DIR/derefer_complex_case.rs:4:34: 4:37 @@ -102,10 +102,10 @@ StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40 _5 = const (); // scope 1 at $DIR/derefer_complex_case.rs:4:5: 4:40 goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:4:5: 4:40 - } - - bb8 (cleanup): { - resume; // scope 0 at $DIR/derefer_complex_case.rs:3:1: 5:2 ++ } ++ ++ bb8 (cleanup): { ++ resume; // scope 0 at $DIR/derefer_complex_case.rs:3:1: 5:2 } } diff --git a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff index e131adae2b683..b9bf710d3fdf3 100644 --- a/src/test/mir-opt/derefer_inline_test.main.Derefer.diff +++ b/src/test/mir-opt/derefer_inline_test.main.Derefer.diff @@ -8,7 +8,6 @@ let mut _3: usize; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12 let mut _4: *mut u8; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12 let mut _5: std::boxed::Box>; // in scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12 - let mut _6: (); // in scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12 scope 1 { } @@ -25,7 +24,7 @@ bb1: { StorageLive(_5); // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12 _5 = ShallowInitBox(move _4, std::boxed::Box); // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12 - (*_5) = f() -> [return: bb2, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:10:9: 10:12 + (*_5) = f() -> [return: bb2, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:10:9: 10:12 // mir::Constant // + span: $DIR/derefer_inline_test.rs:10:9: 10:10 // + literal: Const { ty: fn() -> Box {f}, val: Value(Scalar()) } @@ -33,12 +32,12 @@ bb2: { _1 = move _5; // scope 0 at $DIR/derefer_inline_test.rs:10:5: 10:12 - goto -> bb3; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12 + drop(_5) -> [return: bb3, unwind: bb5]; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12 } bb3: { StorageDead(_5); // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12 - drop(_1) -> [return: bb4, unwind: bb6]; // scope 0 at $DIR/derefer_inline_test.rs:10:12: 10:13 + drop(_1) -> bb4; // scope 0 at $DIR/derefer_inline_test.rs:10:12: 10:13 } bb4: { @@ -48,22 +47,15 @@ } bb5 (cleanup): { - goto -> bb8; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12 + drop(_1) -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:10:12: 10:13 } bb6 (cleanup): { - resume; // scope 0 at $DIR/derefer_inline_test.rs:9:1: 11:2 + drop(_5) -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12 } bb7 (cleanup): { - _6 = alloc::alloc::box_free::, std::alloc::Global>(move (_5.0: std::ptr::Unique>), move (_5.1: std::alloc::Global)) -> bb6; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12 - // mir::Constant - // + span: $DIR/derefer_inline_test.rs:10:11: 10:12 - // + literal: Const { ty: unsafe fn(Unique>, std::alloc::Global) {alloc::alloc::box_free::, std::alloc::Global>}, val: Value(Scalar()) } - } - - bb8 (cleanup): { - goto -> bb7; // scope 0 at $DIR/derefer_inline_test.rs:10:11: 10:12 + resume; // scope 0 at $DIR/derefer_inline_test.rs:9:1: 11:2 } } diff --git a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff index 8b91a65bf3d7d..cfa3eb3f2d78b 100644 --- a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff +++ b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff @@ -56,12 +56,12 @@ _4 = &_5; // scope 2 at $DIR/derefer_terminator_test.rs:5:15: 5:22 - switchInt((*(*(*(*_4))))) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + StorageLive(_10); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 -+ _10 = move (*_4); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ _10 = virt (*_4); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + StorageLive(_11); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 -+ _11 = move (*_10); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ _11 = virt (*_10); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + StorageDead(_10); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + StorageLive(_12); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 -+ _12 = move (*_11); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ _12 = virt (*_11); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + StorageDead(_11); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + switchInt((*_12)) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 } @@ -94,10 +94,10 @@ StorageDead(_2); // scope 1 at $DIR/derefer_terminator_test.rs:10:1: 10:2 StorageDead(_1); // scope 0 at $DIR/derefer_terminator_test.rs:10:1: 10:2 return; // scope 0 at $DIR/derefer_terminator_test.rs:10:2: 10:2 - } - - bb6 (cleanup): { - resume; // scope 0 at $DIR/derefer_terminator_test.rs:2:1: 10:2 ++ } ++ ++ bb6 (cleanup): { ++ resume; // scope 0 at $DIR/derefer_terminator_test.rs:2:1: 10:2 } } diff --git a/src/test/mir-opt/derefer_test.main.Derefer.diff b/src/test/mir-opt/derefer_test.main.Derefer.diff index 84476aeed7a6c..589fc4210fc24 100644 --- a/src/test/mir-opt/derefer_test.main.Derefer.diff +++ b/src/test/mir-opt/derefer_test.main.Derefer.diff @@ -34,13 +34,13 @@ StorageLive(_4); // scope 2 at $DIR/derefer_test.rs:5:9: 5:10 - _4 = &mut ((*(_2.1: &mut (i32, i32))).0: i32); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 + StorageLive(_6); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 -+ _6 = move (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 ++ _6 = virt (_2.1: &mut (i32, i32)); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 + _4 = &mut ((*_6).0: i32); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 + StorageDead(_6); // scope 3 at $DIR/derefer_test.rs:6:9: 6:10 StorageLive(_5); // scope 3 at $DIR/derefer_test.rs:6:9: 6:10 - _5 = &mut ((*(_2.1: &mut (i32, i32))).1: i32); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 + StorageLive(_7); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 -+ _7 = move (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 ++ _7 = virt (_2.1: &mut (i32, i32)); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 + _5 = &mut ((*_7).1: i32); // scope 3 at $DIR/derefer_test.rs:6:13: 6:26 + StorageDead(_7); // scope 0 at $DIR/derefer_test.rs:2:11: 7:2 _0 = const (); // scope 0 at $DIR/derefer_test.rs:2:11: 7:2 @@ -49,10 +49,10 @@ StorageDead(_2); // scope 1 at $DIR/derefer_test.rs:7:1: 7:2 StorageDead(_1); // scope 0 at $DIR/derefer_test.rs:7:1: 7:2 return; // scope 0 at $DIR/derefer_test.rs:7:2: 7:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/derefer_test.rs:2:1: 7:2 ++ } ++ ++ bb1 (cleanup): { ++ resume; // scope 0 at $DIR/derefer_test.rs:2:1: 7:2 } } diff --git a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff index b8e5a0c328f4d..79734a45dc476 100644 --- a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff +++ b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff @@ -58,24 +58,24 @@ StorageLive(_8); // scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10 - _8 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + StorageLive(_10); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 -+ _10 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 ++ _10 = virt (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + StorageLive(_11); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 -+ _11 = move ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 ++ _11 = virt ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + StorageDead(_10); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + StorageLive(_12); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 -+ _12 = move ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 ++ _12 = virt ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + StorageDead(_11); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + _8 = &mut ((*_12).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + StorageDead(_12); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10 StorageLive(_9); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10 - _9 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + StorageLive(_13); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 -+ _13 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 ++ _13 = virt (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + StorageLive(_14); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 -+ _14 = move ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 ++ _14 = virt ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + StorageDead(_13); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + StorageLive(_15); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 -+ _15 = move ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 ++ _15 = virt ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + StorageDead(_14); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + _9 = &mut ((*_15).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + StorageDead(_15); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2 @@ -87,10 +87,10 @@ StorageDead(_2); // scope 1 at $DIR/derefer_test_multiple.rs:9:1: 9:2 StorageDead(_1); // scope 0 at $DIR/derefer_test_multiple.rs:9:1: 9:2 return; // scope 0 at $DIR/derefer_test_multiple.rs:9:2: 9:2 - } - - bb1 (cleanup): { - resume; // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2 ++ } ++ ++ bb1 (cleanup): { ++ resume; // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2 } } diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff index 67ce0c2aabb1c..9cbc5a4233e93 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff @@ -93,7 +93,7 @@ - StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _34 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _34 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -101,7 +101,7 @@ bb1: { StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _35 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _35 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -123,7 +123,7 @@ bb3: { StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _36 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _36 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -131,7 +131,7 @@ bb4: { StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _37 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _37 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -139,7 +139,7 @@ bb5: { StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _38 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _38 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -149,14 +149,14 @@ - StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 - _39 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + _39 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 - _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + _15 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 - StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 - _40 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + _40 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 - _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + _16 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 @@ -195,14 +195,14 @@ - StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - _41 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + _41 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + _20 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - _42 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + _42 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + _21 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 @@ -241,14 +241,14 @@ - StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 - _43 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + _43 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 - _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + _25 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 - StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 - _44 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + _44 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 - _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + _26 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 @@ -287,14 +287,14 @@ - StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - _45 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + _45 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + _30 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - _46 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + _46 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + _31 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff index c2b00f915a4eb..e52d2865179e5 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -79,7 +79,7 @@ StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _34 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _34 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -87,7 +87,7 @@ bb1: { StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _35 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _35 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -107,7 +107,7 @@ bb3: { StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _36 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _36 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -115,7 +115,7 @@ bb4: { StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _37 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _37 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -123,7 +123,7 @@ bb5: { StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 - _38 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _38 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 @@ -132,12 +132,12 @@ bb6: { StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 - _39 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + _39 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 - _40 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + _40 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 @@ -160,12 +160,12 @@ bb7: { StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - _41 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + _41 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - _42 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + _42 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 @@ -188,12 +188,12 @@ bb8: { StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 - _43 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + _43 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 - _44 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + _44 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 @@ -216,12 +216,12 @@ bb9: { StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - _45 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + _45 = virt (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - _46 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + _46 = virt (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff index 982dd7a27bc6b..e40ef981a4e8c 100644 --- a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff @@ -17,7 +17,7 @@ bb1: { StorageLive(_4); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 - _4 = move (((*_1) as Some).0: &E); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + _4 = virt (((*_1) as Some).0: &E); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 _2 = discriminant((*_4)); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 StorageDead(_4); // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir index c6b49b66dc5c0..80d8d3b1c7b96 100644 --- a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -46,12 +46,12 @@ fn foo(_1: T, _2: i32) -> (i32, T) { _9 = move (_7.0: i32); // scope 1 at $DIR/inline-closure-captures.rs:12:5: 12:9 StorageLive(_10); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 StorageLive(_12); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 - _12 = move ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 + _12 = virt ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 _10 = (*_12); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 StorageDead(_12); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 StorageLive(_11); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 StorageLive(_13); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 - _13 = move ((*_6).1: &T); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 + _13 = virt ((*_6).1: &T); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 _11 = (*_13); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 StorageDead(_13); // scope 2 at $DIR/inline-closure-captures.rs:11:18: 11:24 Deinit(_0); // scope 2 at $DIR/inline-closure-captures.rs:11:18: 11:24 diff --git a/src/test/mir-opt/inline/inline_generator.main.Inline.diff b/src/test/mir-opt/inline/inline_generator.main.Inline.diff index 3e1c4a4670143..51c2688da4709 100644 --- a/src/test/mir-opt/inline/inline_generator.main.Inline.diff +++ b/src/test/mir-opt/inline/inline_generator.main.Inline.diff @@ -77,7 +77,7 @@ + StorageLive(_11); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46 + StorageLive(_12); // scope 0 at $DIR/inline-generator.rs:9:14: 9:46 + StorageLive(_13); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 -+ _13 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 ++ _13 = virt (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + _12 = discriminant((*_13)); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + StorageDead(_13); // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 + switchInt(move _12) -> [0_u32: bb3, 1_u32: bb8, 3_u32: bb7, otherwise: bb9]; // scope 6 at $DIR/inline-generator.rs:15:5: 15:41 @@ -125,7 +125,7 @@ + ((_1 as Yielded).0: i32) = move _8; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + discriminant(_1) = 0; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + StorageLive(_14); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 -+ _14 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 ++ _14 = virt (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + discriminant((*_14)) = 3; // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + StorageDead(_14); // scope 6 at $DIR/inline-generator.rs:15:11: 15:39 + goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:11: 15:39 @@ -139,7 +139,7 @@ + ((_1 as Complete).0: bool) = move _10; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 + discriminant(_1) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 + StorageLive(_15); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 -+ _15 = move (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 ++ _15 = virt (_2.0: &mut [generator@$DIR/inline-generator.rs:15:5: 15:41]); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 + discriminant((*_15)) = 1; // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 + StorageDead(_15); // scope 6 at $DIR/inline-generator.rs:15:41: 15:41 + goto -> bb1; // scope 0 at $DIR/inline-generator.rs:15:41: 15:41 diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir index 11a205eb41580..a0b23b43ef467 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir @@ -22,7 +22,7 @@ fn b(_1: &mut Box) -> &mut T { StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageLive(_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageLive(_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _7 = move (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _7 = virt (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageLive(_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _8 = (((_7.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _6 = &mut (*_8); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir index b04a91d7c9590..91acf2d2c5c4e 100644 --- a/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir +++ b/src/test/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir @@ -16,7 +16,7 @@ fn d(_1: &Box) -> &T { StorageLive(_3); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 _3 = &(*_1); // scope 0 at $DIR/issue-58867-inline-as-ref-as-mut.rs:18:5: 18:15 StorageLive(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL - _4 = move (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + _4 = virt (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL StorageLive(_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _5 = (((_4.0: std::ptr::Unique).0: std::ptr::NonNull).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL _2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 498dcbb89006d..53fa2ccdcc138 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -124,6 +124,7 @@ fn check_rvalue<'tcx>( Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => { check_place(tcx, *place, span, body) }, + Rvalue::VirtualRef(place) => check_place(tcx, *place, span, body), Rvalue::Repeat(operand, _) | Rvalue::Use(operand) | Rvalue::Cast(