8000 Initial implementation of `#![feature(move_ref_pattern)]` by Centril · Pull Request #68376 · rust-lang/rust · GitHub
[go: up one dir, main page]

Skip to content

Initial implementation of #![feature(move_ref_pattern)] #68376

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Feb 9, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
move_ref_pattern: change pov in diagnostics & add binding names
  • Loading branch information
Centril committed Feb 2, 2020
commit bd318be05dab2e1149595aacbf3d808559fa42dc
76 changes: 44 additions & 32 deletions src/librustc_mir_build/hair/pattern/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,8 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_
name,
tables.node_type(pat.hir_id),
);
sess.struct_span_err(pat.span, &format!("borrow of moved value: `{}`", name))
.span_label(binding_span, "value moved here")
sess.struct_span_err(pat.span, "borrow of moved value")
.span_label(binding_span, format!("value moved into `{}` here", name))
.span_label(binding_span, occurs_because)
.span_labels(conflicts_ref, "value borrowed here after move")
.emit();
Expand All @@ -675,50 +675,62 @@ fn check_borrow_conflicts_in_at_patterns(cx: &MatchVisitor<'_, '_>, pat: &Pat<'_
let mut conflicts_move = Vec::new();
let mut conflicts_mut_mut = Vec::new();
let mut conflicts_mut_ref = Vec::new();
sub.each_binding(|_, hir_id, span, _| match tables.extract_binding_mode(sess, hir_id, span) {
Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) {
(Mutability::Not, Mutability::Not) => {} // Both sides are `ref`.
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push(span), // 2x `ref mut`.
_ => conflicts_mut_ref.push(span), // `ref` + `ref mut` in either direction.
},
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => {
conflicts_move.push(span) // `ref mut?` + by-move conflict.
sub.each_binding(|_, hir_id, span, name| {
match tables.extract_binding_mode(sess, hir_id, span) {
Some(ty::BindByReference(mut_inner)) => match (mut_outer, mut_inner) {
(Mutability::Not, Mutability::Not) => {} // Both sides are `ref`.
(Mutability::Mut, Mutability::Mut) => conflicts_mut_mut.push((span, name)), // 2x `ref mut`.
_ => conflicts_mut_ref.push((span, name)), // `ref` + `ref mut` in either direction.
},
Some(ty::BindByValue(_)) if is_binding_by_move(cx, hir_id, span) => {
conflicts_move.push((span, name)) // `ref mut?` + by-move conflict.
}
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
}
Some(ty::BindByValue(_)) | None => {} // `ref mut?` + by-copy is fine.
});

// Report errors if any.
if !conflicts_mut_mut.is_empty() {
// Report mutability conflicts for e.g. `ref mut x @ Some(ref mut y)`.
let msg = &format!("cannot borrow `{}` as mutable more than once at a time", name);
sess.struct_span_err(pat.span, msg)
.span_label(binding_span, "first mutable borrow occurs here")
.span_labels(conflicts_mut_mut, "another mutable borrow occurs here")
.span_labels(conflicts_mut_ref, "also borrowed as immutable here")
.span_labels(conflicts_move, "also moved here")
.emit();
let mut err = sess
.struct_span_err(pat.span, "cannot borrow value as mutable more than once at a time");
err.span_label(binding_span, format!("first mutable borrow, by `{}`, occurs here", name));
for (span, name) in conflicts_mut_mut {
err.span_label(span, format!("another mutable borrow, by `{}`, occurs here", name));
}
for (span, name) in conflicts_mut_ref {
err.span_label(span, format!("also borrowed as immutable, by `{}`, here", name));
}
for (span, name) in conflicts_move {
err.span_label(span, format!("also moved into `{}` here", name));
}
err.emit();
} else if !conflicts_mut_ref.is_empty() {
// Report mutability conflicts for e.g. `ref x @ Some(ref mut y)` or the converse.
let (primary, also) = match mut_outer {
Mutability::Mut => ("mutable", "immutable"),
Mutability::Not => ("immutable", "mutable"),
};
let msg = &format!(
"cannot borrow `{}` as {} because it is also borrowed as {}",
name, also, primary,
);
sess.struct_span_err(pat.span, msg)
.span_label(binding_span, format!("{} borrow occurs here", primary))
.span_labels(conflicts_mut_ref, format!("{} borrow occurs here", also))
.span_labels(conflicts_move, "also moved here")
.emit();
let msg =
format!("cannot borrow value as {} because it is also borrowed as {}", also, primary);
let mut err = sess.struct_span_err(pat.span, &msg);
err.span_label(binding_span, format!("{} borrow, by `{}`, occurs here", primary, name));
for (span, name) in conflicts_mut_ref {
err.span_label(span, format!("{} borrow, by `{}`, occurs here", also, name));
}
for (span, name) in conflicts_move {
err.span_label(span, format!("also moved into `{}` here", name));
}
err.emit();
} else if !conflicts_move.is_empty() {
// Report by-ref and by-move conflicts, e.g. `ref x @ y`.
let msg = &format!("cannot move out of `{}` because it is borrowed", name);
sess.struct_span_err(pat.span, msg)
.span_label(binding_span, format!("borrow of `{}` occurs here", name))
.span_labels(conflicts_move, format!("move out of `{}` occurs here", name))
.emit();
let mut err =
sess.struct_span_err(pat.span, "cannot move out of value because it is borrowed");
err.span_label(binding_span, format!("value borrowed, by `{}`, here", name));
for (span, name) in conflicts_move {
err.span_label(span, format!("value moved into `{}` here", name));
}
err.emit();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct X {
fn main() {
let x = Some(X { x: () });
match x {
Some(ref _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed
Some(ref _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed
None => panic!(),
}

Expand All @@ -26,7 +26,7 @@ fn main() {

let mut x = Some(X { x: () });
match x {
Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of `_y` because it is borrowed
Some(ref mut _y @ _z) => {} //~ ERROR cannot move out of value because it is borrowed
None => panic!(),
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
error: cannot move out of `_y` because it is borrowed
error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:15:14
|
LL | Some(ref _y @ _z) => {}
| ------^^^--
| | |
| | move out of `_y` occurs here
| borrow of `_y` occurs here
| | value moved into `_z` here
| value borrowed, by `_y`, here

error: borrow of moved value: `_z`
error: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:21:14
|
LL | Some(_z @ ref _y) => {}
| --^^^------
| | |
| | value borrowed here after move
| value moved here
| value moved into `_z` here
| move occurs because `_z` has type `X` which does implement the `Copy` trait

error: cannot move out of `_y` because it is borrowed
error: cannot move out of value because it is borrowed
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:29:14
|
LL | Some(ref mut _y @ _z) => {}
| ----------^^^--
| | |
| | move out of `_y` occurs here
| borrow of `_y` occurs here
| | value moved into `_z` here
| value borrowed, by `_y`, here

error: borrow of moved value: `_z`
error: borrow of moved value
--> $DIR/bind-by-move-neither-can-live-while-the-other-survives-1.rs:35:14
|
LL | Some(_z @ ref mut _y) => {}
| --^^^----------
| | |
| | value borrowed here after move
| value moved here
| value moved into `_z` here
| move occurs because `_z` has type `X` which does implement the `Copy` trait

error[E0382]: borrow of moved value
Expand Down
16 changes: 8 additions & 8 deletions src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,37 +34,37 @@ fn main() {
a @ box b => {} //~ ERROR use of moved value
}

let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of `a` because it is borrowed
let ref a @ box b = Box::new(NC); //~ ERROR cannot move out of value because it is borrowed

let ref a @ box ref mut b = Box::new(nc());
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
let ref a @ box ref mut b = Box::new(NC);
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
let ref a @ box ref mut b = Box::new(NC);
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
*b = NC;
let ref a @ box ref mut b = Box::new(NC);
//~^ ERROR cannot borrow `a` as mutable because it is also borrowed as immutable
//~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
//~| ERROR cannot borrow `_` as mutable because it is also borrowed as immutable
*b = NC;
drop(a);

let ref mut a @ box ref b = Box::new(NC);
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC);
drop(b);

fn f5(ref mut a @ box ref b: Box<NC>) {
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC);
drop(b);
}

match Box::new(nc()) {
ref mut a @ box ref b => {
//~^ ERROR cannot borrow `a` as immutable because it is also borrowed as mutable
//~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
//~| ERROR cannot borrow `_` as immutable because it is also borrowed as mutable
*a = Box::new(NC);
drop(b);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,74 +1,74 @@
error: cannot move out of `a` because it is borrowed
error: cannot move out of value because it is borrowed
--> $DIR/borrowck-pat-at-and-box.rs:37:9
|
LL | let ref a @ box b = Box::new(NC);
| -----^^^^^^^-
| | |
| | move out of `a` occurs here
| borrow of `a` occurs here
| | value moved into `b` here
| value borrowed, by `a`, here

error: cannot borrow `a` as mutable because it is also borrowed as immutable
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:39:9
|
LL | let ref a @ box ref mut b = Box::new(nc());
| -----^^^^^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here

error: cannot borrow `a` as mutable because it is also borrowed as immutable
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:41:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here

error: cannot borrow `a` as mutable because it is also borrowed as immutable
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:43:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here

error: cannot borrow `a` as mutable because it is also borrowed as immutable
error: cannot borrow value as mutable because it is also borrowed as immutable
--> $DIR/borrowck-pat-at-and-box.rs:46:9
|
LL | let ref a @ box ref mut b = Box::new(NC);
| -----^^^^^^^---------
| | |
| | mutable borrow occurs here
| immutable borrow occurs here
| | mutable borrow, by `b`, occurs here
| immutable borrow, by `a`, occurs here

error: cannot borrow `a` as immutable because it is also borrowed as mutable
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:52:9
|
LL | let ref mut a @ box ref b = Box::new(NC);
| ---------^^^^^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here

error: cannot borrow `a` as immutable because it is also borrowed as mutable
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:66:9
|
LL | ref mut a @ box ref b => {
| ---------^^^^^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here

error: cannot borrow `a` as immutable because it is also borrowed as mutable
error: cannot borrow value as immutable because it is also borrowed as mutable
--> $DIR/borrowck-pat-at-and-box.rs:58:11
|
LL | fn f5(ref mut a @ box ref b: Box<NC>) {
| ---------^^^^^^^-----
| | |
| | immutable borrow occurs here
| mutable borrow occurs here
| | immutable borrow, by `b`, occurs here
| mutable borrow, by `a`, occurs here

error[E0382]: use of moved value
--> $DIR/borrowck-pat-at-and-box.rs:21:18
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error: borrow of moved value: `a`
error: borrow of moved value
--> $DIR/borrowck-pat-by-move-and-ref-inverse-promotion.rs:9:9
|
LL | let a @ ref b = U;
| -^^^-----
| | |
| | value borrowed here after move
| value moved here
| value moved into `a` here
| move occurs because `a` has type `main::U` which does implement the `Copy` trait

error: aborting due to previous error
Expand Down
Loading
0