Suggest ref for some patterns as a fallback

This commit is contained in:
Esteban Küber 2022-12-08 17:14:56 -08:00
parent 4f7c257fd8
commit dd72b1a0df
34 changed files with 476 additions and 63 deletions

View File

@ -460,7 +460,7 @@ fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diagnostic, sp
} }
fn add_move_error_suggestions(&self, err: &mut Diagnostic, binds_to: &[Local]) { fn add_move_error_suggestions(&self, err: &mut Diagnostic, binds_to: &[Local]) {
let mut suggestions: Vec<(Span, &str, String)> = Vec::new(); let mut suggestions: Vec<(Span, String, String)> = Vec::new();
for local in binds_to { for local in binds_to {
let bind_to = &self.body.local_decls[*local]; let bind_to = &self.body.local_decls[*local];
if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var( if let Some(box LocalInfo::User(ClearCrossCrate::Set(BindingForm::Var(
@ -469,7 +469,14 @@ fn add_move_error_suggestions(&self, err: &mut Diagnostic, binds_to: &[Local]) {
{ {
let Ok(pat_snippet) = let Ok(pat_snippet) =
self.infcx.tcx.sess.source_map().span_to_snippet(pat_span) else { continue; }; self.infcx.tcx.sess.source_map().span_to_snippet(pat_span) else { continue; };
let Some(stripped) = pat_snippet.strip_prefix('&') else { continue; }; let Some(stripped) = pat_snippet.strip_prefix('&') else {
suggestions.push((
bind_to.source_info.span.shrink_to_lo(),
"consider borrowing the pattern binding".to_string(),
"ref ".to_string(),
));
continue;
};
let inner_pat_snippet = stripped.trim_start(); let inner_pat_snippet = stripped.trim_start();
let (pat_span, suggestion, to_remove) = if inner_pat_snippet.starts_with("mut") let (pat_span, suggestion, to_remove) = if inner_pat_snippet.starts_with("mut")
&& inner_pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace) && inner_pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace)
@ -488,18 +495,17 @@ fn add_move_error_suggestions(&self, err: &mut Diagnostic, binds_to: &[Local]) {
); );
(pat_span, String::new(), "borrow") (pat_span, String::new(), "borrow")
}; };
suggestions.push((pat_span, to_remove, suggestion.to_owned())); suggestions.push((
pat_span,
format!("consider removing the {to_remove}"),
suggestion.to_string(),
));
} }
} }
suggestions.sort_unstable_by_key(|&(span, _, _)| span); suggestions.sort_unstable_by_key(|&(span, _, _)| span);
suggestions.dedup_by_key(|&mut (span, _, _)| span); suggestions.dedup_by_key(|&mut (span, _, _)| span);
for (span, to_remove, suggestion) in suggestions { for (span, msg, suggestion) in suggestions {
err.span_suggestion_verbose( err.span_suggestion_verbose(span, &msg, suggestion, Applicability::MachineApplicable);
span,
&format!("consider removing the {to_remove}"),
suggestion,
Applicability::MachineApplicable,
);
} }
} }

View File

@ -0,0 +1,56 @@
// run-rustfix
#![allow(unused)]
enum Foo {
Foo1(Box<u32>, Box<u32>),
Foo2(Box<u32>),
Foo3,
}
fn blah() {
let f = &Foo::Foo1(Box::new(1), Box::new(2));
match &*f { //~ ERROR cannot move out of
Foo::Foo1(num1,
num2) => (),
Foo::Foo2(num) => (),
Foo::Foo3 => ()
}
}
struct S {
f: String,
g: String
}
impl Drop for S {
fn drop(&mut self) { println!("{}", self.f); }
}
fn move_in_match() {
match (S {f: "foo".to_string(), g: "bar".to_string()}) {
//~^ ERROR cannot move out of type `S`, which implements the `Drop` trait
S {
f: ref _s,
g: ref _t
} => {}
}
}
// from issue-8064
struct A {
a: Box<isize>,
}
fn free<T>(_: T) {}
fn blah2() {
let a = &A { a: Box::new(1) };
match &a.a { //~ ERROR cannot move out of
n => {
free(n)
}
}
free(a)
}
fn main() {}

View File

@ -1,3 +1,5 @@
// run-rustfix
#![allow(unused)]
enum Foo { enum Foo {
Foo1(Box<u32>, Box<u32>), Foo1(Box<u32>, Box<u32>),
Foo2(Box<u32>), Foo2(Box<u32>),

View File

@ -1,5 +1,5 @@
error[E0507]: cannot move out of `f` as enum variant `Foo1` which is behind a shared reference error[E0507]: cannot move out of `f` as enum variant `Foo1` which is behind a shared reference
--> $DIR/borrowck-move-error-with-note.rs:11:11 --> $DIR/borrowck-move-error-with-note.rs:13:11
| |
LL | match *f { LL | match *f {
| ^^ | ^^
@ -17,7 +17,7 @@ LL | match &*f {
| + | +
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-error-with-note.rs:28:11 --> $DIR/borrowck-move-error-with-note.rs:30:11
| |
LL | match (S {f: "foo".to_string(), g: "bar".to_string()}) { LL | match (S {f: "foo".to_string(), g: "bar".to_string()}) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
@ -28,9 +28,17 @@ LL | g: _t
| -- ...and here | -- ...and here
| |
= note: move occurs because these variables have types that don't implement the `Copy` trait = note: move occurs because these variables have types that don't implement the `Copy` trait
help: consider borrowing the pattern binding
|
LL | f: ref _s,
| +++
help: consider borrowing the pattern binding
|
LL | g: ref _t
| +++
error[E0507]: cannot move out of `a.a` which is behind a shared reference error[E0507]: cannot move out of `a.a` which is behind a shared reference
--> $DIR/borrowck-move-error-with-note.rs:46:11 --> $DIR/borrowck-move-error-with-note.rs:48:11
| |
LL | match a.a { LL | match a.a {
| ^^^ | ^^^

View File

@ -0,0 +1,24 @@
// run-rustfix
#![allow(unused)]
struct S {f:String}
impl Drop for S {
fn drop(&mut self) { println!("{}", self.f); }
}
fn move_in_match() {
match (S {f:"foo".to_string()}) {
//~^ ERROR [E0509]
S {f:ref _s} => {}
}
}
fn move_in_let() {
let S {f:ref _s} = S {f:"foo".to_string()};
//~^ ERROR [E0509]
}
fn move_in_fn_arg(S {f:ref _s}: S) {
//~^ ERROR [E0509]
}
fn main() {}

View File

@ -1,3 +1,5 @@
// run-rustfix
#![allow(unused)]
struct S {f:String} struct S {f:String}
impl Drop for S { impl Drop for S {
fn drop(&mut self) { println!("{}", self.f); } fn drop(&mut self) { println!("{}", self.f); }

View File

@ -1,5 +1,5 @@
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-out-of-struct-with-dtor.rs:7:11 --> $DIR/borrowck-move-out-of-struct-with-dtor.rs:9:11
| |
LL | match (S {f:"foo".to_string()}) { LL | match (S {f:"foo".to_string()}) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here | ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
@ -9,18 +9,28 @@ LL | S {f:_s} => {}
| | | |
| data moved here | data moved here
| move occurs because `_s` has type `String`, which does not implement the `Copy` trait | move occurs because `_s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | S {f:ref _s} => {}
| +++
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-out-of-struct-with-dtor.rs:14:20 --> $DIR/borrowck-move-out-of-struct-with-dtor.rs:16:20
| |
LL | let S {f:_s} = S {f:"foo".to_string()}; LL | let S {f:_s} = S {f:"foo".to_string()};
| -- ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here | -- ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of here
| | | |
| data moved here | data moved here
| move occurs because `_s` has type `String`, which does not implement the `Copy` trait | move occurs because `_s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let S {f:ref _s} = S {f:"foo".to_string()};
| +++
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-out-of-struct-with-dtor.rs:18:19 --> $DIR/borrowck-move-out-of-struct-with-dtor.rs:20:19
| |
LL | fn move_in_fn_arg(S {f:_s}: S) { LL | fn move_in_fn_arg(S {f:_s}: S) {
| ^^^^^--^ | ^^^^^--^
@ -28,6 +38,11 @@ LL | fn move_in_fn_arg(S {f:_s}: S) {
| | data moved here | | data moved here
| | move occurs because `_s` has type `String`, which does not implement the `Copy` trait | | move occurs because `_s` has type `String`, which does not implement the `Copy` trait
| cannot move out of here | cannot move out of here
|
help: consider borrowing the pattern binding
|
LL | fn move_in_fn_arg(S {f:ref _s}: S) {
| +++
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View File

@ -0,0 +1,24 @@
// run-rustfix
#![allow(unused)]
struct S(String);
impl Drop for S {
fn drop(&mut self) { }
}
fn move_in_match() {
match S("foo".to_string()) {
//~^ ERROR cannot move out of type `S`, which implements the `Drop` trait
S(ref _s) => {}
}
}
fn move_in_let() {
let S(ref _s) = S("foo".to_string());
//~^ ERROR cannot move out of type `S`, which implements the `Drop` trait
}
fn move_in_fn_arg(S(ref _s): S) {
//~^ ERROR cannot move out of type `S`, which implements the `Drop` trait
}
fn main() {}

View File

@ -1,3 +1,5 @@
// run-rustfix
#![allow(unused)]
struct S(String); struct S(String);
impl Drop for S { impl Drop for S {
fn drop(&mut self) { } fn drop(&mut self) { }

View File

@ -1,5 +1,5 @@
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:7:11 --> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:9:11
| |
LL | match S("foo".to_string()) { LL | match S("foo".to_string()) {
| ^^^^^^^^^^^^^^^^^^^^ cannot move out of here | ^^^^^^^^^^^^^^^^^^^^ cannot move out of here
@ -9,18 +9,28 @@ LL | S(_s) => {}
| | | |
| data moved here | data moved here
| move occurs because `_s` has type `String`, which does not implement the `Copy` trait | move occurs because `_s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | S(ref _s) => {}
| +++
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:14:17 --> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:16:17
| |
LL | let S(_s) = S("foo".to_string()); LL | let S(_s) = S("foo".to_string());
| -- ^^^^^^^^^^^^^^^^^^^^ cannot move out of here | -- ^^^^^^^^^^^^^^^^^^^^ cannot move out of here
| | | |
| data moved here | data moved here
| move occurs because `_s` has type `String`, which does not implement the `Copy` trait | move occurs because `_s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let S(ref _s) = S("foo".to_string());
| +++
error[E0509]: cannot move out of type `S`, which implements the `Drop` trait error[E0509]: cannot move out of type `S`, which implements the `Drop` trait
--> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:18:19 --> $DIR/borrowck-move-out-of-tuple-struct-with-dtor.rs:20:19
| |
LL | fn move_in_fn_arg(S(_s): S) { LL | fn move_in_fn_arg(S(_s): S) {
| ^^--^ | ^^--^
@ -28,6 +38,11 @@ LL | fn move_in_fn_arg(S(_s): S) {
| | data moved here | | data moved here
| | move occurs because `_s` has type `String`, which does not implement the `Copy` trait | | move occurs because `_s` has type `String`, which does not implement the `Copy` trait
| cannot move out of here | cannot move out of here
|
help: consider borrowing the pattern binding
|
LL | fn move_in_fn_arg(S(ref _s): S) {
| +++
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View File

@ -6,6 +6,11 @@ LL | .find(|(&event_type, _)| event == event_type)
| | | |
| data moved here | data moved here
| move occurs because `event_type` has type `EventType`, which does not implement the `Copy` trait | move occurs because `event_type` has type `EventType`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | .find(|(&ref event_type, _)| event == event_type)
| +++
error: aborting due to previous error error: aborting due to previous error

View File

@ -0,0 +1,12 @@
// run-rustfix
// Regression test for #51415: match default bindings were failing to
// see the "move out" implied by `&s` below.
fn main() {
let a = vec![String::from("a")];
let opt = a.iter().enumerate().find(|(_, &ref s)| {
//~^ ERROR cannot move out
*s == String::from("d")
}).map(|(i, _)| i);
println!("{:?}", opt);
}

View File

@ -1,3 +1,4 @@
// run-rustfix
// Regression test for #51415: match default bindings were failing to // Regression test for #51415: match default bindings were failing to
// see the "move out" implied by `&s` below. // see the "move out" implied by `&s` below.

View File

@ -1,11 +1,16 @@
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/issue-51415.rs:6:42 --> $DIR/issue-51415.rs:7:42
| |
LL | let opt = a.iter().enumerate().find(|(_, &s)| { LL | let opt = a.iter().enumerate().find(|(_, &s)| {
| ^^^^^-^ | ^^^^^-^
| | | |
| data moved here | data moved here
| move occurs because `s` has type `String`, which does not implement the `Copy` trait | move occurs because `s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let opt = a.iter().enumerate().find(|(_, &ref s)| {
| +++
error: aborting due to previous error error: aborting due to previous error

View File

@ -0,0 +1,21 @@
// run-rustfix
struct X {
x: String,
}
impl Drop for X {
fn drop(&mut self) {
println!("value: {}", self.x);
}
}
fn unwrap(x: X) -> String {
let X { x: ref y } = x; //~ ERROR cannot move out of type
y.to_string()
}
fn main() {
let x = X { x: "hello".to_string() };
let y = unwrap(x);
println!("contents: {}", y);
}

View File

@ -1,3 +1,4 @@
// run-rustfix
struct X { struct X {
x: String, x: String,
} }
@ -10,7 +11,7 @@ fn drop(&mut self) {
fn unwrap(x: X) -> String { fn unwrap(x: X) -> String {
let X { x: y } = x; //~ ERROR cannot move out of type let X { x: y } = x; //~ ERROR cannot move out of type
y y.to_string()
} }
fn main() { fn main() {

View File

@ -1,11 +1,16 @@
error[E0509]: cannot move out of type `X`, which implements the `Drop` trait error[E0509]: cannot move out of type `X`, which implements the `Drop` trait
--> $DIR/disallowed-deconstructing-destructing-struct-let.rs:12:22 --> $DIR/disallowed-deconstructing-destructing-struct-let.rs:13:22
| |
LL | let X { x: y } = x; LL | let X { x: y } = x;
| - ^ cannot move out of here | - ^ cannot move out of here
| | | |
| data moved here | data moved here
| move occurs because `y` has type `String`, which does not implement the `Copy` trait | move occurs because `y` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let X { x: ref y } = x;
| +++
error: aborting due to previous error error: aborting due to previous error

View File

@ -0,0 +1,19 @@
// run-rustfix
struct X {
x: String,
}
impl Drop for X {
fn drop(&mut self) {
println!("value: {}", self.x);
}
}
fn main() {
let x = X { x: "hello".to_string() };
match x {
//~^ ERROR cannot move out of type `X`, which implements the `Drop` trait
X { x: ref y } => println!("contents: {}", y)
}
}

View File

@ -1,3 +1,4 @@
// run-rustfix
struct X { struct X {
x: String, x: String,
} }

View File

@ -1,5 +1,5 @@
error[E0509]: cannot move out of type `X`, which implements the `Drop` trait error[E0509]: cannot move out of type `X`, which implements the `Drop` trait
--> $DIR/disallowed-deconstructing-destructing-struct-match.rs:14:11 --> $DIR/disallowed-deconstructing-destructing-struct-match.rs:15:11
| |
LL | match x { LL | match x {
| ^ cannot move out of here | ^ cannot move out of here
@ -9,6 +9,11 @@ LL | X { x: y } => println!("contents: {}", y)
| | | |
| data moved here | data moved here
| move occurs because `y` has type `String`, which does not implement the `Copy` trait | move occurs because `y` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | X { x: ref y } => println!("contents: {}", y)
| +++
error: aborting due to previous error error: aborting due to previous error

View File

@ -11,6 +11,14 @@ LL | (&[hd1, ..], &[hd2, ..])
| --- ...and here | --- ...and here
| |
= note: move occurs because these variables have types that don't implement the `Copy` trait = note: move occurs because these variables have types that don't implement the `Copy` trait
help: consider borrowing the pattern binding
|
LL | (&[], &[ref hd, ..]) | (&[hd, ..], &[])
| +++
help: consider borrowing the pattern binding
|
LL | (&[ref hd1, ..], &[hd2, ..])
| +++
error[E0508]: cannot move out of type `[T]`, a non-copy slice error[E0508]: cannot move out of type `[T]`, a non-copy slice
--> $DIR/issue-12567.rs:2:11 --> $DIR/issue-12567.rs:2:11
@ -25,6 +33,14 @@ LL | (&[hd1, ..], &[hd2, ..])
| --- ...and here | --- ...and here
| |
= note: move occurs because these variables have types that don't implement the `Copy` trait = note: move occurs because these variables have types that don't implement the `Copy` trait
help: consider borrowing the pattern binding
|
LL | (&[], &[ref hd, ..]) | (&[hd, ..], &[])
| +++
help: consider borrowing the pattern binding
|
LL | (&[hd1, ..], &[ref hd2, ..])
| +++
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -8,6 +8,11 @@ LL | box [a] => {},
| | | |
| data moved here | data moved here
| move occurs because `a` has type `A`, which does not implement the `Copy` trait | move occurs because `a` has type `A`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | box [ref a] => {},
| +++
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,6 @@
#![feature(unsized_locals)] #![feature(unsized_locals)]
//~^ WARN the feature `unsized_locals` is incomplete //~^ WARN the feature `unsized_locals` is incomplete
#![allow(unused)]
struct A; struct A;
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

View File

@ -8,7 +8,7 @@ LL | #![feature(unsized_locals)]
= note: `#[warn(incomplete_features)]` on by default = note: `#[warn(incomplete_features)]` on by default
error[E0508]: cannot move out of type `[A]`, a non-copy slice error[E0508]: cannot move out of type `[A]`, a non-copy slice
--> $DIR/move-out-of-slice-2.rs:10:11 --> $DIR/move-out-of-slice-2.rs:11:11
| |
LL | match *a { LL | match *a {
| ^^ cannot move out of here | ^^ cannot move out of here
@ -18,9 +18,14 @@ LL | [a @ ..] => {}
| | | |
| data moved here | data moved here
| move occurs because `a` has type `[A]`, which does not implement the `Copy` trait | move occurs because `a` has type `[A]`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | [ref a @ ..] => {}
| +++
error[E0508]: cannot move out of type `[A]`, a non-copy slice error[E0508]: cannot move out of type `[A]`, a non-copy slice
--> $DIR/move-out-of-slice-2.rs:16:11 --> $DIR/move-out-of-slice-2.rs:17:11
| |
LL | match *b { LL | match *b {
| ^^ cannot move out of here | ^^ cannot move out of here
@ -30,9 +35,14 @@ LL | [_, _, b @ .., _] => {}
| | | |
| data moved here | data moved here
| move occurs because `b` has type `[A]`, which does not implement the `Copy` trait | move occurs because `b` has type `[A]`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | [_, _, ref b @ .., _] => {}
| +++
error[E0508]: cannot move out of type `[C]`, a non-copy slice error[E0508]: cannot move out of type `[C]`, a non-copy slice
--> $DIR/move-out-of-slice-2.rs:24:11 --> $DIR/move-out-of-slice-2.rs:25:11
| |
LL | match *c { LL | match *c {
| ^^ cannot move out of here | ^^ cannot move out of here
@ -42,9 +52,14 @@ LL | [c @ ..] => {}
| | | |
| data moved here | data moved here
| move occurs because `c` has type `[C]`, which does not implement the `Copy` trait | move occurs because `c` has type `[C]`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | [ref c @ ..] => {}
| +++
error[E0508]: cannot move out of type `[C]`, a non-copy slice error[E0508]: cannot move out of type `[C]`, a non-copy slice
--> $DIR/move-out-of-slice-2.rs:30:11 --> $DIR/move-out-of-slice-2.rs:31:11
| |
LL | match *d { LL | match *d {
| ^^ cannot move out of here | ^^ cannot move out of here
@ -54,6 +69,11 @@ LL | [_, _, d @ .., _] => {}
| | | |
| data moved here | data moved here
| move occurs because `d` has type `[C]`, which does not implement the `Copy` trait | move occurs because `d` has type `[C]`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | [_, _, ref d @ .., _] => {}
| +++
error: aborting due to 4 previous errors; 1 warning emitted error: aborting due to 4 previous errors; 1 warning emitted

View File

@ -81,6 +81,11 @@ LL | let C(D(s)) = c;
| | | |
| data moved here | data moved here
| move occurs because `s` has type `String`, which does not implement the `Copy` trait | move occurs because `s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let C(D(ref s)) = c;
| +++
error[E0507]: cannot move out of `*a` which is behind a shared reference error[E0507]: cannot move out of `*a` which is behind a shared reference
--> $DIR/move-errors.rs:51:9 --> $DIR/move-errors.rs:51:9
@ -116,6 +121,11 @@ LL | B::U(D(s)) => (),
| | | |
| data moved here | data moved here
| move occurs because `s` has type `String`, which does not implement the `Copy` trait | move occurs because `s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | B::U(D(ref s)) => (),
| +++
error[E0509]: cannot move out of type `D`, which implements the `Drop` trait error[E0509]: cannot move out of type `D`, which implements the `Drop` trait
--> $DIR/move-errors.rs:92:11 --> $DIR/move-errors.rs:92:11
@ -128,6 +138,11 @@ LL | (D(s), &t) => (),
| | | |
| data moved here | data moved here
| move occurs because `s` has type `String`, which does not implement the `Copy` trait | move occurs because `s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | (D(ref s), &t) => (),
| +++
error[E0507]: cannot move out of `*x.1` which is behind a shared reference error[E0507]: cannot move out of `*x.1` which is behind a shared reference
--> $DIR/move-errors.rs:92:11 --> $DIR/move-errors.rs:92:11
@ -140,6 +155,11 @@ LL | (D(s), &t) => (),
| | | |
| data moved here | data moved here
| move occurs because `t` has type `String`, which does not implement the `Copy` trait | move occurs because `t` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | (D(s), &ref t) => (),
| +++
error[E0509]: cannot move out of type `F`, which implements the `Drop` trait error[E0509]: cannot move out of type `F`, which implements the `Drop` trait
--> $DIR/move-errors.rs:102:11 --> $DIR/move-errors.rs:102:11
@ -153,6 +173,14 @@ LL | F(s, mut t) => (),
| data moved here | data moved here
| |
= note: move occurs because these variables have types that don't implement the `Copy` trait = note: move occurs because these variables have types that don't implement the `Copy` trait
help: consider borrowing the pattern binding
|
LL | F(ref s, mut t) => (),
| +++
help: consider borrowing the pattern binding
|
LL | F(s, ref mut t) => (),
| +++
error[E0507]: cannot move out of `x` as enum variant `Err` which is behind a shared reference error[E0507]: cannot move out of `x` as enum variant `Err` which is behind a shared reference
--> $DIR/move-errors.rs:110:11 --> $DIR/move-errors.rs:110:11

View File

@ -0,0 +1,12 @@
// run-rustfix
#![allow(unused_variables)]
fn main() {
struct U;
// A tuple is a "non-reference pattern".
// A `mut` binding pattern resets the binding mode to by-value.
let mut p = (U, U);
let (a, ref mut b) = &mut p;
//~^ ERROR cannot move out of a mutable reference
}

View File

@ -0,0 +1,12 @@
// run-rustfix
#![allow(unused_variables)]
fn main() {
struct U;
// A tuple is a "non-reference pattern".
// A `mut` binding pattern resets the binding mode to by-value.
let mut p = (U, U);
let (a, mut b) = &mut p;
//~^ ERROR cannot move out of a mutable reference
}

View File

@ -0,0 +1,17 @@
error[E0507]: cannot move out of a mutable reference
--> $DIR/move-ref-patterns-default-binding-modes-fixable.rs:10:22
|
LL | let (a, mut b) = &mut p;
| ----- ^^^^^^
| |
| data moved here
| move occurs because `b` has type `U`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let (a, ref mut b) = &mut p;
| +++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`.

View File

@ -7,8 +7,4 @@ fn main() {
let p = (U, U); let p = (U, U);
let (a, mut b) = &p; let (a, mut b) = &p;
//~^ ERROR cannot move out of a shared reference //~^ ERROR cannot move out of a shared reference
let mut p = (U, U);
let (a, mut b) = &mut p;
//~^ ERROR cannot move out of a mutable reference
} }

View File

@ -6,16 +6,12 @@ LL | let (a, mut b) = &p;
| | | |
| data moved here | data moved here
| move occurs because `b` has type `U`, which does not implement the `Copy` trait | move occurs because `b` has type `U`, which does not implement the `Copy` trait
error[E0507]: cannot move out of a mutable reference
--> $DIR/move-ref-patterns-default-binding-modes.rs:12:22
| |
LL | let (a, mut b) = &mut p; help: consider borrowing the pattern binding
| ----- ^^^^^^ |
| | LL | let (a, ref mut b) = &p;
| data moved here | +++
| move occurs because `b` has type `U`, which does not implement the `Copy` trait
error: aborting due to 2 previous errors error: aborting due to previous error
For more information about this error, try `rustc --explain E0507`. For more information about this error, try `rustc --explain E0507`.

View File

@ -6,6 +6,11 @@ LL | for (n, mut m) in &tups {
| | | |
| data moved here | data moved here
| move occurs because `m` has type `Foo`, which does not implement the `Copy` trait | move occurs because `m` has type `Foo`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | for (n, ref mut m) in &tups {
| +++
error: aborting due to previous error error: aborting due to previous error

View File

@ -219,31 +219,42 @@ fn f2(&mut X(_t): &mut X) { }
let (&X(_t),) = (&x.clone(),); let (&X(_t),) = (&x.clone(),);
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
if let (&Either::One(_t),) = (&e.clone(),) { } if let (&Either::One(_t),) = (&e.clone(),) { }
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
while let (&Either::One(_t),) = (&e.clone(),) { } while let (&Either::One(_t),) = (&e.clone(),) { }
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
match (&e.clone(),) { match (&e.clone(),) {
//~^ ERROR cannot move //~^ ERROR cannot move
(&Either::One(_t),) (&Either::One(_t),)
//~^ HELP consider borrowing the pattern binding
| (&Either::Two(_t),) => (), | (&Either::Two(_t),) => (),
} }
fn f3((&X(_t),): (&X,)) { } fn f3((&X(_t),): (&X,)) { }
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
let (&mut X(_t),) = (&mut xm.clone(),); let (&mut X(_t),) = (&mut xm.clone(),);
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
if let (&mut Either::One(_t),) = (&mut em.clone(),) { } if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
while let (&mut Either::One(_t),) = (&mut em.clone(),) { } while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
match (&mut em.clone(),) { match (&mut em.clone(),) {
//~^ ERROR cannot move //~^ ERROR cannot move
(&mut Either::One(_t),) => (), (&mut Either::One(_t),) => (),
//~^ HELP consider borrowing the pattern binding
(&mut Either::Two(_t),) => (), (&mut Either::Two(_t),) => (),
//~^ HELP consider borrowing the pattern binding
} }
fn f4((&mut X(_t),): (&mut X,)) { } fn f4((&mut X(_t),): (&mut X,)) { }
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
// move from &Either/&X value // move from &Either/&X value
@ -319,6 +330,7 @@ struct Testing {
fn testing(a: &Testing) { fn testing(a: &Testing) {
let Some(_s) = a.a else { let Some(_s) = a.a else {
//~^ ERROR cannot move //~^ ERROR cannot move
//~| HELP consider borrowing the pattern binding
return; return;
}; };
} }

View File

@ -566,27 +566,42 @@ LL | let (&X(_t),) = (&x.clone(),);
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let (&X(ref _t),) = (&x.clone(),);
| +++
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:222:34 --> $DIR/simple.rs:223:34
| |
LL | if let (&Either::One(_t),) = (&e.clone(),) { } LL | if let (&Either::One(_t),) = (&e.clone(),) { }
| -- ^^^^^^^^^^^^^ | -- ^^^^^^^^^^^^^
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | if let (&Either::One(ref _t),) = (&e.clone(),) { }
| +++
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:224:37 --> $DIR/simple.rs:226:37
| |
LL | while let (&Either::One(_t),) = (&e.clone(),) { } LL | while let (&Either::One(_t),) = (&e.clone(),) { }
| -- ^^^^^^^^^^^^^ | -- ^^^^^^^^^^^^^
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | while let (&Either::One(ref _t),) = (&e.clone(),) { }
| +++
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:226:11 --> $DIR/simple.rs:229:11
| |
LL | match (&e.clone(),) { LL | match (&e.clone(),) {
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
@ -596,49 +611,78 @@ LL | (&Either::One(_t),)
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | (&Either::One(ref _t),)
| +++
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:234:25 --> $DIR/simple.rs:239:25
| |
LL | let (&mut X(_t),) = (&mut xm.clone(),); LL | let (&mut X(_t),) = (&mut xm.clone(),);
| -- ^^^^^^^^^^^^^^^^^^ | -- ^^^^^^^^^^^^^^^^^^
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let (&mut X(ref _t),) = (&mut xm.clone(),);
| +++
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:236:38 --> $DIR/simple.rs:242:38
| |
LL | if let (&mut Either::One(_t),) = (&mut em.clone(),) { } LL | if let (&mut Either::One(_t),) = (&mut em.clone(),) { }
| -- ^^^^^^^^^^^^^^^^^^ | -- ^^^^^^^^^^^^^^^^^^
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | if let (&mut Either::One(ref _t),) = (&mut em.clone(),) { }
| +++
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:238:41 --> $DIR/simple.rs:245:41
| |
LL | while let (&mut Either::One(_t),) = (&mut em.clone(),) { } LL | while let (&mut Either::One(_t),) = (&mut em.clone(),) { }
| -- ^^^^^^^^^^^^^^^^^^ | -- ^^^^^^^^^^^^^^^^^^
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `X`, which does not implement the `Copy` trait | move occurs because `_t` has type `X`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | while let (&mut Either::One(ref _t),) = (&mut em.clone(),) { }
| +++
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:240:11 --> $DIR/simple.rs:248:11
| |
LL | match (&mut em.clone(),) { LL | match (&mut em.clone(),) {
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
LL | LL |
LL | (&mut Either::One(_t),) => (), LL | (&mut Either::One(_t),) => (),
| -- data moved here | -- data moved here
LL |
LL | (&mut Either::Two(_t),) => (), LL | (&mut Either::Two(_t),) => (),
| -- ...and here | -- ...and here
| |
= note: move occurs because these variables have types that don't implement the `Copy` trait = note: move occurs because these variables have types that don't implement the `Copy` trait
help: consider borrowing the pattern binding
|
LL | (&mut Either::One(ref _t),) => (),
| +++
help: consider borrowing the pattern binding
|
LL | (&mut Either::Two(ref _t),) => (),
| +++
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:250:18 --> $DIR/simple.rs:261:18
| |
LL | let &X(_t) = &x; LL | let &X(_t) = &x;
| -- ^^ | -- ^^
@ -653,7 +697,7 @@ LL + let X(_t) = &x;
| |
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:253:31 --> $DIR/simple.rs:264:31
| |
LL | if let &Either::One(_t) = &e { } LL | if let &Either::One(_t) = &e { }
| -- ^^ | -- ^^
@ -668,7 +712,7 @@ LL + if let Either::One(_t) = &e { }
| |
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:256:34 --> $DIR/simple.rs:267:34
| |
LL | while let &Either::One(_t) = &e { } LL | while let &Either::One(_t) = &e { }
| -- ^^ | -- ^^
@ -683,7 +727,7 @@ LL + while let Either::One(_t) = &e { }
| |
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:259:11 --> $DIR/simple.rs:270:11
| |
LL | match &e { LL | match &e {
| ^^ | ^^
@ -701,7 +745,7 @@ LL + Either::One(_t)
| |
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:266:11 --> $DIR/simple.rs:277:11
| |
LL | match &e { LL | match &e {
| ^^ | ^^
@ -719,7 +763,7 @@ LL + Either::One(_t) => (),
| |
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:272:11 --> $DIR/simple.rs:283:11
| |
LL | match &e { LL | match &e {
| ^^ | ^^
@ -737,7 +781,7 @@ LL + Either::One(_t) => (),
| |
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:279:22 --> $DIR/simple.rs:290:22
| |
LL | let &mut X(_t) = &mut xm; LL | let &mut X(_t) = &mut xm;
| -- ^^^^^^^ | -- ^^^^^^^
@ -752,7 +796,7 @@ LL + let mut X(_t) = &mut xm;
| |
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:282:35 --> $DIR/simple.rs:293:35
| |
LL | if let &mut Either::One(_t) = &mut em { } LL | if let &mut Either::One(_t) = &mut em { }
| -- ^^^^^^^ | -- ^^^^^^^
@ -767,7 +811,7 @@ LL + if let mut Either::One(_t) = &mut em { }
| |
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:285:38 --> $DIR/simple.rs:296:38
| |
LL | while let &mut Either::One(_t) = &mut em { } LL | while let &mut Either::One(_t) = &mut em { }
| -- ^^^^^^^ | -- ^^^^^^^
@ -782,7 +826,7 @@ LL + while let mut Either::One(_t) = &mut em { }
| |
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:288:11 --> $DIR/simple.rs:299:11
| |
LL | match &mut em { LL | match &mut em {
| ^^^^^^^ | ^^^^^^^
@ -800,7 +844,7 @@ LL + mut Either::One(_t)
| |
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:295:11 --> $DIR/simple.rs:306:11
| |
LL | match &mut em { LL | match &mut em {
| ^^^^^^^ | ^^^^^^^
@ -818,7 +862,7 @@ LL + mut Either::One(_t) => (),
| |
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:301:11 --> $DIR/simple.rs:312:11
| |
LL | match &mut em { LL | match &mut em {
| ^^^^^^^ | ^^^^^^^
@ -836,7 +880,7 @@ LL + mut Either::One(_t) => (),
| |
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:307:11 --> $DIR/simple.rs:318:11
| |
LL | match &mut em { LL | match &mut em {
| ^^^^^^^ | ^^^^^^^
@ -884,31 +928,46 @@ LL + fn f2(mut X(_t): &mut X) { }
| |
error[E0507]: cannot move out of a shared reference error[E0507]: cannot move out of a shared reference
--> $DIR/simple.rs:231:11 --> $DIR/simple.rs:235:11
| |
LL | fn f3((&X(_t),): (&X,)) { } LL | fn f3((&X(_t),): (&X,)) { }
| ^^^^--^^^ | ^^^^--^^^
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | fn f3((&X(ref _t),): (&X,)) { }
| +++
error[E0507]: cannot move out of a mutable reference error[E0507]: cannot move out of a mutable reference
--> $DIR/simple.rs:245:11 --> $DIR/simple.rs:255:11
| |
LL | fn f4((&mut X(_t),): (&mut X,)) { } LL | fn f4((&mut X(_t),): (&mut X,)) { }
| ^^^^^^^^--^^^ | ^^^^^^^^--^^^
| | | |
| data moved here | data moved here
| move occurs because `_t` has type `Y`, which does not implement the `Copy` trait | move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | fn f4((&mut X(ref _t),): (&mut X,)) { }
| +++
error[E0507]: cannot move out of `a.a` as enum variant `Some` which is behind a shared reference error[E0507]: cannot move out of `a.a` as enum variant `Some` which is behind a shared reference
--> $DIR/simple.rs:320:20 --> $DIR/simple.rs:331:20
| |
LL | let Some(_s) = a.a else { LL | let Some(_s) = a.a else {
| -- ^^^ | -- ^^^
| | | |
| data moved here | data moved here
| move occurs because `_s` has type `String`, which does not implement the `Copy` trait | move occurs because `_s` has type `String`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | let Some(ref _s) = a.a else {
| +++
error: aborting due to 61 previous errors error: aborting due to 61 previous errors

View File

@ -9,6 +9,11 @@ LL | (None, &c) => &c.unwrap(),
| | | |
| data moved here | data moved here
| move occurs because `c` has type `Option<String>`, which does not implement the `Copy` trait | move occurs because `c` has type `Option<String>`, which does not implement the `Copy` trait
|
help: consider borrowing the pattern binding
|
LL | (None, &ref c) => &c.unwrap(),
| +++
error: aborting due to previous error error: aborting due to previous error