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:
Esteban Küber 2023-10-12 22:20:17 +00:00
parent df4379b4eb
commit e7618756c0
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();
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

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