mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 12:36:47 +00:00
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:
parent
df4379b4eb
commit
e7618756c0
@ -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
|
||||
|
@ -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() {}
|
@ -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`.
|
Loading…
Reference in New Issue
Block a user