Merge #1945
1945: Handle divergence in type inference for blocks r=flodiebold a=lnicola Fixes #1944. The `infer_basics` test is failing, not sure what to do about it. Co-authored-by: Laurențiu Nicola <lnicola@dend.ro>
This commit is contained in:
commit
e1c3675951
@ -1602,6 +1602,7 @@ fn infer_block(
|
||||
tail: Option<ExprId>,
|
||||
expected: &Expectation,
|
||||
) -> Ty {
|
||||
let mut diverges = false;
|
||||
for stmt in statements {
|
||||
match stmt {
|
||||
Statement::Let { pat, type_ref, initializer } => {
|
||||
@ -1623,16 +1624,23 @@ fn infer_block(
|
||||
self.infer_pat(*pat, &ty, BindingMode::default());
|
||||
}
|
||||
Statement::Expr(expr) => {
|
||||
self.infer_expr(*expr, &Expectation::none());
|
||||
if let ty_app!(TypeCtor::Never) = self.infer_expr(*expr, &Expectation::none()) {
|
||||
diverges = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(expr) = tail {
|
||||
let ty = if let Some(expr) = tail {
|
||||
self.infer_expr_coerce(expr, expected)
|
||||
} else {
|
||||
self.coerce(&Ty::unit(), &expected.ty);
|
||||
Ty::unit()
|
||||
};
|
||||
if diverges {
|
||||
Ty::simple(TypeCtor::Never)
|
||||
} else {
|
||||
ty
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,7 +218,7 @@ fn test(a: u32, b: isize, c: !, d: &str) {
|
||||
[17; 18) 'b': isize
|
||||
[27; 28) 'c': !
|
||||
[33; 34) 'd': &str
|
||||
[42; 121) '{ ...f32; }': ()
|
||||
[42; 121) '{ ...f32; }': !
|
||||
[48; 49) 'a': u32
|
||||
[55; 56) 'b': isize
|
||||
[62; 63) 'c': !
|
||||
@ -980,6 +980,67 @@ fn main(foo: Foo) {
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_if_match_with_return() {
|
||||
assert_snapshot!(
|
||||
infer(r#"
|
||||
fn foo() {
|
||||
let _x1 = if true {
|
||||
1
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
let _x2 = if true {
|
||||
2
|
||||
} else {
|
||||
return
|
||||
};
|
||||
let _x3 = match true {
|
||||
true => 3,
|
||||
_ => {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let _x4 = match true {
|
||||
true => 4,
|
||||
_ => return
|
||||
};
|
||||
}"#),
|
||||
@r###"
|
||||
[10; 323) '{ ... }; }': ()
|
||||
[20; 23) '_x1': i32
|
||||
[26; 80) 'if tru... }': i32
|
||||
[29; 33) 'true': bool
|
||||
[34; 51) '{ ... }': i32
|
||||
[44; 45) '1': i32
|
||||
[57; 80) '{ ... }': !
|
||||
[67; 73) 'return': !
|
||||
[90; 93) '_x2': i32
|
||||
[96; 149) 'if tru... }': i32
|
||||
[99; 103) 'true': bool
|
||||
[104; 121) '{ ... }': i32
|
||||
[114; 115) '2': i32
|
||||
[127; 149) '{ ... }': !
|
||||
[137; 143) 'return': !
|
||||
[159; 162) '_x3': i32
|
||||
[165; 247) 'match ... }': i32
|
||||
[171; 175) 'true': bool
|
||||
[186; 190) 'true': bool
|
||||
[194; 195) '3': i32
|
||||
[205; 206) '_': bool
|
||||
[210; 241) '{ ... }': !
|
||||
[224; 230) 'return': !
|
||||
[257; 260) '_x4': i32
|
||||
[263; 320) 'match ... }': i32
|
||||
[269; 273) 'true': bool
|
||||
[284; 288) 'true': bool
|
||||
[292; 293) '4': i32
|
||||
[303; 304) '_': bool
|
||||
[308; 314) 'return': !
|
||||
"###
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn infer_inherent_method() {
|
||||
assert_snapshot!(
|
||||
|
Loading…
Reference in New Issue
Block a user