Skip to content

Commit 48b684a

Browse files
committed
Be ambiguous when type cannot be properly mentioned
1 parent 6c506d4 commit 48b684a

8 files changed

+72
-56
lines changed

src/librustc_borrowck/borrowck/mod.rs

+24-16
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,16 @@ impl<'tcx> LoanPath<'tcx> {
346346
}
347347

348348
fn to_type(&self) -> Ty<'tcx> { self.ty }
349+
350+
fn is_downcast(&self) -> bool {
351+
match self.kind {
352+
LpDowncast(_, _) => true,
353+
LpExtend(ref lp, _, LpInterior(_, _)) => {
354+
lp.is_downcast()
355+
}
356+
_ => false,
357+
}
358+
}
349359
}
350360

351361
// FIXME (pnkfelix): See discussion here
@@ -711,28 +721,26 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
711721
err = if use_span == move_span {
712722
err.span_label(
713723
use_span,
714-
format!("value moved{} here in previous iteration of loop{}",
715-
move_note,
716-
extra_move_label));
717-
718-
if need_note {
719-
err.note(&format!("value moved because it has type `{}`, \
720-
which does not implement the `Copy` trait",
721-
moved_lp.ty)
722-
}
724+
format!("value moved{} here in previous iteration of loop",
725+
move_note));
723726
err
724727
} else {
725728
err.span_label(use_span, format!("value {} here after move", verb_participle));
726-
let extra_move_label = if need_note {
727-
&format!(" because it has type `{}`, which does not implement the `Copy` trait",
728-
moved_lp.ty)
729-
} else {
730-
""
731-
};
732-
err.span_label(move_span,format!("value moved{} here{}", move_note, extra_move_label));
729+
err.span_label(move_span, format!("value moved{} here", move_note));
733730
err
734731
};
735732

733+
if need_note {
734+
err.note(&format!(
735+
"move occurs because {} has type `{}`, which does not implement the `Copy` trait",
736+
if moved_lp.is_downcast() {
737+
"the value".to_string()
738+
} else {
739+
format!("`{}`", self.loan_path_to_string(moved_lp))
740+
},
741+
moved_lp.ty));
742+
}
743+
736744
// Note: we used to suggest adding a `ref binding` or calling
737745
// `clone` but those suggestions have been removed because
738746
// they are often not what you actually want to do, and were

src/test/compile-fail/issue-24357.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ struct NoCopy;
1212
fn main() {
1313
let x = NoCopy;
1414
let f = move || { let y = x; };
15-
//~^ NOTE value moved (into closure) here because it has type `NoCopy`, which does not
15+
//~^ NOTE value moved (into closure) here
1616
let z = x;
1717
//~^ ERROR use of moved value: `x`
1818
//~| NOTE value used here after move
19+
//~| NOTE move occurs because `x` has type `NoCopy`
1920
}

src/test/compile-fail/moves-based-on-type-distribute-copy-over-paren.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,19 @@ fn touch<A>(_a: &A) {}
1717
fn f00() {
1818
let x = "hi".to_string();
1919
let _y = Foo { f:x };
20-
//~^ NOTE value moved here because it has type
20+
//~^ NOTE value moved here
2121
touch(&x); //~ ERROR use of moved value: `x`
2222
//~^ NOTE value used here after move
23+
//~| NOTE move occurs because `x` has type `std::string::String`
2324
}
2425

2526
fn f05() {
2627
let x = "hi".to_string();
2728
let _y = Foo { f:(((x))) };
28-
//~^ NOTE value moved here because it has type
29+
//~^ NOTE value moved here
2930
touch(&x); //~ ERROR use of moved value: `x`
3031
//~^ NOTE value used here after move
32+
//~| NOTE move occurs because `x` has type `std::string::String`
3133
}
3234

3335
fn f10() {

src/test/ui/augmented-assignments.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,15 @@ impl AddAssign for Int {
2020

2121
fn main() {
2222
let mut x = Int(1);
23-
x
24-
//~^ error: use of moved value: `x`
25-
//~| note: value used here after move
23+
x //~ error: use of moved value: `x`
24+
//~^ value used here after move
2625
+=
27-
x;
28-
//~^ note: value moved here because it has type `Int`, which does not implement the `Copy`
26+
x; //~ value moved here
2927

3028
let y = Int(2);
31-
//~^ note: consider changing this to `mut y`
32-
y
33-
//~^ error: cannot borrow immutable local variable `y` as mutable
34-
//~| note: cannot borrow mutably
29+
//~^ consider changing this to `mut y`
30+
y //~ error: cannot borrow immutable local variable `y` as mutable
31+
//~| cannot borrow
3532
+=
3633
Int(1);
3734
}

src/test/ui/borrowck/borrowck-box-insensitivity.rs

+27-24
Original file line numberDiff line numberDiff line change
@@ -33,33 +33,36 @@ struct D {
3333
fn copy_after_move() {
3434
let a: Box<_> = box A { x: box 0, y: 1 };
3535
let _x = a.x;
36-
//~^ NOTE value moved here because it has type `std::boxed::Box<isize>`, which does not
37-
let _y = a.y; //~ ERROR use of moved value
38-
//~^ NOTE value used here after move
36+
//~^ value moved here
37+
let _y = a.y; //~ ERROR use of moved
38+
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
39+
//~| value used here after move
3940
}
4041

4142
fn move_after_move() {
4243
let a: Box<_> = box B { x: box 0, y: box 1 };
4344
let _x = a.x;
44-
//~^ NOTE value moved here because it has type `std::boxed::Box<isize>`, which does not
45+
//~^ value moved here
4546
let _y = a.y; //~ ERROR use of moved
46-
//~^ NOTE value used here after move
47+
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
48+
//~| value used here after move
4749
}
4850

4951
fn borrow_after_move() {
5052
let a: Box<_> = box A { x: box 0, y: 1 };
5153
let _x = a.x;
52-
//~^ NOTE value moved here because it has type `std::boxed::Box<isize>`, which does not
54+
//~^ value moved here
5355
let _y = &a.y; //~ ERROR use of moved
54-
//~^ NOTE value used here after move
56+
//~^ move occurs because `a.x` has type `std::boxed::Box<isize>`
57+
//~| value used here after move
5558
}
5659

5760
fn move_after_borrow() {
5861
let a: Box<_> = box B { x: box 0, y: box 1 };
5962
let _x = &a.x;
6063
let _y = a.y;
6164
//~^ ERROR cannot move
62-
//~| NOTE move out of
65+
//~| move out of
6366
}
6467

6568
fn copy_after_mut_borrow() {
@@ -73,54 +76,54 @@ fn move_after_mut_borrow() {
7376
let _x = &mut a.x;
7477
let _y = a.y;
7578
//~^ ERROR cannot move
76-
//~| NOTE move out of
79+
//~| move out of
7780
}
7881

7982
fn borrow_after_mut_borrow() {
8083
let mut a: Box<_> = box A { x: box 0, y: 1 };
8184
let _x = &mut a.x;
8285
let _y = &a.y; //~ ERROR cannot borrow
83-
//~^ NOTE immutable borrow occurs here (via `a.y`)
86+
//~^ immutable borrow occurs here (via `a.y`)
8487
}
8588

8689
fn mut_borrow_after_borrow() {
8790
let mut a: Box<_> = box A { x: box 0, y: 1 };
8891
let _x = &a.x;
8992
let _y = &mut a.y; //~ ERROR cannot borrow
90-
//~^ NOTE mutable borrow occurs here (via `a.y`)
93+
//~^ mutable borrow occurs here (via `a.y`)
9194
}
9295

9396
fn copy_after_move_nested() {
9497
let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
9598
let _x = a.x.x;
96-
//~^ NOTE value moved here because it has type `std::boxed::Box<isize>`, which does not
99+
//~^ value moved here
97100
let _y = a.y; //~ ERROR use of collaterally moved
98-
//~^ NOTE value used here after move
101+
//~| value used here after move
99102
}
100103

101104
fn move_after_move_nested() {
102105
let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
103106
let _x = a.x.x;
104-
//~^ NOTE value moved here because it has type `std::boxed::Box<isize>`, which does not
107+
//~^ value moved here
105108
let _y = a.y; //~ ERROR use of collaterally moved
106-
//~^ NOTE value used here after move
109+
//~| value used here after move
107110
}
108111

109112
fn borrow_after_move_nested() {
110113
let a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
111114
let _x = a.x.x;
112-
//~^ NOTE value moved here because it has type `std::boxed::Box<isize>`, which does not
115+
//~^ value moved here
113116
let _y = &a.y; //~ ERROR use of collaterally moved
114-
//~^ NOTE value used here after move
117+
//~| value used here after move
115118
}
116119

117120
fn move_after_borrow_nested() {
118121
let a: Box<_> = box D { x: box A { x: box 0, y: 1 }, y: box 2 };
119122
let _x = &a.x.x;
120-
//~^ NOTE borrow of `a.x.x` occurs here
123+
//~^ borrow of `a.x.x` occurs here
121124
let _y = a.y;
122125
//~^ ERROR cannot move
123-
//~| NOTE move out of
126+
//~| move out of
124127
}
125128

126129
fn copy_after_mut_borrow_nested() {
@@ -134,23 +137,23 @@ fn move_after_mut_borrow_nested() {
134137
let _x = &mut a.x.x;
135138
let _y = a.y;
136139
//~^ ERROR cannot move
137-
//~| NOTE move out of
140+
//~| move out of
138141
}
139142

140143
fn borrow_after_mut_borrow_nested() {
141144
let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
142145
let _x = &mut a.x.x;
143-
//~^ NOTE mutable borrow occurs here
146+
//~^ mutable borrow occurs here
144147
let _y = &a.y; //~ ERROR cannot borrow
145-
//~^ NOTE immutable borrow occurs here
148+
//~^ immutable borrow occurs here
146149
}
147150

148151
fn mut_borrow_after_borrow_nested() {
149152
let mut a: Box<_> = box C { x: box A { x: box 0, y: 1 }, y: 2 };
150153
let _x = &a.x.x;
151-
//~^ NOTE immutable borrow occurs here
154+
//~^ immutable borrow occurs here
152155
let _y = &mut a.y; //~ ERROR cannot borrow
153-
//~^ NOTE mutable borrow occurs here
156+
//~^ mutable borrow occurs here
154157
}
155158

156159
fn main() {

src/test/ui/borrowck/issue-41962.rs

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ pub fn main(){
1313

1414
loop {
1515
if let Some(thing) = maybe {
16+
//~^ ERROR use of partially moved value
17+
//~| ERROR use of moved value
1618
}
1719
}
1820
}

src/test/ui/borrowck/issue-41962.stderr

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,17 @@ error[E0382]: use of partially moved value: `maybe`
44
15 | if let Some(thing) = maybe {
55
| ----- ^^^^^ value used here after move
66
| |
7-
| value moved here because it has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
7+
| value moved here
8+
|
9+
= note: move occurs because the value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
810

911
error[E0382]: use of moved value: `(maybe as std::prelude::v1::Some).0`
1012
--> $DIR/issue-41962.rs:15:21
1113
|
1214
15 | if let Some(thing) = maybe {
1315
| ^^^^^ value moved here in previous iteration of loop
14-
= note: value moved because it has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
16+
|
17+
= note: move occurs because the value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
1518

1619
error: aborting due to 2 previous errors
1720

src/test/ui/moves-based-on-type-match-bindings.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ fn f10() {
2121

2222
let y = match x {
2323
Foo {f} => {}
24-
//~^ NOTE value moved here because it has type `std::string::String`, which does not
2524
};
2625

2726
touch(&x); //~ ERROR use of partially moved value: `x`
28-
//~^ NOTE value used here after move
27+
//~^ value used here after move
28+
//~| move occurs because `x.f` has type `std::string::String`
2929
}
3030

3131
fn main() {}

0 commit comments

Comments
 (0)