Skip to content

Commit

Permalink
Rollup merge of rust-lang#57294 - estebank:point-copy-less, r=nikomat…
Browse files Browse the repository at this point in the history
…sakis

When using value after move, point at span of local

When trying to use a value after move, instead of using a note, point
at the local declaration that has a type that doesn't implement `Copy`
trait.

```
error[E0382]: use of moved value: `x`
  --> $DIR/issue-34721.rs:27:9
   |
LL |     pub fn baz<T: Foo>(x: T) -> T {
   |                -       - move occurs because `x` has type `T`, which does not implement the `Copy` trait
   |                |
   |                consider adding a `Copy` constraint to this type argument
LL |         if 0 == 1 {
LL |             bar::bar(x.zero())
   |                      - value moved here
LL |         } else {
LL |             x.zero()
   |             - value moved here
LL |         };
LL |         x.zero()
   |         ^ value used here after move
```

Fix rust-lang#34721.
  • Loading branch information
Centril authored Jan 21, 2019
2 parents 7164a9f + 09006d8 commit 68ea7e4
Show file tree
Hide file tree
Showing 23 changed files with 175 additions and 87 deletions.
41 changes: 30 additions & 11 deletions src/librustc_mir/borrow_check/error_reporting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,19 +198,38 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
let place = &self.move_data.move_paths[mpi].place;

let ty = place.ty(self.mir, self.infcx.tcx).to_ty(self.infcx.tcx);
let note_msg = match self.describe_place_with_options(
place,
IncludingDowncast(true),
) {
Some(name) => format!("`{}`", name),
let opt_name = self.describe_place_with_options(place, IncludingDowncast(true));
let note_msg = match opt_name {
Some(ref name) => format!("`{}`", name),
None => "value".to_owned(),
};

err.note(&format!(
"move occurs because {} has type `{}`, \
which does not implement the `Copy` trait",
note_msg, ty
));
if let ty::TyKind::Param(param_ty) = ty.sty {
let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id);
let def_id = generics.type_param(&param_ty, tcx).def_id;
if let Some(sp) = tcx.hir().span_if_local(def_id) {
err.span_label(
sp,
"consider adding a `Copy` constraint to this type argument",
);
}
}
if let Place::Local(local) = place {
let decl = &self.mir.local_decls[*local];
err.span_label(
decl.source_info.span,
format!(
"move occurs because {} has type `{}`, \
which does not implement the `Copy` trait",
note_msg, ty,
));
} else {
err.note(&format!(
"move occurs because {} has type `{}`, \
which does not implement the `Copy` trait",
note_msg, ty
));
}
}

if let Some((_, mut old_err)) = self.move_error_reported
Expand Down
10 changes: 6 additions & 4 deletions src/test/ui/borrowck/borrowck-asm.mir.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
error[E0382]: use of moved value: `x`
--> $DIR/borrowck-asm.rs:27:17
|
LL | let x = &mut 0isize;
| - move occurs because `x` has type `&mut isize`, which does not implement the `Copy` trait
LL | unsafe {
LL | asm!("nop" : : "r"(x));
| - value moved here
LL | }
LL | let z = x; //[ast]~ ERROR use of moved value: `x`
| ^ value used here after move
|
= note: move occurs because `x` has type `&mut isize`, which does not implement the `Copy` trait

error[E0503]: cannot use `x` because it was mutably borrowed
--> $DIR/borrowck-asm.rs:35:32
Expand Down Expand Up @@ -66,12 +67,13 @@ LL | let z = y;
error[E0382]: use of moved value: `x`
--> $DIR/borrowck-asm.rs:86:40
|
LL | let x = &mut 2;
| - move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait
LL | unsafe {
LL | asm!("nop" : : "r"(x), "r"(x) ); //[ast]~ ERROR use of moved value
| - ^ value used here after move
| |
| value moved here
|
= note: move occurs because `x` has type `&mut i32`, which does not implement the `Copy` trait

error: aborting due to 7 previous errors

Expand Down
5 changes: 3 additions & 2 deletions src/test/ui/borrowck/borrowck-drop-from-guard.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
error[E0382]: use of moved value: `my_str`
--> $DIR/borrowck-drop-from-guard.rs:11:23
|
LL | let my_str = "hello".to_owned();
| ------ move occurs because `my_str` has type `std::string::String`, which does not implement the `Copy` trait
LL | match Some(42) {
LL | Some(_) if { drop(my_str); false } => {}
| ------ value moved here
LL | Some(_) => {}
LL | None => { foo(my_str); } //~ ERROR [E0382]
| ^^^^^^ value used here after move
|
= note: move occurs because `my_str` has type `std::string::String`, which does not implement the `Copy` trait

error: aborting due to previous error

Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/borrowck/borrowck-issue-48962.stderr
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
error[E0382]: use of moved value: `src`
--> $DIR/borrowck-issue-48962.rs:16:5
|
LL | let mut src = &mut node;
| ------- move occurs because `src` has type `&mut Node`, which does not implement the `Copy` trait
LL | {src};
| --- value moved here
LL | src.next = None; //~ ERROR use of moved value: `src` [E0382]
| ^^^^^^^^ value used here after move
|
= note: move occurs because `src` has type `&mut Node`, which does not implement the `Copy` trait

error[E0382]: use of moved value: `src`
--> $DIR/borrowck-issue-48962.rs:22:5
|
LL | let mut src = &mut (22, 44);
| ------- move occurs because `src` has type `&mut (i32, i32)`, which does not implement the `Copy` trait
LL | {src};
| --- value moved here
LL | src.0 = 66; //~ ERROR use of moved value: `src` [E0382]
| ^^^^^^^^^^ value used here after move
|
= note: move occurs because `src` has type `&mut (i32, i32)`, which does not implement the `Copy` trait

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
error[E0382]: use of moved value: `t`
--> $DIR/borrowck-move-moved-value-into-closure.rs:14:12
|
LL | let t: Box<_> = box 3;
| - move occurs because `t` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
LL |
LL | call_f(move|| { *t + 1 });
| ------ - variable moved due to use in closure
| |
Expand All @@ -9,8 +12,6 @@ LL | call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value
| ^^^^^^ - use occurs due to use in closure
| |
| value used here after move
|
= note: move occurs because `t` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait

error: aborting due to previous error

Expand Down
5 changes: 3 additions & 2 deletions src/test/ui/borrowck/borrowck-reinit.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@ LL | let _ = (1,x); //~ ERROR use of moved value: `x` (Ast)
error[E0382]: use of moved value: `x` (Mir)
--> $DIR/borrowck-reinit.rs:8:16
|
LL | let mut x = Box::new(0);
| ----- move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait
...
LL | drop(x);
| - value moved here
LL | let _ = (1,x); //~ ERROR use of moved value: `x` (Ast)
| ^ value used here after move
|
= note: move occurs because `x` has type `std::boxed::Box<i32>`, which does not implement the `Copy` trait

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
error[E0382]: assign to part of moved value: `t`
--> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:23:9
|
LL | let mut t: Tuple = (S(0), 0);
| ----- move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait
LL | drop(t);
| - value moved here
LL | t.0 = S(1);
| ^^^^^^^^^^ value partially assigned here after move
|
= note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait

error[E0382]: assign to part of moved value: `u`
--> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:34:9
|
LL | let mut u: Tpair = Tpair(S(0), 0);
| ----- move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait
LL | drop(u);
| - value moved here
LL | u.0 = S(1);
| ^^^^^^^^^^ value partially assigned here after move
|
= note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait

error[E0382]: assign to part of moved value: `v`
--> $DIR/issue-54499-field-mutation-of-moved-out-with-mut.rs:45:9
|
LL | let mut v: Spair = Spair { x: S(0), y: 0 };
| ----- move occurs because `v` has type `Spair`, which does not implement the `Copy` trait
LL | drop(v);
| - value moved here
LL | v.x = S(1);
| ^^^^^^^^^^ value partially assigned here after move
|
= note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait

error: aborting due to 3 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ LL | t.0 = S(1);
error[E0382]: assign to part of moved value: `t`
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:23:9
|
LL | let t: Tuple = (S(0), 0);
| - move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait
LL | drop(t);
| - value moved here
LL | t.0 = S(1);
| ^^^^^^^^^^ value partially assigned here after move
|
= note: move occurs because `t` has type `(S, i32)`, which does not implement the `Copy` trait

error[E0594]: cannot assign to `t.1`, as `t` is not declared as mutable
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:27:9
Expand All @@ -38,12 +38,12 @@ LL | u.0 = S(1);
error[E0382]: assign to part of moved value: `u`
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:38:9
|
LL | let u: Tpair = Tpair(S(0), 0);
| - move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait
LL | drop(u);
| - value moved here
LL | u.0 = S(1);
| ^^^^^^^^^^ value partially assigned here after move
|
= note: move occurs because `u` has type `Tpair`, which does not implement the `Copy` trait

error[E0594]: cannot assign to `u.1`, as `u` is not declared as mutable
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:42:9
Expand All @@ -66,12 +66,12 @@ LL | v.x = S(1);
error[E0382]: assign to part of moved value: `v`
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:53:9
|
LL | let v: Spair = Spair { x: S(0), y: 0 };
| - move occurs because `v` has type `Spair`, which does not implement the `Copy` trait
LL | drop(v);
| - value moved here
LL | v.x = S(1);
| ^^^^^^^^^^ value partially assigned here after move
|
= note: move occurs because `v` has type `Spair`, which does not implement the `Copy` trait

error[E0594]: cannot assign to `v.y`, as `v` is not declared as mutable
--> $DIR/issue-54499-field-mutation-of-moved-out.rs:57:9
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/borrowck/two-phase-nonrecv-autoref.nll.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ LL | f(f(10));
error[E0382]: use of moved value: `*f`
--> $DIR/two-phase-nonrecv-autoref.rs:69:11
|
LL | fn twice_ten_so<F: FnOnce(i32) -> i32>(f: Box<F>) {
| - consider adding a `Copy` constraint to this type argument
LL | f(f(10));
| - ^ value used here after move
| |
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
error[E0382]: use of moved value: `b`
--> $DIR/issue-27282-move-match-input-into-guard.rs:18:14
|
LL | let b = &mut true;
| - move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait
...
LL | _ if { (|| { let bar = b; *bar = false; })();
| -- - variable moved due to use in closure
| |
| value moved into closure here
LL | false } => { },
LL | &mut true => { println!("You might think we should get here"); },
| ^^^^ value used here after move
|
= note: move occurs because `b` has type `&mut bool`, which does not implement the `Copy` trait

error: aborting due to previous error

Expand Down
5 changes: 3 additions & 2 deletions src/test/ui/issues/issue-29723.stderr
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
error[E0382]: use of moved value: `s`
--> $DIR/issue-29723.rs:12:13
|
LL | let s = String::new();
| - move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait
LL | let _s = match 0 {
LL | 0 if { drop(s); false } => String::from("oops"),
| - value moved here
...
LL | s
| ^ value used here after move
|
= note: move occurs because `s` has type `std::string::String`, which does not implement the `Copy` trait

error: aborting due to previous error

Expand Down
34 changes: 34 additions & 0 deletions src/test/ui/issues/issue-34721.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#![feature(nll)]

pub trait Foo {
fn zero(self) -> Self;
}

impl Foo for u32 {
fn zero(self) -> u32 { 0u32 }
}

pub mod bar {
pub use Foo;
pub fn bar<T: Foo>(x: T) -> T {
x.zero()
}
}

mod baz {
use bar;
use Foo;
pub fn baz<T: Foo>(x: T) -> T {
if 0 == 1 {
bar::bar(x.zero())
} else {
x.zero()
};
x.zero()
//~^ ERROR use of moved value
}
}

fn main() {
let _ = baz::baz(0u32);
}
20 changes: 20 additions & 0 deletions src/test/ui/issues/issue-34721.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error[E0382]: use of moved value: `x`
--> $DIR/issue-34721.rs:27:9
|
LL | pub fn baz<T: Foo>(x: T) -> T {
| - - move occurs because `x` has type `T`, which does not implement the `Copy` trait
| |
| consider adding a `Copy` constraint to this type argument
LL | if 0 == 1 {
LL | bar::bar(x.zero())
| - value moved here
LL | } else {
LL | x.zero()
| - value moved here
LL | };
LL | x.zero()
| ^ value used here after move

error: aborting due to previous error

For more information about this error, try `rustc --explain E0382`.
4 changes: 2 additions & 2 deletions src/test/ui/moves/moves-based-on-type-tuple.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ LL | box (x, x)
error[E0382]: use of moved value: `x` (Mir)
--> $DIR/moves-based-on-type-tuple.rs:6:13
|
LL | fn dup(x: Box<isize>) -> Box<(Box<isize>,Box<isize>)> {
| - move occurs because `x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait
LL | box (x, x)
| - ^ value used here after move
| |
| value moved here
|
= note: move occurs because `x` has type `std::boxed::Box<isize>`, which does not implement the `Copy` trait

error: aborting due to 2 previous errors

Expand Down
Loading

0 comments on commit 68ea7e4

Please sign in to comment.