about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-09-30 20:23:47 +0000
committerbors <bors@rust-lang.org>2021-09-30 20:23:47 +0000
commitaa7aca3b954131720df725e70d12e902eb3be1de (patch)
treeec4c0188a45ca8210d9fb58dd4a5b23aa6fb9ccb
parent6dc08b909b469d58dd8fa54c57ab193b8cf95257 (diff)
parentd0e2b607de9b3b4e7e6495206a21847201248144 (diff)
downloadrust-aa7aca3b954131720df725e70d12e902eb3be1de.tar.gz
rust-aa7aca3b954131720df725e70d12e902eb3be1de.zip
Auto merge of #89282 - sexxi-goose:fix-88118, r=nikomatsakis
2229: Consume IfLet expr

When using the IfLet guard feature, we can ICE when attempting to resolve PlaceBuilders.
For pattern matching, we currently don't consume the IfLet expression when "visiting" the arms leading us to not "read" all variables and hence not being able to resolve them.

r? `@nikomatsakis`
Closes https://github.com/rust-lang/rust/issues/88118
-rw-r--r--compiler/rustc_typeck/src/expr_use_visitor.rs2
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-88118-2.rs24
-rw-r--r--src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr12
3 files changed, 38 insertions, 0 deletions
diff --git a/compiler/rustc_typeck/src/expr_use_visitor.rs b/compiler/rustc_typeck/src/expr_use_visitor.rs
index ba70006fe96..b5c4d6ac261 100644
--- a/compiler/rustc_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_typeck/src/expr_use_visitor.rs
@@ -619,6 +619,8 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
 
         if let Some(hir::Guard::If(ref e)) = arm.guard {
             self.consume_expr(e)
+        } else if let Some(hir::Guard::IfLet(_, ref e)) = arm.guard {
+            self.consume_expr(e)
         }
 
         self.consume_expr(&arm.body);
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88118-2.rs b/src/test/ui/closures/2229_closure_analysis/issue-88118-2.rs
new file mode 100644
index 00000000000..0cfb1a55bf2
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-88118-2.rs
@@ -0,0 +1,24 @@
+// edition:2021
+// run-pass
+#![feature(if_let_guard)]
+#[allow(unused_must_use)]
+#[allow(dead_code)]
+
+fn print_error_count(registry: &Registry) {
+    |x: &Registry| {
+        match &x {
+            Registry if let _ = registry.try_find_description() => { }
+            //~^ WARNING: irrefutable `if let` guard pattern
+            _ => {}
+        }
+    };
+}
+
+struct Registry;
+impl Registry {
+    pub fn try_find_description(&self) {
+        unimplemented!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr b/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr
new file mode 100644
index 00000000000..15689023d81
--- /dev/null
+++ b/src/test/ui/closures/2229_closure_analysis/issue-88118-2.stderr
@@ -0,0 +1,12 @@
+warning: irrefutable `if let` guard pattern
+  --> $DIR/issue-88118-2.rs:10:29
+   |
+LL |             Registry if let _ = registry.try_find_description() => { }
+   |                             ^
+   |
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
+   = note: this pattern will always match, so the guard is useless
+   = help: consider removing the guard and adding a `let` inside the match arm
+
+warning: 1 warning emitted
+