about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-12 02:34:07 +0000
committerbors <bors@rust-lang.org>2023-10-12 02:34:07 +0000
commit3d575a2f2ef8a6eb99064bb31c16feb8d508f1ee (patch)
treec31f3038df31f0c4bdbb80769c2e7b405e0d7f8b /tests
parentf562931178ff103f23b9e9a10dc0deb38e0d064f (diff)
parent9d2eb66e1a9639b35f428fa478de179f9cfbe466 (diff)
downloadrust-3d575a2f2ef8a6eb99064bb31c16feb8d508f1ee.tar.gz
rust-3d575a2f2ef8a6eb99064bb31c16feb8d508f1ee.zip
Auto merge of #113487 - estebank:sugg-113174, r=oli-obk
Use structured suggestion for #113174

When encountering a for loop that is rejected by the borrow checker because it is being advanced within its body, provide a structured suggestion for `while let Some(pat) = iter.next()`.
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/suggestions/issue-102972.fixed41
-rw-r--r--tests/ui/suggestions/issue-102972.rs25
-rw-r--r--tests/ui/suggestions/issue-102972.stderr56
3 files changed, 118 insertions, 4 deletions
diff --git a/tests/ui/suggestions/issue-102972.fixed b/tests/ui/suggestions/issue-102972.fixed
new file mode 100644
index 00000000000..ebd73b2dc14
--- /dev/null
+++ b/tests/ui/suggestions/issue-102972.fixed
@@ -0,0 +1,41 @@
+// run-rustfix
+
+fn test1() {
+    let mut chars = "Hello".chars();
+    let iter = chars.by_ref();
+    while let Some(_c) = iter.next() {
+        iter.next(); //~ ERROR cannot borrow `chars` as mutable more than once at a time
+    }
+}
+
+fn test2() {
+    let v = vec![1, 2, 3];
+    let mut iter = v.iter();
+    while let Some(_i) = iter.next() {
+        iter.next(); //~ ERROR borrow of moved value: `iter`
+    }
+}
+
+fn test3() {
+    let v = vec![(), (), ()];
+    let mut i = v.iter();
+    let iter = i.by_ref();
+    while let Some(()) = iter.next() {
+        iter.next(); //~ ERROR cannot borrow `i`
+    }
+}
+
+fn test4() {
+    let v = vec![(), (), ()];
+    let mut iter = v.iter();
+    while let Some(()) = iter.next() {
+        iter.next(); //~ ERROR borrow of moved value: `iter`
+    }
+}
+
+fn main() {
+    test1();
+    test2();
+    test3();
+    test4();
+}
diff --git a/tests/ui/suggestions/issue-102972.rs b/tests/ui/suggestions/issue-102972.rs
index 106288b054d..1f8e9776759 100644
--- a/tests/ui/suggestions/issue-102972.rs
+++ b/tests/ui/suggestions/issue-102972.rs
@@ -1,3 +1,5 @@
+// run-rustfix
+
 fn test1() {
     let mut chars = "Hello".chars();
     for _c in chars.by_ref() {
@@ -13,4 +15,25 @@ fn test2() {
     }
 }
 
-fn main() { }
+fn test3() {
+    let v = vec![(), (), ()];
+    let mut i = v.iter();
+    for () in i.by_ref() {
+        i.next(); //~ ERROR cannot borrow `i`
+    }
+}
+
+fn test4() {
+    let v = vec![(), (), ()];
+    let mut iter = v.iter();
+    for () in iter {
+        iter.next(); //~ ERROR borrow of moved value: `iter`
+    }
+}
+
+fn main() {
+    test1();
+    test2();
+    test3();
+    test4();
+}
diff --git a/tests/ui/suggestions/issue-102972.stderr b/tests/ui/suggestions/issue-102972.stderr
index 3303d6bbc3f..4b0d3b96f85 100644
--- a/tests/ui/suggestions/issue-102972.stderr
+++ b/tests/ui/suggestions/issue-102972.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `chars` as mutable more than once at a time
-  --> $DIR/issue-102972.rs:4:9
+  --> $DIR/issue-102972.rs:6:9
    |
 LL |     for _c in chars.by_ref() {
    |               --------------
@@ -8,9 +8,17 @@ LL |     for _c in chars.by_ref() {
    |               first borrow later used here
 LL |         chars.next();
    |         ^^^^^ second mutable borrow occurs here
+   |
+   = note: a for loop advances the iterator for you, the result is stored in `_c`
+help: if you want to call `next` on a iterator within the loop, consider using `while let`
+   |
+LL ~     let iter = chars.by_ref();
+LL ~     while let Some(_c) = iter.next() {
+LL ~         iter.next();
+   |
 
 error[E0382]: borrow of moved value: `iter`
-  --> $DIR/issue-102972.rs:12:9
+  --> $DIR/issue-102972.rs:14:9
    |
 LL |     let mut iter = v.iter();
    |         -------- move occurs because `iter` has type `std::slice::Iter<'_, i32>`, which does not implement the `Copy` trait
@@ -19,10 +27,52 @@ LL |     for _i in iter {
 LL |         iter.next();
    |         ^^^^ value borrowed here after move
    |
+   = note: a for loop advances the iterator for you, the result is stored in `_i`
 note: `into_iter` takes ownership of the receiver `self`, which moves `iter`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+help: if you want to call `next` on a iterator within the loop, consider using `while let`
+   |
+LL |     while let Some(_i) = iter.next() {
+   |     ~~~~~~~~~~~~~~~  ~~~     +++++++
+
+error[E0499]: cannot borrow `i` as mutable more than once at a time
+  --> $DIR/issue-102972.rs:22:9
+   |
+LL |     for () in i.by_ref() {
+   |               ----------
+   |               |
+   |               first mutable borrow occurs here
+   |               first borrow later used here
+LL |         i.next();
+   |         ^ second mutable borrow occurs here
+   |
+   = note: a for loop advances the iterator for you, the result is stored in its pattern
+help: if you want to call `next` on a iterator within the loop, consider using `while let`
+   |
+LL ~     let iter = i.by_ref();
+LL ~     while let Some(()) = iter.next() {
+LL ~         iter.next();
+   |
+
+error[E0382]: borrow of moved value: `iter`
+  --> $DIR/issue-102972.rs:30:9
+   |
+LL |     let mut iter = v.iter();
+   |         -------- move occurs because `iter` has type `std::slice::Iter<'_, ()>`, which does not implement the `Copy` trait
+LL |     for () in iter {
+   |               ---- `iter` moved due to this implicit call to `.into_iter()`
+LL |         iter.next();
+   |         ^^^^ value borrowed here after move
+   |
+   = note: a for loop advances the iterator for you, the result is stored in its pattern
+note: `into_iter` takes ownership of the receiver `self`, which moves `iter`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+help: if you want to call `next` on a iterator within the loop, consider using `while let`
+   |
+LL |     while let Some(()) = iter.next() {
+   |     ~~~~~~~~~~~~~~~  ~~~     +++++++
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0382, E0499.
 For more information about an error, try `rustc --explain E0382`.