about summary refs log tree commit diff
path: root/compiler/rustc_mir_build/src
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-10-14 16:19:16 +0530
committerGitHub <noreply@github.com>2022-10-14 16:19:16 +0530
commit7cf09c57a21110a4ef76ee4fe1cba960806fd42d (patch)
treeb95ae3a4db742d337565230878b5ca00b86008e5 /compiler/rustc_mir_build/src
parent587b9c1a978e4f73ba1696ceb12a25c4b46af5fe (diff)
parenteab41a136a86d98f8f4cc87b5c76583f58daca8d (diff)
downloadrust-7cf09c57a21110a4ef76ee4fe1cba960806fd42d.tar.gz
rust-7cf09c57a21110a4ef76ee4fe1cba960806fd42d.zip
Rollup merge of #103031 - est31:match_guard_irrefutable_let, r=oli-obk
Suppress irrefutable let patterns lint for prefixes in match guards

In match guards, irrefutable prefixes might use the bindings created by the match pattern. Ideally, we check for this, but we can do the next best thing and just not lint for irrefutable prefixes in match guards.

Fixes #98361
Diffstat (limited to 'compiler/rustc_mir_build/src')
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs18
1 files changed, 13 insertions, 5 deletions
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index ec709a1db51..5984c800d83 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -370,8 +370,12 @@ impl<'p, 'tcx> MatchVisitor<'_, 'p, 'tcx> {
 
             // Check if the let source is while, for there is no alternative place to put a prefix,
             // and we shouldn't lint.
+            // For let guards inside a match, prefixes might use bindings of the match pattern,
+            // so can't always be moved out.
+            // FIXME: Add checking whether the bindings are actually used in the prefix,
+            // and lint if they are not.
             let let_source = let_source_parent(self.tcx, top, None);
-            if !matches!(let_source, LetSource::WhileLet) {
+            if !matches!(let_source, LetSource::WhileLet | LetSource::IfLetGuard) {
                 // Emit the lint
                 let prefix = &chain_refutabilities[..until];
                 lint_affix(prefix, "leading", "outside of the construct");
@@ -1151,10 +1155,14 @@ fn let_source_parent(tcx: TyCtxt<'_>, parent: HirId, pat_id: Option<HirId>) -> L
 
     let parent_parent = hir.get_parent_node(parent);
     let parent_parent_node = hir.get(parent_parent);
-    if let hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), span, .. }) =
-        parent_parent_node
-    {
-        return LetSource::LetElse(*span);
+    match parent_parent_node {
+        hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(_), span, .. }) => {
+            return LetSource::LetElse(*span);
+        }
+        hir::Node::Arm(hir::Arm { guard: Some(hir::Guard::If(_)), .. }) => {
+            return LetSource::IfLetGuard;
+        }
+        _ => {}
     }
 
     let parent_parent_parent = hir.get_parent_node(parent_parent);