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.
This commit is contained in:
bors 2023-10-13 10:29:55 +00:00
commit 34bc5716b5
3 changed files with 69 additions and 1 deletions

View File

@ -2036,7 +2036,8 @@ fn label_fn_like(
} }
let typeck = self.typeck_results.borrow(); let typeck = self.typeck_results.borrow();
for (rcvr, args) in call_finder.calls { 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() && let ty::Closure(call_def_id, _) = rcvr_ty.kind()
&& def_id == *call_def_id && def_id == *call_def_id
&& let Some(idx) = expected_idx && let Some(idx) = expected_idx

View File

@ -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() {}

View File

@ -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`.