Desugars drop and replace at MIR build

This commit desugars the drop and replace deriving from an
assignment at MIR build, avoiding the construction of the
DropAndReplace terminator (which will be removed in a followign PR)

In order to retain the same error messages for replaces a new
DesugaringKind::Replace variant is introduced.
This commit is contained in:
Giacomo Pasini 2023-02-08 22:29:52 +01:00
parent 13471d3b20
commit b3a47d9b6b
No known key found for this signature in database
GPG Key ID: A03851B78A6C9A46
20 changed files with 273 additions and 157 deletions

View File

@ -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),

View File

@ -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!(

View File

@ -40,7 +40,7 @@ use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, CapturedPlace, ParamEnv, RegionVid, TyCtxt};
use rustc_session::lint::builtin::UNUSED_MUT;
use rustc_span::{Span, Symbol};
use rustc_span::{DesugaringKind, Span, Symbol};
use either::Either;
use smallvec::SmallVec;
@ -1184,13 +1184,22 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
this.report_conflicting_borrow(location, place_span, bk, borrow);
this.buffer_error(err);
}
WriteKind::StorageDeadOrDrop => this
.report_borrowed_value_does_not_live_long_enough(
location,
borrow,
place_span,
Some(kind),
),
WriteKind::StorageDeadOrDrop => {
if let Some(DesugaringKind::Replace) = place_span.1.desugaring_kind() {
// If this is a drop triggered by a reassignment, it's more user friendly
// to report a problem with the explicit assignment than the implicit drop.
this.report_illegal_mutation_of_borrowed(
location, place_span, borrow,
)
} else {
this.report_borrowed_value_does_not_live_long_enough(
location,
borrow,
place_span,
Some(kind),
)
}
}
WriteKind::Mutate => {
this.report_illegal_mutation_of_borrowed(location, place_span, borrow)
}

View File

@ -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 {

View File

@ -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, .. }

View File

@ -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);
}
}
}

View File

@ -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",
}
}
}

View File

@ -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<std::boxed::Box<u32>>; // 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<std::boxed::Box<u32>>; // 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<std::boxed::Box<u32>>; // 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::<Box<u32>>::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
}
}

View File

@ -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<std::boxed::Box<u32>>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<std::boxed::Box<u32>>) }, span: $DIR/basic_assignment.rs:18:17: 18:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 0: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<std::boxed::Box<u32>>) }, span: $DIR/basic_assignment.rs:19:17: 19:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
| 1: user_ty: Canonical { max_universe: U0, variables: [], value: Ty(std::option::Option<std::boxed::Box<u32>>) }, span: $DIR/basic_assignment.rs:19:17: 19:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
|
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
}

View File

@ -1,5 +1,6 @@
// 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

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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<isize>]`, 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<isize>]`, 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<isize>]`, 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<isize>]`, 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<isize>]`, 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<isize>]`, 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];
| ^^^^^^

View File

@ -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<i32>) { //~ 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() {}

View File

@ -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<i32>) {
| - help: consider making this binding mutable: `mut b`

View File

@ -5,7 +5,6 @@ fn main() {
greeting = "DEALLOCATED".to_string();
//~^ ERROR cannot assign
drop(greeting);
//~^ ERROR cannot move
println!("thread result: {:?}", res);
}

View File

@ -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`.

View File

@ -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);
}