diff options
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 68 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/scope.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/expr.rs | 19 |
3 files changed, 71 insertions, 20 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 905c0cf5d..f159f80af 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,16 @@ 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 | ||
222 | .label() | ||
223 | .and_then(|l| l.lifetime_token()) | ||
224 | .map(|l| Name::new_lifetime(&l)), | ||
225 | }, | ||
226 | syntax_ptr, | ||
227 | ) | ||
219 | } | 228 | } |
220 | ast::Expr::WhileExpr(e) => { | 229 | ast::Expr::WhileExpr(e) => { |
221 | let body = self.collect_block_opt(e.loop_body()); | 230 | let body = self.collect_block_opt(e.loop_body()); |
@@ -230,25 +239,56 @@ impl ExprCollector<'_> { | |||
230 | let pat = self.collect_pat(pat); | 239 | let pat = self.collect_pat(pat); |
231 | let match_expr = self.collect_expr_opt(condition.expr()); | 240 | let match_expr = self.collect_expr_opt(condition.expr()); |
232 | let placeholder_pat = self.missing_pat(); | 241 | let placeholder_pat = self.missing_pat(); |
233 | let break_ = self.alloc_expr_desugared(Expr::Break { expr: None }); | 242 | let break_ = |
243 | self.alloc_expr_desugared(Expr::Break { expr: None, label: None }); | ||
234 | let arms = vec![ | 244 | let arms = vec![ |
235 | MatchArm { pat, expr: body, guard: None }, | 245 | MatchArm { pat, expr: body, guard: None }, |
236 | MatchArm { pat: placeholder_pat, expr: break_, guard: None }, | 246 | MatchArm { pat: placeholder_pat, expr: break_, guard: None }, |
237 | ]; | 247 | ]; |
238 | let match_expr = | 248 | let match_expr = |
239 | self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); | 249 | self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); |
240 | return self.alloc_expr(Expr::Loop { body: match_expr }, syntax_ptr); | 250 | return self.alloc_expr( |
251 | Expr::Loop { | ||
252 | body: match_expr, | ||
253 | label: e | ||
254 | .label() | ||
255 | .and_then(|l| l.lifetime_token()) | ||
256 | .map(|l| Name::new_lifetime(&l)), | ||
257 | }, | ||
258 | syntax_ptr, | ||
259 | ); | ||
241 | } | 260 | } |
242 | }, | 261 | }, |
243 | }; | 262 | }; |
244 | 263 | ||
245 | self.alloc_expr(Expr::While { condition, body }, syntax_ptr) | 264 | self.alloc_expr( |
265 | Expr::While { | ||
266 | condition, | ||
267 | body, | ||
268 | label: e | ||
269 | .label() | ||
270 | .and_then(|l| l.lifetime_token()) | ||
271 | .map(|l| Name::new_lifetime(&l)), | ||
272 | }, | ||
273 | syntax_ptr, | ||
274 | ) | ||
246 | } | 275 | } |
247 | ast::Expr::ForExpr(e) => { | 276 | ast::Expr::ForExpr(e) => { |
248 | let iterable = self.collect_expr_opt(e.iterable()); | 277 | let iterable = self.collect_expr_opt(e.iterable()); |
249 | let pat = self.collect_pat_opt(e.pat()); | 278 | let pat = self.collect_pat_opt(e.pat()); |
250 | let body = self.collect_block_opt(e.loop_body()); | 279 | let body = self.collect_block_opt(e.loop_body()); |
251 | self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr) | 280 | self.alloc_expr( |
281 | Expr::For { | ||
282 | iterable, | ||
283 | pat, | ||
284 | body, | ||
285 | label: e | ||
286 | .label() | ||
287 | .and_then(|l| l.lifetime_token()) | ||
288 | .map(|l| Name::new_lifetime(&l)), | ||
289 | }, | ||
290 | syntax_ptr, | ||
291 | ) | ||
252 | } | 292 | } |
253 | ast::Expr::CallExpr(e) => { | 293 | ast::Expr::CallExpr(e) => { |
254 | let callee = self.collect_expr_opt(e.expr()); | 294 | let callee = self.collect_expr_opt(e.expr()); |
@@ -301,13 +341,16 @@ impl ExprCollector<'_> { | |||
301 | .unwrap_or(Expr::Missing); | 341 | .unwrap_or(Expr::Missing); |
302 | self.alloc_expr(path, syntax_ptr) | 342 | self.alloc_expr(path, syntax_ptr) |
303 | } | 343 | } |
304 | ast::Expr::ContinueExpr(_e) => { | 344 | ast::Expr::ContinueExpr(e) => self.alloc_expr( |
305 | // FIXME: labels | 345 | Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, |
306 | self.alloc_expr(Expr::Continue, syntax_ptr) | 346 | syntax_ptr, |
307 | } | 347 | ), |
308 | ast::Expr::BreakExpr(e) => { | 348 | ast::Expr::BreakExpr(e) => { |
309 | let expr = e.expr().map(|e| self.collect_expr(e)); | 349 | let expr = e.expr().map(|e| self.collect_expr(e)); |
310 | self.alloc_expr(Expr::Break { expr }, syntax_ptr) | 350 | self.alloc_expr( |
351 | Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, | ||
352 | syntax_ptr, | ||
353 | ) | ||
311 | } | 354 | } |
312 | ast::Expr::ParenExpr(e) => { | 355 | ast::Expr::ParenExpr(e) => { |
313 | let inner = self.collect_expr_opt(e.expr()); | 356 | let inner = self.collect_expr_opt(e.expr()); |
@@ -529,7 +572,8 @@ impl ExprCollector<'_> { | |||
529 | }) | 572 | }) |
530 | .collect(); | 573 | .collect(); |
531 | let tail = block.expr().map(|e| self.collect_expr(e)); | 574 | let tail = block.expr().map(|e| self.collect_expr(e)); |
532 | self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) | 575 | let label = block.label().and_then(|l| l.lifetime_token()).map(|t| Name::new_lifetime(&t)); |
576 | self.alloc_expr(Expr::Block { statements, tail, label }, syntax_node_ptr) | ||
533 | } | 577 | } |
534 | 578 | ||
535 | fn collect_block_items(&mut self, block: &ast::BlockExpr) { | 579 | 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( | |||
138 | fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope: ScopeId) { | 138 | fn 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); |
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index f25c6f958..ca49b26d1 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs | |||
@@ -52,18 +52,22 @@ pub enum Expr { | |||
52 | Block { | 52 | Block { |
53 | statements: Vec<Statement>, | 53 | statements: Vec<Statement>, |
54 | tail: Option<ExprId>, | 54 | tail: Option<ExprId>, |
55 | label: Option<Name>, | ||
55 | }, | 56 | }, |
56 | Loop { | 57 | Loop { |
57 | body: ExprId, | 58 | body: ExprId, |
59 | label: Option<Name>, | ||
58 | }, | 60 | }, |
59 | While { | 61 | While { |
60 | condition: ExprId, | 62 | condition: ExprId, |
61 | body: ExprId, | 63 | body: ExprId, |
64 | label: Option<Name>, | ||
62 | }, | 65 | }, |
63 | For { | 66 | For { |
64 | iterable: ExprId, | 67 | iterable: ExprId, |
65 | pat: PatId, | 68 | pat: PatId, |
66 | body: ExprId, | 69 | body: ExprId, |
70 | label: Option<Name>, | ||
67 | }, | 71 | }, |
68 | Call { | 72 | Call { |
69 | callee: ExprId, | 73 | callee: ExprId, |
@@ -79,9 +83,12 @@ pub enum Expr { | |||
79 | expr: ExprId, | 83 | expr: ExprId, |
80 | arms: Vec<MatchArm>, | 84 | arms: Vec<MatchArm>, |
81 | }, | 85 | }, |
82 | Continue, | 86 | Continue { |
87 | label: Option<Name>, | ||
88 | }, | ||
83 | Break { | 89 | Break { |
84 | expr: Option<ExprId>, | 90 | expr: Option<ExprId>, |
91 | label: Option<Name>, | ||
85 | }, | 92 | }, |
86 | Return { | 93 | Return { |
87 | expr: Option<ExprId>, | 94 | expr: Option<ExprId>, |
@@ -225,7 +232,7 @@ impl Expr { | |||
225 | f(*else_branch); | 232 | f(*else_branch); |
226 | } | 233 | } |
227 | } | 234 | } |
228 | Expr::Block { statements, tail } => { | 235 | Expr::Block { statements, tail, .. } => { |
229 | for stmt in statements { | 236 | for stmt in statements { |
230 | match stmt { | 237 | match stmt { |
231 | Statement::Let { initializer, .. } => { | 238 | Statement::Let { initializer, .. } => { |
@@ -241,8 +248,8 @@ impl Expr { | |||
241 | } | 248 | } |
242 | } | 249 | } |
243 | Expr::TryBlock { body } => f(*body), | 250 | Expr::TryBlock { body } => f(*body), |
244 | Expr::Loop { body } => f(*body), | 251 | Expr::Loop { body, .. } => f(*body), |
245 | Expr::While { condition, body } => { | 252 | Expr::While { condition, body, .. } => { |
246 | f(*condition); | 253 | f(*condition); |
247 | f(*body); | 254 | f(*body); |
248 | } | 255 | } |
@@ -268,8 +275,8 @@ impl Expr { | |||
268 | f(arm.expr); | 275 | f(arm.expr); |
269 | } | 276 | } |
270 | } | 277 | } |
271 | Expr::Continue => {} | 278 | Expr::Continue { .. } => {} |
272 | Expr::Break { expr } | Expr::Return { expr } => { | 279 | Expr::Break { expr, .. } | Expr::Return { expr } => { |
273 | if let Some(expr) = expr { | 280 | if let Some(expr) = expr { |
274 | f(*expr); | 281 | f(*expr); |
275 | } | 282 | } |