Skip to content

Commit

Permalink
Auto merge of rust-lang#116676 - estebank:issue-116658, r=compiler-er…
Browse files Browse the repository at this point in the history
…rors

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 rust-lang#116658.
  • Loading branch information
bors committed Oct 13, 2023
2 parents a4a10bd + e761875 commit 34bc571
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 34bc571

Please sign in to comment.