about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-10-13 10:29:55 +0000
committerbors <bors@rust-lang.org>2023-10-13 10:29:55 +0000
commit34bc5716b539272b193fdd2a549a28c60783cf5d (patch)
tree04a25535d905ed4cc3f0faa0ef0520f9a9d3b9d4
parenta4a10bdf29a13b8773948c8938d2af47c03becb9 (diff)
parente7618756c067081c4d347b1ad5f500af0bb534a0 (diff)
downloadrust-34bc5716b539272b193fdd2a549a28c60783cf5d.tar.gz
rust-34bc5716b539272b193fdd2a549a28c60783cf5d.zip
Auto merge of #116676 - estebank:issue-116658, r=compiler-errors
On type error involving closure, avoid ICE

When we encounter a type error involving a closure, we try to typeck prior closure invocations to see if they influenced the current expected type. When trying to do so, ensure that the closure was defined in our current scope.

Fix #116658.
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs3
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.rs23
-rw-r--r--tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr44
3 files changed, 69 insertions, 1 deletions
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 9b7f8f80310..c762e684480 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -2036,7 +2036,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
                 let typeck = self.typeck_results.borrow();
                 for (rcvr, args) in call_finder.calls {
-                    if let Some(rcvr_ty) = typeck.node_type_opt(rcvr.hir_id)
+                    if rcvr.hir_id.owner == typeck.hir_owner
+                        && let Some(rcvr_ty) = typeck.node_type_opt(rcvr.hir_id)
                         && let ty::Closure(call_def_id, _) = rcvr_ty.kind()
                         && def_id == *call_def_id
                         && let Some(idx) = expected_idx
diff --git a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.rs b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.rs
new file mode 100644
index 00000000000..157383fede1
--- /dev/null
+++ b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.rs
@@ -0,0 +1,23 @@
+fn test() {
+    let x = match **x { //~ ERROR
+        Some(&a) if { panic!() } => {}
+    };
+    let mut p = &x;
+
+    {
+        let mut closure = expect_sig(|p, y| *p = y);
+        closure(&mut p, &y); //~ ERROR
+        //~^ ERROR
+    }
+
+    deref(p); //~ ERROR
+}
+
+fn expect_sig<F>(f: F) -> F
+where
+    F: FnMut(&mut &i32, &i32),
+{
+    f
+}
+
+fn main() {}
diff --git a/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr
new file mode 100644
index 00000000000..1470c32d7de
--- /dev/null
+++ b/tests/ui/unboxed-closures/unboxed-closures-type-mismatch-closure-from-another-scope.stderr
@@ -0,0 +1,44 @@
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:2:21
+   |
+LL |     let x = match **x {
+   |                     ^ not found in this scope
+
+error[E0425]: cannot find value `y` in this scope
+  --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:26
+   |
+LL |         closure(&mut p, &y);
+   |                          ^ help: a local variable with a similar name exists: `p`
+
+error[E0308]: mismatched types
+  --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:17
+   |
+LL |         closure(&mut p, &y);
+   |         ------- ^^^^^^ expected `&mut &i32`, found `&mut &()`
+   |         |
+   |         arguments to this function are incorrect
+   |
+   = note: expected mutable reference `&mut &i32`
+              found mutable reference `&mut &()`
+note: closure parameter defined here
+  --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:8:39
+   |
+LL |         let mut closure = expect_sig(|p, y| *p = y);
+   |                                       ^
+
+error[E0425]: cannot find function `deref` in this scope
+  --> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:13:5
+   |
+LL |     deref(p);
+   |     ^^^^^ not found in this scope
+   |
+help: use the `.` operator to call the method `Deref::deref` on `&&()`
+   |
+LL -     deref(p);
+LL +     p.deref();
+   |
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0308, E0425.
+For more information about an error, try `rustc --explain E0308`.