]> git.lizzy.rs Git - rust.git/commitdiff
Use the root trait predicate to determine whether to remove references
authorEsteban Küber <esteban@kuber.com.ar>
Mon, 9 Jan 2023 04:43:18 +0000 (04:43 +0000)
committerEsteban Küber <esteban@kuber.com.ar>
Wed, 11 Jan 2023 21:39:07 +0000 (21:39 +0000)
Fix #84837.

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
tests/ui/auto-traits/typeck-default-trait-impl-precedence.stderr
tests/ui/not-panic/not-panic-safe-4.stderr
tests/ui/suggestions/suggest-remove-refs-5.fixed [new file with mode: 0644]
tests/ui/suggestions/suggest-remove-refs-5.rs [new file with mode: 0644]
tests/ui/suggestions/suggest-remove-refs-5.stderr [new file with mode: 0644]

index 7e900fe0034b463c10972f3f6c5039d889b3f71d..678e7b87829895eb1637be84dc517c2e672fb363 100644 (file)
@@ -1359,6 +1359,14 @@ fn suggest_remove_reference(
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
         let mut span = obligation.cause.span;
+        let mut trait_pred = trait_pred;
+        let mut code = obligation.cause.code();
+        while let Some((c, Some(parent_trait_pred))) = code.parent() {
+            // We want the root obligation, in order to detect properly handle
+            // `for _ in &mut &mut vec![] {}`.
+            code = c;
+            trait_pred = parent_trait_pred;
+        }
         while span.desugaring_kind().is_some() {
             // Remove all the hir desugaring contexts while maintaining the macro contexts.
             span.remove_mark();
index ce7095664c11a3798fcae9f8bccfd967562f5ad8..32256ed69a76915cc5f5a5778762364dd2b1ad89 100644 (file)
@@ -4,7 +4,6 @@ error[E0277]: the trait bound `u32: Signed` is not satisfied
 LL |     is_defaulted::<&'static u32>();
    |                    ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`
    |
-   = help: the trait `Signed` is implemented for `i32`
 note: required for `&'static u32` to implement `Defaulted`
   --> $DIR/typeck-default-trait-impl-precedence.rs:10:19
    |
@@ -15,6 +14,11 @@ note: required by a bound in `is_defaulted`
    |
 LL | fn is_defaulted<T:Defaulted>() { }
    |                   ^^^^^^^^^ required by this bound in `is_defaulted`
+help: consider removing the leading `&`-reference
+   |
+LL -     is_defaulted::<&'static u32>();
+LL +     is_defaulted::<u32>();
+   |
 
 error: aborting due to previous error
 
index fc1c594d0d422041ec99e62e30ca70c5c28600ee..9428c125651ec2f718e315ee34965df117a27707 100644 (file)
@@ -12,6 +12,11 @@ note: required by a bound in `assert`
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
    |              ^^^^^^^^^^ required by this bound in `assert`
+help: consider removing the leading `&`-reference
+   |
+LL -     assert::<&RefCell<i32>>();
+LL +     assert::<RefCell<i32>>();
+   |
 
 error[E0277]: the type `UnsafeCell<isize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
   --> $DIR/not-panic-safe-4.rs:9:14
@@ -28,6 +33,11 @@ note: required by a bound in `assert`
    |
 LL | fn assert<T: UnwindSafe + ?Sized>() {}
    |              ^^^^^^^^^^ required by this bound in `assert`
+help: consider removing the leading `&`-reference
+   |
+LL -     assert::<&RefCell<i32>>();
+LL +     assert::<RefCell<i32>>();
+   |
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/suggestions/suggest-remove-refs-5.fixed b/tests/ui/suggestions/suggest-remove-refs-5.fixed
new file mode 100644 (file)
index 0000000..9f59f9c
--- /dev/null
@@ -0,0 +1,8 @@
+// run-rustfix
+fn main() {
+    let v = &mut Vec::<i32>::new();
+    for _ in v {} //~ ERROR E0277
+
+    let v = &mut [1u8];
+    for _ in v {} //~ ERROR E0277
+}
diff --git a/tests/ui/suggestions/suggest-remove-refs-5.rs b/tests/ui/suggestions/suggest-remove-refs-5.rs
new file mode 100644 (file)
index 0000000..d56aa0c
--- /dev/null
@@ -0,0 +1,8 @@
+// run-rustfix
+fn main() {
+    let v = &mut &mut Vec::<i32>::new();
+    for _ in &mut &mut v {} //~ ERROR E0277
+
+    let v = &mut &mut [1u8];
+    for _ in &mut v {} //~ ERROR E0277
+}
diff --git a/tests/ui/suggestions/suggest-remove-refs-5.stderr b/tests/ui/suggestions/suggest-remove-refs-5.stderr
new file mode 100644 (file)
index 0000000..7de84d6
--- /dev/null
@@ -0,0 +1,37 @@
+error[E0277]: `Vec<i32>` is not an iterator
+  --> $DIR/suggest-remove-refs-5.rs:4:14
+   |
+LL |     for _ in &mut &mut v {}
+   |              ^^^^^^^^^^^ `Vec<i32>` is not an iterator; try calling `.into_iter()` or `.iter()`
+   |
+   = help: the trait `Iterator` is not implemented for `Vec<i32>`
+   = note: required for `&mut Vec<i32>` to implement `Iterator`
+   = note: 3 redundant requirements hidden
+   = note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator`
+   = note: required for `&mut &mut &mut &mut Vec<i32>` to implement `IntoIterator`
+help: consider removing 3 leading `&`-references
+   |
+LL ~     let v = &mut Vec::<i32>::new();
+LL ~     for _ in v {}
+   |
+
+error[E0277]: `[u8; 1]` is not an iterator
+  --> $DIR/suggest-remove-refs-5.rs:7:14
+   |
+LL |     for _ in &mut v {}
+   |              ^^^^^^ `[u8; 1]` is not an iterator; try calling `.into_iter()` or `.iter()`
+   |
+   = help: the trait `Iterator` is not implemented for `[u8; 1]`
+   = note: required for `&mut [u8; 1]` to implement `Iterator`
+   = note: 2 redundant requirements hidden
+   = note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator`
+   = note: required for `&mut &mut &mut [u8; 1]` to implement `IntoIterator`
+help: consider removing 2 leading `&`-references
+   |
+LL ~     let v = &mut [1u8];
+LL ~     for _ in v {}
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.