aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/body
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/body')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs56
-rw-r--r--crates/ra_hir_def/src/body/scope.rs4
2 files changed, 47 insertions, 13 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 905c0cf5d..dc52c6bd9 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -134,7 +134,7 @@ impl ExprCollector<'_> {
134 self.make_expr(expr, Err(SyntheticSyntax)) 134 self.make_expr(expr, Err(SyntheticSyntax))
135 } 135 }
136 fn empty_block(&mut self) -> ExprId { 136 fn empty_block(&mut self) -> ExprId {
137 self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None }) 137 self.alloc_expr_desugared(Expr::Block { statements: Vec::new(), tail: None, label: None })
138 } 138 }
139 fn missing_expr(&mut self) -> ExprId { 139 fn missing_expr(&mut self) -> ExprId {
140 self.alloc_expr_desugared(Expr::Missing) 140 self.alloc_expr_desugared(Expr::Missing)
@@ -215,7 +215,13 @@ impl ExprCollector<'_> {
215 ast::Expr::BlockExpr(e) => self.collect_block(e), 215 ast::Expr::BlockExpr(e) => self.collect_block(e),
216 ast::Expr::LoopExpr(e) => { 216 ast::Expr::LoopExpr(e) => {
217 let body = self.collect_block_opt(e.loop_body()); 217 let body = self.collect_block_opt(e.loop_body());
218 self.alloc_expr(Expr::Loop { body }, syntax_ptr) 218 self.alloc_expr(
219 Expr::Loop {
220 body,
221 label: e.label().and_then(|l| l.lifetime_token()).map(|l| Name::new_lifetime(&l)),
222 },
223 syntax_ptr,
224 )
219 } 225 }
220 ast::Expr::WhileExpr(e) => { 226 ast::Expr::WhileExpr(e) => {
221 let body = self.collect_block_opt(e.loop_body()); 227 let body = self.collect_block_opt(e.loop_body());
@@ -230,25 +236,47 @@ impl ExprCollector<'_> {
230 let pat = self.collect_pat(pat); 236 let pat = self.collect_pat(pat);
231 let match_expr = self.collect_expr_opt(condition.expr()); 237 let match_expr = self.collect_expr_opt(condition.expr());
232 let placeholder_pat = self.missing_pat(); 238 let placeholder_pat = self.missing_pat();
233 let break_ = self.alloc_expr_desugared(Expr::Break { expr: None }); 239 let break_ =
240 self.alloc_expr_desugared(Expr::Break { expr: None, label: None });
234 let arms = vec![ 241 let arms = vec![
235 MatchArm { pat, expr: body, guard: None }, 242 MatchArm { pat, expr: body, guard: None },
236 MatchArm { pat: placeholder_pat, expr: break_, guard: None }, 243 MatchArm { pat: placeholder_pat, expr: break_, guard: None },
237 ]; 244 ];
238 let match_expr = 245 let match_expr =
239 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); 246 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms });
240 return self.alloc_expr(Expr::Loop { body: match_expr }, syntax_ptr); 247 return self.alloc_expr(
248 Expr::Loop {
249 body: match_expr,
250 label: e.label().and_then(|l| l.lifetime_token()).map(|l| Name::new_lifetime(&l)),
251 },
252 syntax_ptr,
253 );
241 } 254 }
242 }, 255 },
243 }; 256 };
244 257
245 self.alloc_expr(Expr::While { condition, body }, syntax_ptr) 258 self.alloc_expr(
259 Expr::While {
260 condition,
261 body,
262 label: e.label().and_then(|l| l.lifetime_token()).map(|l| Name::new_lifetime(&l)),
263 },
264 syntax_ptr,
265 )
246 } 266 }
247 ast::Expr::ForExpr(e) => { 267 ast::Expr::ForExpr(e) => {
248 let iterable = self.collect_expr_opt(e.iterable()); 268 let iterable = self.collect_expr_opt(e.iterable());
249 let pat = self.collect_pat_opt(e.pat()); 269 let pat = self.collect_pat_opt(e.pat());
250 let body = self.collect_block_opt(e.loop_body()); 270 let body = self.collect_block_opt(e.loop_body());
251 self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr) 271 self.alloc_expr(
272 Expr::For {
273 iterable,
274 pat,
275 body,
276 label: e.label().and_then(|l| l.lifetime_token()).map(|l| Name::new_lifetime(&l)),
277 },
278 syntax_ptr,
279 )
252 } 280 }
253 ast::Expr::CallExpr(e) => { 281 ast::Expr::CallExpr(e) => {
254 let callee = self.collect_expr_opt(e.expr()); 282 let callee = self.collect_expr_opt(e.expr());
@@ -301,13 +329,18 @@ impl ExprCollector<'_> {
301 .unwrap_or(Expr::Missing); 329 .unwrap_or(Expr::Missing);
302 self.alloc_expr(path, syntax_ptr) 330 self.alloc_expr(path, syntax_ptr)
303 } 331 }
304 ast::Expr::ContinueExpr(_e) => { 332 ast::Expr::ContinueExpr(e) => {
305 // FIXME: labels 333 self.alloc_expr(
306 self.alloc_expr(Expr::Continue, syntax_ptr) 334 Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) },
335 syntax_ptr,
336 )
307 } 337 }
308 ast::Expr::BreakExpr(e) => { 338 ast::Expr::BreakExpr(e) => {
309 let expr = e.expr().map(|e| self.collect_expr(e)); 339 let expr = e.expr().map(|e| self.collect_expr(e));
310 self.alloc_expr(Expr::Break { expr }, syntax_ptr) 340 self.alloc_expr(
341 Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) },
342 syntax_ptr,
343 )
311 } 344 }
312 ast::Expr::ParenExpr(e) => { 345 ast::Expr::ParenExpr(e) => {
313 let inner = self.collect_expr_opt(e.expr()); 346 let inner = self.collect_expr_opt(e.expr());
@@ -529,7 +562,8 @@ impl ExprCollector<'_> {
529 }) 562 })
530 .collect(); 563 .collect();
531 let tail = block.expr().map(|e| self.collect_expr(e)); 564 let tail = block.expr().map(|e| self.collect_expr(e));
532 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 565 let label = block.label().and_then(|l| l.lifetime_token()).map(|t| Name::new_lifetime(&t));
566 self.alloc_expr(Expr::Block { statements, tail, label }, syntax_node_ptr)
533 } 567 }
534 568
535 fn collect_block_items(&mut self, block: &ast::BlockExpr) { 569 fn collect_block_items(&mut self, block: &ast::BlockExpr) {
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index 09e92b74e..e48ff38f9 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -138,10 +138,10 @@ fn compute_block_scopes(
138fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) { 138fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) {
139 scopes.set_scope(expr, scope); 139 scopes.set_scope(expr, scope);
140 match &body[expr] { 140 match &body[expr] {
141 Expr::Block { statements, tail } => { 141 Expr::Block { statements, tail, .. } => {
142 compute_block_scopes(&statements, *tail, body, scopes, scope); 142 compute_block_scopes(&statements, *tail, body, scopes, scope);
143 } 143 }
144 Expr::For { iterable, pat, body: body_expr } => { 144 Expr::For { iterable, pat, body: body_expr, .. } => {
145 compute_expr_scopes(*iterable, body, scopes, scope); 145 compute_expr_scopes(*iterable, body, scopes, scope);
146 let scope = scopes.new_scope(scope); 146 let scope = scopes.new_scope(scope);
147 scopes.add_bindings(body, scope, *pat); 147 scopes.add_bindings(body, scope, *pat);