aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2021-02-10 13:41:54 +0000
committerJonas Schievink <[email protected]>2021-02-10 13:41:54 +0000
commite837df84792d2cbf5c606788c7cab7ea4d1829d0 (patch)
tree7b9b4e4523803432d157220199a4a11c4821c471
parent82a1b91f205ac9c3d397b2bea033639f5df9e6b6 (diff)
infer: update resolver when descending into block
-rw-r--r--crates/hir_ty/src/infer/expr.rs36
-rw-r--r--crates/hir_ty/src/tests/simple.rs19
2 files changed, 39 insertions, 16 deletions
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 12f1591c8..d05c715e7 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -137,24 +137,28 @@ impl<'a> InferenceContext<'a> {
137 137
138 self.coerce_merge_branch(&then_ty, &else_ty) 138 self.coerce_merge_branch(&then_ty, &else_ty)
139 } 139 }
140 Expr::Block { statements, tail, label, id: _ } => match label { 140 Expr::Block { statements, tail, label, id: _ } => {
141 Some(_) => { 141 self.resolver = resolver_for_expr(self.db.upcast(), self.owner, tgt_expr);
142 let break_ty = self.table.new_type_var(); 142 match label {
143 self.breakables.push(BreakableContext { 143 Some(_) => {
144 may_break: false, 144 let break_ty = self.table.new_type_var();
145 break_ty: break_ty.clone(), 145 self.breakables.push(BreakableContext {
146 label: label.map(|label| self.body[label].name.clone()), 146 may_break: false,
147 }); 147 break_ty: break_ty.clone(),
148 let ty = self.infer_block(statements, *tail, &Expectation::has_type(break_ty)); 148 label: label.map(|label| self.body[label].name.clone()),
149 let ctxt = self.breakables.pop().expect("breakable stack broken"); 149 });
150 if ctxt.may_break { 150 let ty =
151 ctxt.break_ty 151 self.infer_block(statements, *tail, &Expectation::has_type(break_ty));
152 } else { 152 let ctxt = self.breakables.pop().expect("breakable stack broken");
153 ty 153 if ctxt.may_break {
154 ctxt.break_ty
155 } else {
156 ty
157 }
154 } 158 }
159 None => self.infer_block(statements, *tail, expected),
155 } 160 }
156 None => self.infer_block(statements, *tail, expected), 161 }
157 },
158 Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected), 162 Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected),
159 Expr::TryBlock { body } => { 163 Expr::TryBlock { body } => {
160 let _inner = self.infer_expr(*body, expected); 164 let _inner = self.infer_expr(*body, expected);
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 16682f76f..ab21332fb 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -2415,3 +2415,22 @@ fn infer_const_params() {
2415 "#]], 2415 "#]],
2416 ); 2416 );
2417} 2417}
2418
2419#[test]
2420fn infer_inner_type() {
2421 check_infer(r#"
2422 fn foo() {
2423 struct S { field: u32 }
2424 let s = S { field: 0 };
2425 let f = s.field;
2426 }
2427 "#, expect![[r#"
2428 9..89 '{ ...eld; }': ()
2429 47..48 's': S
2430 51..65 'S { field: 0 }': S
2431 62..63 '0': u32
2432 75..76 'f': u32
2433 79..80 's': S
2434 79..86 's.field': u32
2435 "#]]);
2436}