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:
bors[bot] 2019-10-02 18:57:20 +00:00 committed by GitHub
commit e1c3675951
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 3 deletions

View File

@ -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
}
}

View File

@ -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!(