diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index cb97699d7d2..a622a215a2e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1467,6 +1467,32 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// Reports StorageDeadOrDrop of `place` conflicts with `borrow`. /// + /// Depending on the origin of the StorageDeadOrDrop, this may be + /// reported as either a drop or an illegal mutation of a borrowed value. + /// The latter is preferred when the this is a drop triggered by a + /// reassignment, as it's more user friendly to report a problem with the + /// explicit assignment than the implicit drop. + #[instrument(level = "debug", skip(self))] + pub(crate) fn report_storage_dead_or_drop_of_borrowed( + &mut self, + location: Location, + place_span: (Place<'tcx>, Span), + borrow: &BorrowData<'tcx>, + ) { + // It's sufficient to check the last desugaring as Replace is the last + // one to be applied. + if let Some(DesugaringKind::Replace) = place_span.1.desugaring_kind() { + self.report_illegal_mutation_of_borrowed(location, place_span, borrow) + } else { + self.report_borrowed_value_does_not_live_long_enough( + location, + borrow, + place_span, + Some(WriteKind::StorageDeadOrDrop), + ) + } + } + /// This means that some data referenced by `borrow` needs to live /// past the point where the StorageDeadOrDrop of `place` occurs. /// This is usually interpreted as meaning that `place` has too diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index a99fd594a07..a1817f85483 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -925,7 +925,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return OtherUse(use_span); } - for stmt in &self.body[location.block].statements[location.statement_index + 1..] { + // drop and replace might have moved the assignment to the next block + let maybe_additional_statement = + if let TerminatorKind::Drop { target: drop_target, .. } = + self.body[location.block].terminator().kind + { + self.body[drop_target].statements.first() + } else { + None + }; + + let statements = + self.body[location.block].statements[location.statement_index + 1..].iter(); + + for stmt in statements.chain(maybe_additional_statement) { if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind { let (&def_id, is_generator) = match kind { box AggregateKind::Closure(def_id, _) => (def_id, false), diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index 328ac880dd4..eded913ae96 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -828,7 +828,13 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let Some(hir::Node::Item(item)) = node else { return; }; let hir::ItemKind::Fn(.., body_id) = item.kind else { return; }; let body = self.infcx.tcx.hir().body(body_id); - let mut v = V { assign_span: span, err, ty, suggested: false }; + let mut assign_span = span; + // Drop desugaring is done at MIR build so it's not in the HIR + if let Some(DesugaringKind::Replace) = span.desugaring_kind() { + assign_span.remove_mark(); + } + + let mut v = V { assign_span, err, ty, suggested: false }; v.visit_body(body); if !v.suggested { err.help(&format!( diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 0f591460e9d..115e512a974 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1185,12 +1185,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { this.buffer_error(err); } WriteKind::StorageDeadOrDrop => this - .report_borrowed_value_does_not_live_long_enough( - location, - borrow, - place_span, - Some(kind), - ), + .report_storage_dead_or_drop_of_borrowed(location, place_span, borrow), WriteKind::Mutate => { this.report_illegal_mutation_of_borrowed(location, place_span, borrow) } diff --git a/compiler/rustc_mir_build/src/build/expr/stmt.rs b/compiler/rustc_mir_build/src/build/expr/stmt.rs index 78083685193..ea5aeb67d85 100644 --- a/compiler/rustc_mir_build/src/build/expr/stmt.rs +++ b/compiler/rustc_mir_build/src/build/expr/stmt.rs @@ -40,7 +40,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // Generate better code for things that don't need to be // dropped. if lhs.ty.needs_drop(this.tcx, this.param_env) { - let rhs = unpack!(block = this.as_local_operand(block, rhs)); + let rhs = unpack!(block = this.as_local_rvalue(block, rhs)); let lhs = unpack!(block = this.as_place(block, lhs)); unpack!(block = this.build_drop_and_replace(block, lhs_span, lhs, rhs)); } else { diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 591b416337b..770701b3750 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -91,7 +91,7 @@ use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{Expr, LintLevel}; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::{DesugaringKind, Span, DUMMY_SP}; #[derive(Debug)] pub struct Scopes<'tcx> { @@ -1118,24 +1118,35 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } /// Utility function for *non*-scope code to build their own drops + /// Force a drop at this point in the MIR by creating a new block. pub(crate) fn build_drop_and_replace( &mut self, block: BasicBlock, span: Span, place: Place<'tcx>, - value: Operand<'tcx>, + value: Rvalue<'tcx>, ) -> BlockAnd<()> { + let span = self.tcx.with_stable_hashing_context(|hcx| { + span.mark_with_reason(None, DesugaringKind::Replace, self.tcx.sess.edition(), hcx) + }); let source_info = self.source_info(span); - let next_target = self.cfg.start_new_block(); + + // create the new block for the assignment + let assign = self.cfg.start_new_block(); + self.cfg.push_assign(assign, source_info, place, value.clone()); + + // create the new block for the assignment in the case of unwinding + let assign_unwind = self.cfg.start_new_cleanup_block(); + self.cfg.push_assign(assign_unwind, source_info, place, value.clone()); self.cfg.terminate( block, source_info, - TerminatorKind::DropAndReplace { place, value, target: next_target, unwind: None }, + TerminatorKind::Drop { place, target: assign, unwind: Some(assign_unwind) }, ); self.diverge_from(block); - next_target.unit() + assign.unit() } /// Creates an `Assert` terminator and return the success block. @@ -1413,8 +1424,15 @@ impl<'tcx> DropTreeBuilder<'tcx> for Unwind { fn add_entry(cfg: &mut CFG<'tcx>, from: BasicBlock, to: BasicBlock) { let term = &mut cfg.block_data_mut(from).terminator_mut(); match &mut term.kind { - TerminatorKind::Drop { unwind, .. } - | TerminatorKind::DropAndReplace { unwind, .. } + TerminatorKind::Drop { unwind, .. } => { + if let Some(unwind) = *unwind { + let source_info = term.source_info; + cfg.terminate(unwind, source_info, TerminatorKind::Goto { target: to }); + } else { + *unwind = Some(to); + } + } + TerminatorKind::DropAndReplace { unwind, .. } | TerminatorKind::FalseUnwind { unwind, .. } | TerminatorKind::Call { cleanup: unwind, .. } | TerminatorKind::Assert { cleanup: unwind, .. } diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index bdfd8dc6e99..29424f09695 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -14,7 +14,7 @@ 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}; -use rustc_span::Span; +use rustc_span::{DesugaringKind, Span}; use rustc_target::abi::VariantIdx; use std::fmt; @@ -425,10 +425,19 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { bb, ), LookupResult::Parent(..) => { - self.tcx.sess.delay_span_bug( - terminator.source_info.span, - &format!("drop of untracked value {:?}", bb), - ); + if !matches!( + terminator.source_info.span.desugaring_kind(), + Some(DesugaringKind::Replace), + ) { + self.tcx.sess.delay_span_bug( + terminator.source_info.span, + &format!("drop of untracked value {:?}", bb), + ); + } + // A drop and replace behind a pointer/array/whatever. + // The borrow checker requires that these locations are initialized before the assignment, + // so we just leave an unconditional drop. + assert!(!data.is_cleanup); } } } diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index dee823eefde..9f22e9776d4 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1151,6 +1151,7 @@ pub enum DesugaringKind { Await, ForLoop, WhileLoop, + Replace, } impl DesugaringKind { @@ -1166,6 +1167,7 @@ impl DesugaringKind { DesugaringKind::OpaqueTy => "`impl Trait`", DesugaringKind::ForLoop => "`for` loop", DesugaringKind::WhileLoop => "`while` loop", + DesugaringKind::Replace => "drop and replace", } } } diff --git a/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff b/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff new file mode 100644 index 00000000000..61a934685cd --- /dev/null +++ b/tests/mir-opt/basic_assignment.main.ElaborateDrops.diff @@ -0,0 +1,85 @@ +- // MIR for `main` before ElaborateDrops ++ // MIR for `main` after ElaborateDrops + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/basic_assignment.rs:+0:11: +0:11 + let _1: bool; // in scope 0 at $DIR/basic_assignment.rs:+1:9: +1:17 + let mut _3: bool; // in scope 0 at $DIR/basic_assignment.rs:+6:16: +6:24 + let mut _6: std::option::Option>; // in scope 0 at $DIR/basic_assignment.rs:+13:14: +13:20 + scope 1 { + debug nodrop_x => _1; // in scope 1 at $DIR/basic_assignment.rs:+1:9: +1:17 + let _2: bool; // in scope 1 at $DIR/basic_assignment.rs:+2:9: +2:17 + scope 2 { + debug nodrop_y => _2; // in scope 2 at $DIR/basic_assignment.rs:+2:9: +2:17 + let _4: std::option::Option>; // in scope 2 at $DIR/basic_assignment.rs:+8:9: +8:15 + scope 3 { + debug drop_x => _4; // in scope 3 at $DIR/basic_assignment.rs:+8:9: +8:15 + let _5: std::option::Option>; // in scope 3 at $DIR/basic_assignment.rs:+9:9: +9:15 + scope 4 { + debug drop_y => _5; // in scope 4 at $DIR/basic_assignment.rs:+9:9: +9:15 + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/basic_assignment.rs:+1:9: +1:17 + _1 = const false; // scope 0 at $DIR/basic_assignment.rs:+1:20: +1:25 + StorageLive(_2); // scope 1 at $DIR/basic_assignment.rs:+2:9: +2:17 + StorageLive(_3); // scope 2 at $DIR/basic_assignment.rs:+6:16: +6:24 + _3 = _1; // scope 2 at $DIR/basic_assignment.rs:+6:16: +6:24 + _2 = move _3; // scope 2 at $DIR/basic_assignment.rs:+6:5: +6:24 + StorageDead(_3); // scope 2 at $DIR/basic_assignment.rs:+6:23: +6:24 + StorageLive(_4); // scope 2 at $DIR/basic_assignment.rs:+8:9: +8:15 + _4 = Option::>::None; // scope 2 at $DIR/basic_assignment.rs:+8:36: +8:40 + StorageLive(_5); // scope 3 at $DIR/basic_assignment.rs:+9:9: +9:15 + StorageLive(_6); // scope 4 at $DIR/basic_assignment.rs:+13:14: +13:20 + _6 = move _4; // scope 4 at $DIR/basic_assignment.rs:+13:14: +13:20 +- drop(_5) -> [return: bb1, unwind: bb2]; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 ++ goto -> bb1; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 + } + + bb1: { + _5 = move _6; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 +- drop(_6) -> [return: bb3, unwind: bb6]; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 ++ goto -> bb3; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 + } + + bb2 (cleanup): { + _5 = move _6; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 + drop(_6) -> bb6; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 + } + + bb3: { + StorageDead(_6); // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 + _0 = const (); // scope 0 at $DIR/basic_assignment.rs:+0:11: +14:2 + drop(_5) -> [return: bb4, unwind: bb7]; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb4: { + StorageDead(_5); // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 +- drop(_4) -> bb5; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 ++ goto -> bb5; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb5: { + StorageDead(_4); // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 + StorageDead(_2); // scope 1 at $DIR/basic_assignment.rs:+14:1: +14:2 + StorageDead(_1); // scope 0 at $DIR/basic_assignment.rs:+14:1: +14:2 + return; // scope 0 at $DIR/basic_assignment.rs:+14:2: +14:2 + } + + bb6 (cleanup): { + drop(_5) -> bb7; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb7 (cleanup): { +- drop(_4) -> bb8; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 ++ goto -> bb8; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/basic_assignment.rs:+0:1: +14:2 + } + } + diff --git a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir index 1f099cd5e83..f20b534259a 100644 --- a/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir +++ b/tests/mir-opt/basic_assignment.main.SimplifyCfg-initial.after.mir @@ -1,8 +1,8 @@ // MIR for `main` after SimplifyCfg-initial | User Type Annotations -| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option> -| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option> +| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option>) }, span: $DIR/basic_assignment.rs:20:17: 20:33, inferred_ty: std::option::Option> +| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option>) }, span: $DIR/basic_assignment.rs:20:17: 20:33, inferred_ty: std::option::Option> | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/basic_assignment.rs:+0:11: +0:11 @@ -41,35 +41,37 @@ fn main() -> () { StorageLive(_5); // scope 3 at $DIR/basic_assignment.rs:+9:9: +9:15 StorageLive(_6); // scope 4 at $DIR/basic_assignment.rs:+13:14: +13:20 _6 = move _4; // scope 4 at $DIR/basic_assignment.rs:+13:14: +13:20 - replace(_5 <- move _6) -> [return: bb1, unwind: bb5]; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 + drop(_5) -> [return: bb1, unwind: bb2]; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 } bb1: { - drop(_6) -> [return: bb2, unwind: bb6]; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 + _5 = move _6; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 + drop(_6) -> [return: bb3, unwind: bb6]; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 } - bb2: { - StorageDead(_6); // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 - _0 = const (); // scope 0 at $DIR/basic_assignment.rs:+0:11: +14:2 - drop(_5) -> [return: bb3, unwind: bb7]; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 + bb2 (cleanup): { + _5 = move _6; // scope 4 at $DIR/basic_assignment.rs:+13:5: +13:11 + drop(_6) -> bb6; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 } bb3: { - StorageDead(_5); // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 - drop(_4) -> [return: bb4, unwind: bb8]; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 + StorageDead(_6); // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 + _0 = const (); // scope 0 at $DIR/basic_assignment.rs:+0:11: +14:2 + drop(_5) -> [return: bb4, unwind: bb7]; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 } bb4: { + StorageDead(_5); // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 + drop(_4) -> [return: bb5, unwind: bb8]; // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 + } + + bb5: { StorageDead(_4); // scope 2 at $DIR/basic_assignment.rs:+14:1: +14:2 StorageDead(_2); // scope 1 at $DIR/basic_assignment.rs:+14:1: +14:2 StorageDead(_1); // scope 0 at $DIR/basic_assignment.rs:+14:1: +14:2 return; // scope 0 at $DIR/basic_assignment.rs:+14:2: +14:2 } - bb5 (cleanup): { - drop(_6) -> bb6; // scope 4 at $DIR/basic_assignment.rs:+13:19: +13:20 - } - bb6 (cleanup): { drop(_5) -> bb7; // scope 3 at $DIR/basic_assignment.rs:+14:1: +14:2 } diff --git a/tests/mir-opt/basic_assignment.rs b/tests/mir-opt/basic_assignment.rs index ac350271e9f..92434e44aa9 100644 --- a/tests/mir-opt/basic_assignment.rs +++ b/tests/mir-opt/basic_assignment.rs @@ -1,5 +1,7 @@ +// needs-unwind // this tests move up progration, which is not yet implemented +// EMIT_MIR basic_assignment.main.ElaborateDrops.diff // EMIT_MIR basic_assignment.main.SimplifyCfg-initial.after.mir // Check codegen for assignments (`a = b`) where the left-hand-side is diff --git a/tests/mir-opt/issue_41110.test.ElaborateDrops.diff b/tests/mir-opt/issue_41110.test.ElaborateDrops.diff index 79e3d073be5..3dd1a9bbab5 100644 --- a/tests/mir-opt/issue_41110.test.ElaborateDrops.diff +++ b/tests/mir-opt/issue_41110.test.ElaborateDrops.diff @@ -38,37 +38,39 @@ StorageLive(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _6 = const false; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 _5 = move _1; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 -- replace(_2 <- move _5) -> [return: bb2, unwind: bb6]; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 -+ goto -> bb12; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 +- drop(_2) -> [return: bb2, unwind: bb3]; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 ++ goto -> bb2; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 } bb2: { -- drop(_5) -> [return: bb3, unwind: bb8]; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 -+ goto -> bb3; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 +- drop(_5) -> [return: bb4, unwind: bb8]; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 ++ goto -> bb4; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 } - bb3: { - StorageDead(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 - _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2 - drop(_2) -> [return: bb4, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 + bb3 (cleanup): { + _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 + drop(_5) -> bb8; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 } bb4: { - StorageDead(_2); // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 -- drop(_1) -> bb5; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 -+ goto -> bb5; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + StorageDead(_5); // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 + _0 = const (); // scope 0 at $DIR/issue_41110.rs:+0:15: +5:2 + drop(_2) -> [return: bb5, unwind: bb9]; // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 } bb5: { + StorageDead(_2); // scope 1 at $DIR/issue_41110.rs:+5:1: +5:2 +- drop(_1) -> bb6; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ goto -> bb6; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } + + bb6: { + _6 = const false; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 StorageDead(_1); // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 return; // scope 0 at $DIR/issue_41110.rs:+5:2: +5:2 } - bb6 (cleanup): { - drop(_5) -> bb8; // scope 2 at $DIR/issue_41110.rs:+4:9: +4:10 - } - bb7 (cleanup): { - drop(_4) -> bb8; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 + goto -> bb8; // scope 2 at $DIR/issue_41110.rs:+3:11: +3:12 @@ -81,7 +83,7 @@ bb9 (cleanup): { - drop(_1) -> bb10; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 -+ goto -> bb14; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ goto -> bb12; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 } bb10 (cleanup): { @@ -89,21 +91,11 @@ + } + + bb11 (cleanup): { -+ _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 -+ goto -> bb10; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 -+ } -+ -+ bb12: { -+ _2 = move _5; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 -+ goto -> bb2; // scope 2 at $DIR/issue_41110.rs:+4:5: +4:6 -+ } -+ -+ bb13 (cleanup): { + drop(_1) -> bb10; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 + } + -+ bb14 (cleanup): { -+ switchInt(_6) -> [0: bb10, otherwise: bb13]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 ++ bb12 (cleanup): { ++ switchInt(_6) -> [0: bb10, otherwise: bb11]; // scope 0 at $DIR/issue_41110.rs:+5:1: +5:2 } } diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff index 257f0b1e6e8..4e38659a90b 100644 --- a/tests/mir-opt/issue_41888.main.ElaborateDrops.diff +++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.diff @@ -34,7 +34,7 @@ } bb1: { - switchInt(move _2) -> [0: bb7, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 + switchInt(move _2) -> [0: bb8, otherwise: bb2]; // scope 1 at $DIR/issue_41888.rs:+2:8: +2:14 } bb2: { @@ -43,47 +43,56 @@ _4 = K; // scope 1 at $DIR/issue_41888.rs:+3:18: +3:19 _3 = E::F(move _4); // scope 1 at $DIR/issue_41888.rs:+3:13: +3:20 StorageDead(_4); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 -- replace(_1 <- move _3) -> [return: bb3, unwind: bb10]; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ goto -> bb14; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 +- drop(_1) -> [return: bb3, unwind: bb4]; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ goto -> bb3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 } bb3: { -- drop(_3) -> [return: bb4, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 -+ goto -> bb4; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 ++ _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 ++ _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 +- drop(_3) -> [return: bb5, unwind: bb11]; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 ++ goto -> bb5; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 } - bb4: { - StorageDead(_3); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 - _5 = discriminant(_1); // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 - switchInt(move _5) -> [0: bb5, otherwise: bb6]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + bb4 (cleanup): { + _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 + drop(_3) -> bb11; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 } bb5: { + StorageDead(_3); // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 + _5 = discriminant(_1); // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + switchInt(move _5) -> [0: bb6, otherwise: bb7]; // scope 2 at $DIR/issue_41888.rs:+4:16: +4:24 + } + + bb6: { StorageLive(_6); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 + _9 = const false; // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 _6 = move ((_1 as F).0: K); // scope 2 at $DIR/issue_41888.rs:+4:21: +4:23 _0 = const (); // scope 2 at $DIR/issue_41888.rs:+4:29: +7:10 StorageDead(_6); // scope 1 at $DIR/issue_41888.rs:+7:9: +7:10 - goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 - } - - bb6: { - _0 = const (); // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10 - goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 + goto -> bb9; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 } bb7: { - _0 = const (); // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6 - goto -> bb8; // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6 + _0 = const (); // scope 1 at $DIR/issue_41888.rs:+7:10: +7:10 + goto -> bb9; // scope 1 at $DIR/issue_41888.rs:+4:9: +7:10 } bb8: { - StorageDead(_2); // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6 -- drop(_1) -> bb9; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 -+ goto -> bb20; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + _0 = const (); // scope 1 at $DIR/issue_41888.rs:+8:6: +8:6 + goto -> bb9; // scope 1 at $DIR/issue_41888.rs:+2:5: +8:6 } bb9: { + StorageDead(_2); // scope 1 at $DIR/issue_41888.rs:+8:5: +8:6 +- drop(_1) -> bb10; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ goto -> bb18; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + + bb10: { + _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + _8 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + _9 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 @@ -91,10 +100,6 @@ return; // scope 0 at $DIR/issue_41888.rs:+9:2: +9:2 } - bb10 (cleanup): { - drop(_3) -> bb11; // scope 1 at $DIR/issue_41888.rs:+3:19: +3:20 - } - bb11 (cleanup): { - drop(_1) -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 @@ -104,55 +109,39 @@ resume; // scope 0 at $DIR/issue_41888.rs:+0:1: +9:2 + } + -+ bb13 (cleanup): { -+ _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ goto -> bb12; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ } -+ -+ bb14: { -+ _7 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ _8 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ _9 = const true; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ _1 = move _3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ goto -> bb3; // scope 1 at $DIR/issue_41888.rs:+3:9: +3:10 -+ } -+ -+ bb15: { ++ bb13: { + _7 = const false; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 -+ goto -> bb9; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ goto -> bb10; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + -+ bb16 (cleanup): { ++ bb14 (cleanup): { + goto -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + -+ bb17: { -+ drop(_1) -> [return: bb15, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ bb15: { ++ drop(_1) -> [return: bb13, unwind: bb12]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + -+ bb18 (cleanup): { ++ bb16 (cleanup): { + drop(_1) -> bb12; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + -+ bb19: { ++ bb17: { + _10 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 -+ switchInt(move _10) -> [0: bb15, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ switchInt(move _10) -> [0: bb13, otherwise: bb15]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + -+ bb20: { -+ switchInt(_7) -> [0: bb15, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ bb18: { ++ switchInt(_7) -> [0: bb13, otherwise: bb17]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + -+ bb21 (cleanup): { ++ bb19 (cleanup): { + _11 = discriminant(_1); // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 -+ switchInt(move _11) -> [0: bb16, otherwise: bb18]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ switchInt(move _11) -> [0: bb14, otherwise: bb16]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 + } + -+ bb22 (cleanup): { -+ switchInt(_7) -> [0: bb12, otherwise: bb21]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 ++ bb20 (cleanup): { ++ switchInt(_7) -> [0: bb12, otherwise: bb19]; // scope 0 at $DIR/issue_41888.rs:+9:1: +9:2 } } diff --git a/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir index 210f178a0a9..56cb9166c37 100644 --- a/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir +++ b/tests/mir-opt/packed_struct_drop_aligned.main.SimplifyCfg-elaborate-drops.after.mir @@ -28,21 +28,21 @@ fn main() -> () { StorageDead(_5); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29 StorageLive(_6); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 _6 = move (_1.0: Aligned); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 - drop(_6) -> [return: bb4, unwind: bb3]; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + drop(_6) -> [return: bb4, unwind: bb1]; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 } - bb1: { + bb1 (cleanup): { + (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 + drop(_1) -> bb3; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 + } + + bb2: { StorageDead(_1); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 return; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:2: +3:2 } - bb2 (cleanup): { - resume; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:1: +3:2 - } - bb3 (cleanup): { - (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 - drop(_1) -> bb2; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 + resume; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:1: +3:2 } bb4: { @@ -50,6 +50,6 @@ fn main() -> () { (_1.0: Aligned) = move _4; // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:5: +2:8 StorageDead(_4); // scope 1 at $DIR/packed_struct_drop_aligned.rs:+2:28: +2:29 _0 = const (); // scope 0 at $DIR/packed_struct_drop_aligned.rs:+0:11: +3:2 - drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 + drop(_1) -> [return: bb2, unwind: bb3]; // scope 0 at $DIR/packed_struct_drop_aligned.rs:+3:1: +3:2 } } diff --git a/tests/run-make/coverage-reports/expected_show_coverage.closure.txt b/tests/run-make/coverage-reports/expected_show_coverage.closure.txt index e463099a5ee..002ecec3b91 100644 --- a/tests/run-make/coverage-reports/expected_show_coverage.closure.txt +++ b/tests/run-make/coverage-reports/expected_show_coverage.closure.txt @@ -29,8 +29,8 @@ 29| 1| some_string = Some(String::from("the string content")); 30| 1| let 31| 1| a - 32| 1| = - 33| 1| || + 32| | = + 33| | || 34| 0| { 35| 0| let mut countdown = 0; 36| 0| if is_false { diff --git a/tests/ui/borrowck/borrowck-vec-pattern-nesting.rs b/tests/ui/borrowck/borrowck-vec-pattern-nesting.rs index 1bda7a49713..127a3f5b2dc 100644 --- a/tests/ui/borrowck/borrowck-vec-pattern-nesting.rs +++ b/tests/ui/borrowck/borrowck-vec-pattern-nesting.rs @@ -8,6 +8,7 @@ fn a() { //~^ NOTE `vec[_]` is borrowed here vec[0] = Box::new(4); //~ ERROR cannot assign //~^ NOTE `vec[_]` is assigned to here + //~| NOTE in this expansion of desugaring of drop and replace _a.use_ref(); //~^ NOTE borrow later used here } @@ -22,6 +23,7 @@ fn b() { //~^ `vec[_]` is borrowed here vec[0] = Box::new(4); //~ ERROR cannot assign //~^ NOTE `vec[_]` is assigned to here + //~| NOTE in this expansion of desugaring of drop and replace _b.use_ref(); //~^ NOTE borrow later used here } diff --git a/tests/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/tests/ui/borrowck/borrowck-vec-pattern-nesting.stderr index 70b9e4f4433..5e1251b0590 100644 --- a/tests/ui/borrowck/borrowck-vec-pattern-nesting.stderr +++ b/tests/ui/borrowck/borrowck-vec-pattern-nesting.stderr @@ -6,24 +6,24 @@ LL | [box ref _a, _, _] => { LL | LL | vec[0] = Box::new(4); | ^^^^^^ `vec[_]` is assigned to here but it was already borrowed -LL | +... LL | _a.use_ref(); | ------------ borrow later used here error[E0506]: cannot assign to `vec[_]` because it is borrowed - --> $DIR/borrowck-vec-pattern-nesting.rs:23:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:24:13 | LL | &mut [ref _b @ ..] => { | ------ `vec[_]` is borrowed here LL | LL | vec[0] = Box::new(4); | ^^^^^^ `vec[_]` is assigned to here but it was already borrowed -LL | +... LL | _b.use_ref(); | ------------ borrow later used here error[E0508]: cannot move out of type `[Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:34:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:36:11 | LL | match vec { | ^^^ cannot move out of here @@ -41,7 +41,7 @@ LL + [_a, | error[E0508]: cannot move out of type `[Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:46:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:48:13 | LL | let a = vec[0]; | ^^^^^^ @@ -55,7 +55,7 @@ LL | let a = &vec[0]; | + error[E0508]: cannot move out of type `[Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:55:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:57:11 | LL | match vec { | ^^^ cannot move out of here @@ -73,7 +73,7 @@ LL + [ | error[E0508]: cannot move out of type `[Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:65:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:67:13 | LL | let a = vec[0]; | ^^^^^^ @@ -87,7 +87,7 @@ LL | let a = &vec[0]; | + error[E0508]: cannot move out of type `[Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:74:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:76:11 | LL | match vec { | ^^^ cannot move out of here @@ -106,7 +106,7 @@ LL + [_a, _b, _c] => {} | error[E0508]: cannot move out of type `[Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:85:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:87:13 | LL | let a = vec[0]; | ^^^^^^ diff --git a/tests/ui/borrowck/issue-45199.rs b/tests/ui/borrowck/issue-45199.rs index ded46e56e34..6a6b25541f3 100644 --- a/tests/ui/borrowck/issue-45199.rs +++ b/tests/ui/borrowck/issue-45199.rs @@ -5,6 +5,7 @@ fn test_drop_replace() { b = Box::new(1); //~ NOTE first assignment b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` //~| NOTE cannot assign twice to immutable + //~| NOTE in this expansion of desugaring of drop and replace } fn test_call() { @@ -13,12 +14,14 @@ fn test_call() { //~| SUGGESTION mut b b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` //~| NOTE cannot assign twice to immutable + //~| NOTE in this expansion of desugaring of drop and replace } fn test_args(b: Box) { //~ HELP consider making this binding mutable //~| SUGGESTION mut b b = Box::new(2); //~ ERROR cannot assign to immutable argument `b` //~| NOTE cannot assign to immutable argument + //~| NOTE in this expansion of desugaring of drop and replace } fn main() {} diff --git a/tests/ui/borrowck/issue-45199.stderr b/tests/ui/borrowck/issue-45199.stderr index 47aa3090827..163f2370ba0 100644 --- a/tests/ui/borrowck/issue-45199.stderr +++ b/tests/ui/borrowck/issue-45199.stderr @@ -10,7 +10,7 @@ LL | b = Box::new(2); | ^ cannot assign twice to immutable variable error[E0384]: cannot assign twice to immutable variable `b` - --> $DIR/issue-45199.rs:14:5 + --> $DIR/issue-45199.rs:15:5 | LL | let b = Box::new(1); | - @@ -22,7 +22,7 @@ LL | b = Box::new(2); | ^ cannot assign twice to immutable variable error[E0384]: cannot assign to immutable argument `b` - --> $DIR/issue-45199.rs:20:5 + --> $DIR/issue-45199.rs:22:5 | LL | fn test_args(b: Box) { | - help: consider making this binding mutable: `mut b` diff --git a/tests/ui/borrowck/issue-58776-borrowck-scans-children.rs b/tests/ui/borrowck/issue-58776-borrowck-scans-children.rs index efa313a9d23..0b2372d1274 100644 --- a/tests/ui/borrowck/issue-58776-borrowck-scans-children.rs +++ b/tests/ui/borrowck/issue-58776-borrowck-scans-children.rs @@ -5,7 +5,6 @@ fn main() { greeting = "DEALLOCATED".to_string(); //~^ ERROR cannot assign drop(greeting); - //~^ ERROR cannot move println!("thread result: {:?}", res); } diff --git a/tests/ui/borrowck/issue-58776-borrowck-scans-children.stderr b/tests/ui/borrowck/issue-58776-borrowck-scans-children.stderr index 0870b423769..967451c68be 100644 --- a/tests/ui/borrowck/issue-58776-borrowck-scans-children.stderr +++ b/tests/ui/borrowck/issue-58776-borrowck-scans-children.stderr @@ -12,21 +12,6 @@ LL | greeting = "DEALLOCATED".to_string(); LL | println!("thread result: {:?}", res); | --- borrow later used here -error[E0505]: cannot move out of `greeting` because it is borrowed - --> $DIR/issue-58776-borrowck-scans-children.rs:7:10 - | -LL | let res = (|| (|| &greeting)())(); - | -- -------- borrow occurs due to use in closure - | | - | borrow of `greeting` occurs here -... -LL | drop(greeting); - | ^^^^^^^^ move out of `greeting` occurs here -... -LL | println!("thread result: {:?}", res); - | --- borrow later used here +error: aborting due to previous error -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0505, E0506. -For more information about an error, try `rustc --explain E0505`. +For more information about this error, try `rustc --explain E0506`. diff --git a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs index c9b16e43910..293fdca1cc9 100644 --- a/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs +++ b/tests/ui/liveness/liveness-assign/liveness-assign-imm-local-with-drop.rs @@ -5,6 +5,7 @@ fn test() { drop(b); b = Box::new(2); //~ ERROR cannot assign twice to immutable variable `b` //~| NOTE cannot assign twice to immutable + //~| NOTE in this expansion of desugaring of drop and replace drop(b); }