Skip to content

Commit 8b8cce1

Browse files
committed
Use the root trait predicate to determine whether to remove references
Fix #84837.
1 parent bb72117 commit 8b8cce1

File tree

6 files changed

+76
-1
lines changed

6 files changed

+76
-1
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+8
Original file line numberDiff line numberDiff line change
@@ -1359,6 +1359,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
13591359
trait_pred: ty::PolyTraitPredicate<'tcx>,
13601360
) -> bool {
13611361
let mut span = obligation.cause.span;
1362+
let mut trait_pred = trait_pred;
1363+
let mut code = obligation.cause.code();
1364+
while let Some((c, Some(parent_trait_pred))) = code.parent() {
1365+
// We want the root obligation, in order to detect properly handle
1366+
// `for _ in &mut &mut vec![] {}`.
1367+
code = c;
1368+
trait_pred = parent_trait_pred;
1369+
}
13621370
while span.desugaring_kind().is_some() {
13631371
// Remove all the hir desugaring contexts while maintaining the macro contexts.
13641372
span.remove_mark();

tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ error[E0277]: the trait bound `u32: Signed` is not satisfied
44
LL | is_defaulted::<&'static u32>();
55
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
66
|
7-
= help: the trait `Signed` is implemented for `i32`
87
note: required for `&'static u32` to implement `Defaulted`
98
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19
109
|
@@ -15,6 +14,11 @@ note: required by a bound in `is_defaulted`
1514
|
1615
LL | fn is_defaulted<T:Defaulted>() { }
1716
| ^^^^^^^^^ required by this bound in `is_defaulted`
17+
help: consider removing the leading `&`-reference
18+
|
19+
LL - is_defaulted::<&'static u32>();
20+
LL + is_defaulted::<u32>();
21+
|
1822

1923
error: aborting due to previous error
2024

tests/ui/not-panic/not-panic-safe-4.stderr

+10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ note: required by a bound in `assert`
1212
|
1313
LL | fn assert<T: UnwindSafe + ?Sized>() {}
1414
| ^^^^^^^^^^ required by this bound in `assert`
15+
help: consider removing the leading `&`-reference
16+
|
17+
LL - assert::<&RefCell<i32>>();
18+
LL + assert::<RefCell<i32>>();
19+
|
1520

1621
error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
1722
--> $DIR/not-panic-safe-4.rs:9:14
@@ -28,6 +33,11 @@ note: required by a bound in `assert`
2833
|
2934
LL | fn assert<T: UnwindSafe + ?Sized>() {}
3035
| ^^^^^^^^^^ required by this bound in `assert`
36+
help: consider removing the leading `&`-reference
37+
|
38+
LL - assert::<&RefCell<i32>>();
39+
LL + assert::<RefCell<i32>>();
40+
|
3141

3242
error: aborting due to 2 previous errors
3343

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
fn main() {
3+
let v = &mut Vec::<i32>::new();
4+
for _ in v {} //~ ERROR E0277
5+
6+
let v = &mut [1u8];
7+
for _ in v {} //~ ERROR E0277
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// run-rustfix
2+
fn main() {
3+
let v = &mut &mut Vec::<i32>::new();
4+
for _ in &mut &mut v {} //~ ERROR E0277
5+
6+
let v = &mut &mut [1u8];
7+
for _ in &mut v {} //~ ERROR E0277
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
error[E0277]: `Vec<i32>` is not an iterator
2+
--> $DIR/suggest-remove-refs-5.rs:4:14
3+
|
4+
LL | for _ in &mut &mut v {}
5+
| ^^^^^^^^^^^ `Vec<i32>` is not an iterator; try calling `.into_iter()` or `.iter()`
6+
|
7+
= help: the trait `Iterator` is not implemented for `Vec<i32>`
8+
= note: required for `&mut Vec<i32>` to implement `Iterator`
9+
= note: 3 redundant requirements hidden
10+
= note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator`
11+
= note: required for `&mut &mut &mut &mut Vec<i32>` to implement `IntoIterator`
12+
help: consider removing 3 leading `&`-references
13+
|
14+
LL ~ let v = &mut Vec::<i32>::new();
15+
LL ~ for _ in v {}
16+
|
17+
18+
error[E0277]: `[u8; 1]` is not an iterator
19+
--> $DIR/suggest-remove-refs-5.rs:7:14
20+
|
21+
LL | for _ in &mut v {}
22+
| ^^^^^^ `[u8; 1]` is not an iterator; try calling `.into_iter()` or `.iter()`
23+
|
24+
= help: the trait `Iterator` is not implemented for `[u8; 1]`
25+
= note: required for `&mut [u8; 1]` to implement `Iterator`
26+
= note: 2 redundant requirements hidden
27+
= note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator`
28+
= note: required for `&mut &mut &mut [u8; 1]` to implement `IntoIterator`
29+
help: consider removing 2 leading `&`-references
30+
|
31+
LL ~ let v = &mut [1u8];
32+
LL ~ for _ in v {}
33+
|
34+
35+
error: aborting due to 2 previous errors
36+
37+
For more information about this error, try `rustc --explain E0277`.

0 commit comments

Comments
 (0)