Skip to content

Commit

Permalink
On type error involving closure, avoid ICE
Browse files Browse the repository at this point in the history
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 rust-lang#116658.
  • Loading branch information
estebank committed Oct 12, 2023
1 parent df4379b commit 284ff3e
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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() {}
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 284ff3e

Please sign in to comment.