Skip to content

Commit 34bc571

Browse files
committed
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.
2 parents a4a10bd + e761875 commit 34bc571

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

Diff for: compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2036,7 +2036,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20362036
}
20372037
let typeck = self.typeck_results.borrow();
20382038
for (rcvr, args) in call_finder.calls {
2039-
if let Some(rcvr_ty) = typeck.node_type_opt(rcvr.hir_id)
2039+
if rcvr.hir_id.owner == typeck.hir_owner
2040+
&& let Some(rcvr_ty) = typeck.node_type_opt(rcvr.hir_id)
20402041
&& let ty::Closure(call_def_id, _) = rcvr_ty.kind()
20412042
&& def_id == *call_def_id
20422043
&& let Some(idx) = expected_idx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
fn test() {
2+
let x = match **x { //~ ERROR
3+
Some(&a) if { panic!() } => {}
4+
};
5+
let mut p = &x;
6+
7+
{
8+
let mut closure = expect_sig(|p, y| *p = y);
9+
closure(&mut p, &y); //~ ERROR
10+
//~^ ERROR
11+
}
12+
13+
deref(p); //~ ERROR
14+
}
15+
16+
fn expect_sig<F>(f: F) -> F
17+
where
18+
F: FnMut(&mut &i32, &i32),
19+
{
20+
f
21+
}
22+
23+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
error[E0425]: cannot find value `x` in this scope
2+
--> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:2:21
3+
|
4+
LL | let x = match **x {
5+
| ^ not found in this scope
6+
7+
error[E0425]: cannot find value `y` in this scope
8+
--> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:26
9+
|
10+
LL | closure(&mut p, &y);
11+
| ^ help: a local variable with a similar name exists: `p`
12+
13+
error[E0308]: mismatched types
14+
--> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:9:17
15+
|
16+
LL | closure(&mut p, &y);
17+
| ------- ^^^^^^ expected `&mut &i32`, found `&mut &()`
18+
| |
19+
| arguments to this function are incorrect
20+
|
21+
= note: expected mutable reference `&mut &i32`
22+
found mutable reference `&mut &()`
23+
note: closure parameter defined here
24+
--> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:8:39
25+
|
26+
LL | let mut closure = expect_sig(|p, y| *p = y);
27+
| ^
28+
29+
error[E0425]: cannot find function `deref` in this scope
30+
--> $DIR/unboxed-closures-type-mismatch-closure-from-another-scope.rs:13:5
31+
|
32+
LL | deref(p);
33+
| ^^^^^ not found in this scope
34+
|
35+
help: use the `.` operator to call the method `Deref::deref` on `&&()`
36+
|
37+
LL - deref(p);
38+
LL + p.deref();
39+
|
40+
41+
error: aborting due to 4 previous errors
42+
43+
Some errors have detailed explanations: E0308, E0425.
44+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)