diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-02-02 19:34:06 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-02-02 19:34:06 +0100 |
| commit | 799bded9b44fd59b4647d4e2087b8d336f573bae (patch) | |
| tree | 3ded20415ccfc668b343cd95a93446cdff130825 | |
| parent | ef500863bd7a701506d275289af23f62eb931b40 (diff) | |
| parent | bc23bbb99034b762870d3e4372b53f2772ae5dee (diff) | |
| download | rust-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.rs | 24 | ||||
| -rw-r--r-- | src/test/ui/typeck/issue-93486.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/typeck/issue-93486.stderr | 11 |
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`. |
