diff options
Diffstat (limited to 'crates/hir_def/src/body')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 92 |
1 files changed, 45 insertions, 47 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 1b98504bb..17c72779b 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -22,13 +22,14 @@ use test_utils::mark; | |||
22 | 22 | ||
23 | use crate::{ | 23 | use crate::{ |
24 | adt::StructKind, | 24 | adt::StructKind, |
25 | body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax}, | 25 | body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax}, |
26 | builtin_type::{BuiltinFloat, BuiltinInt}, | 26 | builtin_type::{BuiltinFloat, BuiltinInt}, |
27 | db::DefDatabase, | 27 | db::DefDatabase, |
28 | diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, | 28 | diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro}, |
29 | expr::{ | 29 | expr::{ |
30 | dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, | 30 | dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Label, |
31 | LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, | 31 | LabelId, Literal, LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, |
32 | Statement, | ||
32 | }, | 33 | }, |
33 | item_scope::BuiltinShadowMode, | 34 | item_scope::BuiltinShadowMode, |
34 | item_tree::{ItemTree, ItemTreeId, ItemTreeNode}, | 35 | item_tree::{ItemTree, ItemTreeId, ItemTreeNode}, |
@@ -72,6 +73,7 @@ pub(super) fn lower( | |||
72 | body: Body { | 73 | body: Body { |
73 | exprs: Arena::default(), | 74 | exprs: Arena::default(), |
74 | pats: Arena::default(), | 75 | pats: Arena::default(), |
76 | labels: Arena::default(), | ||
75 | params: Vec::new(), | 77 | params: Vec::new(), |
76 | body_expr: dummy_expr_id(), | 78 | body_expr: dummy_expr_id(), |
77 | item_scope: Default::default(), | 79 | item_scope: Default::default(), |
@@ -175,6 +177,18 @@ impl ExprCollector<'_> { | |||
175 | id | 177 | id |
176 | } | 178 | } |
177 | 179 | ||
180 | fn alloc_label(&mut self, label: Label, ptr: AstPtr<ast::Label>) -> LabelId { | ||
181 | let src = self.expander.to_source(ptr); | ||
182 | let id = self.make_label(label, src.clone()); | ||
183 | self.source_map.label_map.insert(src, id); | ||
184 | id | ||
185 | } | ||
186 | fn make_label(&mut self, label: Label, src: LabelSource) -> LabelId { | ||
187 | let id = self.body.labels.alloc(label); | ||
188 | self.source_map.label_map_back.insert(id, src); | ||
189 | id | ||
190 | } | ||
191 | |||
178 | fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { | 192 | fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { |
179 | let syntax_ptr = AstPtr::new(&expr); | 193 | let syntax_ptr = AstPtr::new(&expr); |
180 | if self.check_cfg(&expr).is_none() { | 194 | if self.check_cfg(&expr).is_none() { |
@@ -228,19 +242,22 @@ impl ExprCollector<'_> { | |||
228 | self.alloc_expr(Expr::Unsafe { body }, syntax_ptr) | 242 | self.alloc_expr(Expr::Unsafe { body }, syntax_ptr) |
229 | } | 243 | } |
230 | // FIXME: we need to record these effects somewhere... | 244 | // FIXME: we need to record these effects somewhere... |
231 | ast::Effect::Label(label) => match e.block_expr() { | 245 | ast::Effect::Label(label) => { |
232 | Some(block) => { | 246 | let label = self.collect_label(label); |
233 | let res = self.collect_block(block); | 247 | match e.block_expr() { |
234 | match &mut self.body.exprs[res] { | 248 | Some(block) => { |
235 | Expr::Block { label: block_label, .. } => { | 249 | let res = self.collect_block(block); |
236 | *block_label = label.lifetime().map(|t| Name::new_lifetime(&t)) | 250 | match &mut self.body.exprs[res] { |
251 | Expr::Block { label: block_label, .. } => { | ||
252 | *block_label = Some(label); | ||
253 | } | ||
254 | _ => unreachable!(), | ||
237 | } | 255 | } |
238 | _ => unreachable!(), | 256 | res |
239 | } | 257 | } |
240 | res | 258 | None => self.missing_expr(), |
241 | } | 259 | } |
242 | None => self.missing_expr(), | 260 | } |
243 | }, | ||
244 | // FIXME: we need to record these effects somewhere... | 261 | // FIXME: we need to record these effects somewhere... |
245 | ast::Effect::Async(_) => { | 262 | ast::Effect::Async(_) => { |
246 | let body = self.collect_block_opt(e.block_expr()); | 263 | let body = self.collect_block_opt(e.block_expr()); |
@@ -253,16 +270,12 @@ impl ExprCollector<'_> { | |||
253 | }, | 270 | }, |
254 | ast::Expr::BlockExpr(e) => self.collect_block(e), | 271 | ast::Expr::BlockExpr(e) => self.collect_block(e), |
255 | ast::Expr::LoopExpr(e) => { | 272 | ast::Expr::LoopExpr(e) => { |
273 | let label = e.label().map(|label| self.collect_label(label)); | ||
256 | let body = self.collect_block_opt(e.loop_body()); | 274 | let body = self.collect_block_opt(e.loop_body()); |
257 | self.alloc_expr( | 275 | self.alloc_expr(Expr::Loop { body, label }, syntax_ptr) |
258 | Expr::Loop { | ||
259 | body, | ||
260 | label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)), | ||
261 | }, | ||
262 | syntax_ptr, | ||
263 | ) | ||
264 | } | 276 | } |
265 | ast::Expr::WhileExpr(e) => { | 277 | ast::Expr::WhileExpr(e) => { |
278 | let label = e.label().map(|label| self.collect_label(label)); | ||
266 | let body = self.collect_block_opt(e.loop_body()); | 279 | let body = self.collect_block_opt(e.loop_body()); |
267 | 280 | ||
268 | let condition = match e.condition() { | 281 | let condition = match e.condition() { |
@@ -283,42 +296,20 @@ impl ExprCollector<'_> { | |||
283 | ]; | 296 | ]; |
284 | let match_expr = | 297 | let match_expr = |
285 | self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); | 298 | self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); |
286 | return self.alloc_expr( | 299 | return self |
287 | Expr::Loop { | 300 | .alloc_expr(Expr::Loop { body: match_expr, label }, syntax_ptr); |
288 | body: match_expr, | ||
289 | label: e | ||
290 | .label() | ||
291 | .and_then(|l| l.lifetime()) | ||
292 | .map(|l| Name::new_lifetime(&l)), | ||
293 | }, | ||
294 | syntax_ptr, | ||
295 | ); | ||
296 | } | 301 | } |
297 | }, | 302 | }, |
298 | }; | 303 | }; |
299 | 304 | ||
300 | self.alloc_expr( | 305 | self.alloc_expr(Expr::While { condition, body, label }, syntax_ptr) |
301 | Expr::While { | ||
302 | condition, | ||
303 | body, | ||
304 | label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)), | ||
305 | }, | ||
306 | syntax_ptr, | ||
307 | ) | ||
308 | } | 306 | } |
309 | ast::Expr::ForExpr(e) => { | 307 | ast::Expr::ForExpr(e) => { |
308 | let label = e.label().map(|label| self.collect_label(label)); | ||
310 | let iterable = self.collect_expr_opt(e.iterable()); | 309 | let iterable = self.collect_expr_opt(e.iterable()); |
311 | let pat = self.collect_pat_opt(e.pat()); | 310 | let pat = self.collect_pat_opt(e.pat()); |
312 | let body = self.collect_block_opt(e.loop_body()); | 311 | let body = self.collect_block_opt(e.loop_body()); |
313 | self.alloc_expr( | 312 | self.alloc_expr(Expr::For { iterable, pat, body, label }, syntax_ptr) |
314 | Expr::For { | ||
315 | iterable, | ||
316 | pat, | ||
317 | body, | ||
318 | label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)), | ||
319 | }, | ||
320 | syntax_ptr, | ||
321 | ) | ||
322 | } | 313 | } |
323 | ast::Expr::CallExpr(e) => { | 314 | ast::Expr::CallExpr(e) => { |
324 | let callee = self.collect_expr_opt(e.expr()); | 315 | let callee = self.collect_expr_opt(e.expr()); |
@@ -818,6 +809,13 @@ impl ExprCollector<'_> { | |||
818 | } | 809 | } |
819 | } | 810 | } |
820 | 811 | ||
812 | fn collect_label(&mut self, ast_label: ast::Label) -> LabelId { | ||
813 | let label = Label { | ||
814 | name: ast_label.lifetime().as_ref().map_or_else(Name::missing, Name::new_lifetime), | ||
815 | }; | ||
816 | self.alloc_label(label, AstPtr::new(&ast_label)) | ||
817 | } | ||
818 | |||
821 | fn collect_pat(&mut self, pat: ast::Pat) -> PatId { | 819 | fn collect_pat(&mut self, pat: ast::Pat) -> PatId { |
822 | let pattern = match &pat { | 820 | let pattern = match &pat { |
823 | ast::Pat::IdentPat(bp) => { | 821 | ast::Pat::IdentPat(bp) => { |