Correctly infer types in guard expressions

The root cause was that we forgot to add bindings from the arm to the
guard expression

closes #3980
This commit is contained in:
Aleksey Kladov 2020-04-18 22:16:04 +02:00
parent fa2ea8f494
commit b79fd82559
2 changed files with 30 additions and 0 deletions

View File

@ -157,6 +157,10 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
for arm in arms {
let scope = scopes.new_scope(scope);
scopes.add_bindings(body, scope, arm.pat);
if let Some(guard) = arm.guard {
scopes.set_scope(guard, scope);
compute_expr_scopes(guard, body, scopes, scope);
}
scopes.set_scope(arm.expr, scope);
compute_expr_scopes(arm.expr, body, scopes, scope);
}

View File

@ -455,3 +455,29 @@ fn test() {
"###
);
}
#[test]
fn infer_guard() {
assert_snapshot!(
infer(r#"
struct S;
impl S { fn foo(&self) -> bool { false } }
fn main() {
match S {
s if s.foo() => (),
}
}
"#), @"
[28; 32) 'self': &S
[42; 51) '{ false }': bool
[44; 49) 'false': bool
[65; 116) '{ ... } }': ()
[71; 114) 'match ... }': ()
[77; 78) 'S': S
[89; 90) 's': S
[94; 95) 's': S
[94; 101) 's.foo()': bool
[105; 107) '()': ()
")
}