aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/body
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2020-12-23 15:34:30 +0000
committerLukas Wirth <[email protected]>2020-12-24 11:49:40 +0000
commit262b9c39824b58068d89d6c5cf53d8fea782b11c (patch)
tree529758599e9c7b4b229d99676e884bb8eaf484a8 /crates/hir_def/src/body
parentfd1fcf2c2e90ab04103a6aa9d033ec64dcc8d555 (diff)
Track labels in the HIR
Diffstat (limited to 'crates/hir_def/src/body')
-rw-r--r--crates/hir_def/src/body/lower.rs92
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 978c3a324..e1de39d0c 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
23use crate::{ 23use 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());
@@ -249,16 +266,12 @@ impl ExprCollector<'_> {
249 }, 266 },
250 ast::Expr::BlockExpr(e) => self.collect_block(e), 267 ast::Expr::BlockExpr(e) => self.collect_block(e),
251 ast::Expr::LoopExpr(e) => { 268 ast::Expr::LoopExpr(e) => {
269 let label = e.label().map(|label| self.collect_label(label));
252 let body = self.collect_block_opt(e.loop_body()); 270 let body = self.collect_block_opt(e.loop_body());
253 self.alloc_expr( 271 self.alloc_expr(Expr::Loop { body, label }, syntax_ptr)
254 Expr::Loop {
255 body,
256 label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
257 },
258 syntax_ptr,
259 )
260 } 272 }
261 ast::Expr::WhileExpr(e) => { 273 ast::Expr::WhileExpr(e) => {
274 let label = e.label().map(|label| self.collect_label(label));
262 let body = self.collect_block_opt(e.loop_body()); 275 let body = self.collect_block_opt(e.loop_body());
263 276
264 let condition = match e.condition() { 277 let condition = match e.condition() {
@@ -279,42 +292,20 @@ impl ExprCollector<'_> {
279 ]; 292 ];
280 let match_expr = 293 let match_expr =
281 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); 294 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms });
282 return self.alloc_expr( 295 return self
283 Expr::Loop { 296 .alloc_expr(Expr::Loop { body: match_expr, label }, syntax_ptr);
284 body: match_expr,
285 label: e
286 .label()
287 .and_then(|l| l.lifetime())
288 .map(|l| Name::new_lifetime(&l)),
289 },
290 syntax_ptr,
291 );
292 } 297 }
293 }, 298 },
294 }; 299 };
295 300
296 self.alloc_expr( 301 self.alloc_expr(Expr::While { condition, body, label }, syntax_ptr)
297 Expr::While {
298 condition,
299 body,
300 label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
301 },
302 syntax_ptr,
303 )
304 } 302 }
305 ast::Expr::ForExpr(e) => { 303 ast::Expr::ForExpr(e) => {
304 let label = e.label().map(|label| self.collect_label(label));
306 let iterable = self.collect_expr_opt(e.iterable()); 305 let iterable = self.collect_expr_opt(e.iterable());
307 let pat = self.collect_pat_opt(e.pat()); 306 let pat = self.collect_pat_opt(e.pat());
308 let body = self.collect_block_opt(e.loop_body()); 307 let body = self.collect_block_opt(e.loop_body());
309 self.alloc_expr( 308 self.alloc_expr(Expr::For { iterable, pat, body, label }, syntax_ptr)
310 Expr::For {
311 iterable,
312 pat,
313 body,
314 label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
315 },
316 syntax_ptr,
317 )
318 } 309 }
319 ast::Expr::CallExpr(e) => { 310 ast::Expr::CallExpr(e) => {
320 let callee = self.collect_expr_opt(e.expr()); 311 let callee = self.collect_expr_opt(e.expr());
@@ -814,6 +805,13 @@ impl ExprCollector<'_> {
814 } 805 }
815 } 806 }
816 807
808 fn collect_label(&mut self, ast_label: ast::Label) -> LabelId {
809 let label = Label {
810 name: ast_label.lifetime().as_ref().map_or_else(Name::missing, Name::new_lifetime),
811 };
812 self.alloc_label(label, AstPtr::new(&ast_label))
813 }
814
817 fn collect_pat(&mut self, pat: ast::Pat) -> PatId { 815 fn collect_pat(&mut self, pat: ast::Pat) -> PatId {
818 let pattern = match &pat { 816 let pattern = match &pat {
819 ast::Pat::IdentPat(bp) => { 817 ast::Pat::IdentPat(bp) => {