about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2022-02-02 19:34:06 +0100
committerGitHub <noreply@github.com>2022-02-02 19:34:06 +0100
commit799bded9b44fd59b4647d4e2087b8d336f573bae (patch)
tree3ded20415ccfc668b343cd95a93446cdff130825
parentef500863bd7a701506d275289af23f62eb931b40 (diff)
parentbc23bbb99034b762870d3e4372b53f2772ae5dee (diff)
downloadrust-799bded9b44fd59b4647d4e2087b8d336f573bae.tar.gz
rust-799bded9b44fd59b4647d4e2087b8d336f573bae.zip
Rollup merge of #93574 - compiler-errors:bad-let-suggestion, r=lcnr
don't suggest adding `let` due to bad assignment expressions inside of `while` loop

adds a check that our `lhs` expression is actually within the conditional part of the `while` loop, instead of anywhere in the `while` body.

fixes #93486
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs24
-rw-r--r--src/test/ui/typeck/issue-93486.rs6
-rw-r--r--src/test/ui/typeck/issue-93486.stderr11
3 files changed, 33 insertions, 8 deletions
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 0e1dbc53806..82cda5a2f2e 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -865,14 +865,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ),
                     ..
                 }) => {
-                    // We have a situation like `while Some(0) = value.get(0) {`, where `while let`
-                    // was more likely intended.
-                    err.span_suggestion_verbose(
-                        expr.span.shrink_to_lo(),
-                        "you might have meant to use pattern destructuring",
-                        "let ".to_string(),
-                        Applicability::MachineApplicable,
-                    );
+                    // Check if our lhs is a child of the condition of a while loop
+                    let expr_is_ancestor = std::iter::successors(Some(lhs.hir_id), |id| {
+                        self.tcx.hir().find_parent_node(*id)
+                    })
+                    .take_while(|id| *id != parent)
+                    .any(|id| id == expr.hir_id);
+                    // if it is, then we have a situation like `while Some(0) = value.get(0) {`,
+                    // where `while let` was more likely intended.
+                    if expr_is_ancestor {
+                        err.span_suggestion_verbose(
+                            expr.span.shrink_to_lo(),
+                            "you might have meant to use pattern destructuring",
+                            "let ".to_string(),
+                            Applicability::MachineApplicable,
+                        );
+                    }
                     break;
                 }
                 hir::Node::Item(_)
diff --git a/src/test/ui/typeck/issue-93486.rs b/src/test/ui/typeck/issue-93486.rs
new file mode 100644
index 00000000000..f8f98d5c1c7
--- /dev/null
+++ b/src/test/ui/typeck/issue-93486.rs
@@ -0,0 +1,6 @@
+fn main() {
+    while let 1 = 1 {
+        vec![].last_mut().unwrap() = 3_u8;
+        //~^ ERROR invalid left-hand side of assignment
+    }
+}
diff --git a/src/test/ui/typeck/issue-93486.stderr b/src/test/ui/typeck/issue-93486.stderr
new file mode 100644
index 00000000000..70b5b63f1cb
--- /dev/null
+++ b/src/test/ui/typeck/issue-93486.stderr
@@ -0,0 +1,11 @@
+error[E0070]: invalid left-hand side of assignment
+  --> $DIR/issue-93486.rs:3:36
+   |
+LL |         vec![].last_mut().unwrap() = 3_u8;
+   |         -------------------------- ^
+   |         |
+   |         cannot assign to this expression
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0070`.