diff options
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 237 |
2 files changed, 158 insertions, 81 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 076d1a4fa..14a1f4773 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -184,7 +184,7 @@ pub struct Body { | |||
184 | /// The `ExprId` of the actual body expression. | 184 | /// The `ExprId` of the actual body expression. |
185 | pub body_expr: ExprId, | 185 | pub body_expr: ExprId, |
186 | pub item_scope: ItemScope, | 186 | pub item_scope: ItemScope, |
187 | pub parent_map: FxHashMap<ExprId, ExprId>, | 187 | pub parent_map: ArenaMap<ExprId, ExprId>, |
188 | } | 188 | } |
189 | 189 | ||
190 | pub type ExprPtr = AstPtr<ast::Expr>; | 190 | pub type ExprPtr = AstPtr<ast::Expr>; |
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index a1678adeb..114b38710 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -7,7 +7,7 @@ use hir_expand::{ | |||
7 | name::{name, AsName, Name}, | 7 | name::{name, AsName, Name}, |
8 | HirFileId, MacroDefId, MacroDefKind, | 8 | HirFileId, MacroDefId, MacroDefKind, |
9 | }; | 9 | }; |
10 | use ra_arena::Arena; | 10 | use ra_arena::{map::ArenaMap, Arena}; |
11 | use ra_syntax::{ | 11 | use ra_syntax::{ |
12 | ast::{ | 12 | ast::{ |
13 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner, | 13 | self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner, |
@@ -15,7 +15,6 @@ use ra_syntax::{ | |||
15 | }, | 15 | }, |
16 | AstNode, AstPtr, | 16 | AstNode, AstPtr, |
17 | }; | 17 | }; |
18 | use rustc_hash::FxHashMap; | ||
19 | use test_utils::mark; | 18 | use test_utils::mark; |
20 | 19 | ||
21 | use crate::{ | 20 | use crate::{ |
@@ -75,7 +74,7 @@ pub(super) fn lower( | |||
75 | params: Vec::new(), | 74 | params: Vec::new(), |
76 | body_expr: dummy_expr_id(), | 75 | body_expr: dummy_expr_id(), |
77 | item_scope: Default::default(), | 76 | item_scope: Default::default(), |
78 | parent_map: FxHashMap::default(), | 77 | parent_map: ArenaMap::default(), |
79 | }, | 78 | }, |
80 | item_trees: { | 79 | item_trees: { |
81 | let mut map = FxHashMap::default(); | 80 | let mut map = FxHashMap::default(); |
@@ -97,6 +96,40 @@ struct ExprCollector<'a> { | |||
97 | item_trees: FxHashMap<HirFileId, Arc<ItemTree>>, | 96 | item_trees: FxHashMap<HirFileId, Arc<ItemTree>>, |
98 | } | 97 | } |
99 | 98 | ||
99 | macro_rules! track_parent { | ||
100 | (@build $collector:ident, $parent:expr $(,)?) => { | ||
101 | $parent | ||
102 | }; | ||
103 | (@build $collector:ident, $parent:expr, opt $expr:ident $($rest:tt)*) => { | ||
104 | { | ||
105 | if let Some(expr) = $expr { | ||
106 | $collector.body.parent_map.insert(expr, $parent); | ||
107 | } | ||
108 | track_parent!(@build $collector, $parent $($rest)*) | ||
109 | } | ||
110 | }; | ||
111 | (@build $collector:ident, $parent:expr, vec $expr:ident $($rest:tt)*) => { | ||
112 | { | ||
113 | for expr in $expr { | ||
114 | $collector.body.parent_map.insert(expr, $parent); | ||
115 | } | ||
116 | track_parent!(@build $collector, $parent $($rest)*) | ||
117 | } | ||
118 | }; | ||
119 | (@build $collector:ident, $parent:expr, $expr:ident $($rest:tt)*) => { | ||
120 | { | ||
121 | $collector.body.parent_map.insert($expr, $parent); | ||
122 | track_parent!(@build $collector, $parent $($rest)*) | ||
123 | } | ||
124 | }; | ||
125 | ($collector:ident, $parent:expr, $($rest:tt)*) => { | ||
126 | { | ||
127 | let parent = $parent; | ||
128 | track_parent!(@build $collector, parent, $($rest)*) | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
100 | impl ExprCollector<'_> { | 133 | impl ExprCollector<'_> { |
101 | fn collect( | 134 | fn collect( |
102 | mut self, | 135 | mut self, |
@@ -185,14 +218,42 @@ impl ExprCollector<'_> { | |||
185 | } | 218 | } |
186 | 219 | ||
187 | fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { | 220 | fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { |
188 | let parent_and_children = self.collect_expr_inner(expr); | 221 | let expr_id = self.collect_expr_inner(expr); |
189 | self.update_parent_map(parent_and_children) | 222 | |
223 | debug_assert!({ | ||
224 | let mut found_count = 0; | ||
225 | let mut incr = || { | ||
226 | found_count += 1; | ||
227 | true | ||
228 | }; | ||
229 | let mut all_children_found = true; | ||
230 | self.body[expr_id].walk_child_exprs(|child| { | ||
231 | all_children_found = all_children_found | ||
232 | && self | ||
233 | .body | ||
234 | .parent_map | ||
235 | .get(child) | ||
236 | .map(|parent| *parent == expr_id) | ||
237 | .unwrap_or(false) | ||
238 | && incr() | ||
239 | }); | ||
240 | |||
241 | if all_children_found { | ||
242 | let child_count_in_map = | ||
243 | self.body.parent_map.iter().filter(|&(_, parent)| *parent == expr_id).count(); | ||
244 | found_count == child_count_in_map | ||
245 | } else { | ||
246 | false | ||
247 | } | ||
248 | }); | ||
249 | |||
250 | expr_id | ||
190 | } | 251 | } |
191 | 252 | ||
192 | fn collect_expr_inner(&mut self, expr: ast::Expr) -> (ExprId, Vec<ExprId>) { | 253 | fn collect_expr_inner(&mut self, expr: ast::Expr) -> ExprId { |
193 | let syntax_ptr = AstPtr::new(&expr); | 254 | let syntax_ptr = AstPtr::new(&expr); |
194 | if !self.expander.is_cfg_enabled(&expr) { | 255 | if !self.expander.is_cfg_enabled(&expr) { |
195 | return (self.missing_expr(), vec![]); | 256 | return self.missing_expr(); |
196 | } | 257 | } |
197 | 258 | ||
198 | match expr { | 259 | match expr { |
@@ -224,48 +285,40 @@ impl ExprCollector<'_> { | |||
224 | guard: None, | 285 | guard: None, |
225 | }, | 286 | }, |
226 | ]; | 287 | ]; |
227 | let children_exprs = if let Some(else_branch) = else_branch { | 288 | let arm_exprs = arms.iter().map(|arm| arm.expr).collect::<Vec<_>>(); |
228 | vec![match_expr, then_branch, else_branch] | 289 | return track_parent!( |
229 | } else { | 290 | self, |
230 | vec![match_expr, then_branch] | ||
231 | }; | ||
232 | return ( | ||
233 | self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr), | 291 | self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr), |
234 | children_exprs, | 292 | match_expr, vec arm_exprs |
235 | ); | 293 | ); |
236 | } | 294 | } |
237 | }, | 295 | }, |
238 | }; | 296 | }; |
239 | 297 | ||
240 | let children_exprs = if let Some(else_branch) = else_branch { | 298 | track_parent!( |
241 | vec![then_branch, else_branch, condition] | 299 | self, |
242 | } else { | ||
243 | vec![then_branch, condition] | ||
244 | }; | ||
245 | |||
246 | ( | ||
247 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr), | 300 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr), |
248 | children_exprs, | 301 | then_branch, opt else_branch, condition |
249 | ) | 302 | ) |
250 | } | 303 | } |
251 | ast::Expr::EffectExpr(e) => match e.effect() { | 304 | ast::Expr::EffectExpr(e) => match e.effect() { |
252 | ast::Effect::Try(_) => { | 305 | ast::Effect::Try(_) => { |
253 | let body = self.collect_block_opt(e.block_expr()); | 306 | let body = self.collect_block_opt(e.block_expr()); |
254 | (self.alloc_expr(Expr::TryBlock { body }, syntax_ptr), vec![body]) | 307 | track_parent!(self, self.alloc_expr(Expr::TryBlock { body }, syntax_ptr), body) |
255 | } | 308 | } |
256 | ast::Effect::Unsafe(_) => { | 309 | ast::Effect::Unsafe(_) => { |
257 | let body = self.collect_block_opt(e.block_expr()); | 310 | let body = self.collect_block_opt(e.block_expr()); |
258 | (self.alloc_expr(Expr::Unsafe { body }, syntax_ptr), vec![body]) | 311 | track_parent!(self, self.alloc_expr(Expr::Unsafe { body }, syntax_ptr), body) |
259 | } | 312 | } |
260 | // FIXME: we need to record these effects somewhere... | 313 | // FIXME: we need to record these effects somewhere... |
261 | ast::Effect::Async(_) | ast::Effect::Label(_) => { | 314 | ast::Effect::Async(_) | ast::Effect::Label(_) => { |
262 | (self.collect_block_opt(e.block_expr()), vec![]) | 315 | self.collect_block_opt(e.block_expr()) |
263 | } | 316 | } |
264 | }, | 317 | }, |
265 | ast::Expr::BlockExpr(e) => (self.collect_block(e), vec![]), | 318 | ast::Expr::BlockExpr(e) => self.collect_block(e), |
266 | ast::Expr::LoopExpr(e) => { | 319 | ast::Expr::LoopExpr(e) => { |
267 | let body = self.collect_block_opt(e.loop_body()); | 320 | let body = self.collect_block_opt(e.loop_body()); |
268 | (self.alloc_expr( | 321 | track_parent!(self, self.alloc_expr(Expr::Loop { body }, syntax_ptr), vec![body]) |
269 | Expr::Loop { | 322 | Expr::Loop { |
270 | body, | 323 | body, |
271 | label: e | 324 | label: e |
@@ -274,7 +327,7 @@ impl ExprCollector<'_> { | |||
274 | .map(|l| Name::new_lifetime(&l)), | 327 | .map(|l| Name::new_lifetime(&l)), |
275 | }, | 328 | }, |
276 | syntax_ptr, | 329 | syntax_ptr, |
277 | ), vec![body]) | 330 | ), body) |
278 | } | 331 | } |
279 | ast::Expr::WhileExpr(e) => { | 332 | ast::Expr::WhileExpr(e) => { |
280 | let body = self.collect_block_opt(e.loop_body()); | 333 | let body = self.collect_block_opt(e.loop_body()); |
@@ -285,7 +338,6 @@ impl ExprCollector<'_> { | |||
285 | None => self.collect_expr_opt(condition.expr()), | 338 | None => self.collect_expr_opt(condition.expr()), |
286 | // if let -- desugar to match | 339 | // if let -- desugar to match |
287 | Some(pat) => { | 340 | Some(pat) => { |
288 | // FIXME(pfaria) track the break and arms parents here? | ||
289 | mark::hit!(infer_resolve_while_let); | 341 | mark::hit!(infer_resolve_while_let); |
290 | let pat = self.collect_pat(pat); | 342 | let pat = self.collect_pat(pat); |
291 | let match_expr = self.collect_expr_opt(condition.expr()); | 343 | let match_expr = self.collect_expr_opt(condition.expr()); |
@@ -298,7 +350,7 @@ impl ExprCollector<'_> { | |||
298 | ]; | 350 | ]; |
299 | let match_expr = | 351 | let match_expr = |
300 | self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); | 352 | self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms }); |
301 | return (self.alloc_expr( | 353 | return track_parent!(self, self.alloc_expr( |
302 | Expr::Loop { | 354 | Expr::Loop { |
303 | body: match_expr, | 355 | body: match_expr, |
304 | label: e | 356 | label: e |
@@ -307,12 +359,12 @@ impl ExprCollector<'_> { | |||
307 | .map(|l| Name::new_lifetime(&l)), | 359 | .map(|l| Name::new_lifetime(&l)), |
308 | }, | 360 | }, |
309 | syntax_ptr, | 361 | syntax_ptr, |
310 | ), vec![match_expr]); | 362 | ), match_expr); |
311 | } | 363 | } |
312 | }, | 364 | }, |
313 | }; | 365 | }; |
314 | 366 | ||
315 | (self.alloc_expr( | 367 | track_parent!(self, self.alloc_expr( |
316 | Expr::While { | 368 | Expr::While { |
317 | condition, | 369 | condition, |
318 | body, | 370 | body, |
@@ -322,13 +374,13 @@ impl ExprCollector<'_> { | |||
322 | .map(|l| Name::new_lifetime(&l)), | 374 | .map(|l| Name::new_lifetime(&l)), |
323 | }, | 375 | }, |
324 | syntax_ptr, | 376 | syntax_ptr, |
325 | ), vec![body, condition]) | 377 | ), body, condition) |
326 | } | 378 | } |
327 | ast::Expr::ForExpr(e) => { | 379 | ast::Expr::ForExpr(e) => { |
328 | let iterable = self.collect_expr_opt(e.iterable()); | 380 | let iterable = self.collect_expr_opt(e.iterable()); |
329 | let pat = self.collect_pat_opt(e.pat()); | 381 | let pat = self.collect_pat_opt(e.pat()); |
330 | let body = self.collect_block_opt(e.loop_body()); | 382 | let body = self.collect_block_opt(e.loop_body()); |
331 | (self.alloc_expr( | 383 | track_parent!(self, self.alloc_expr( |
332 | Expr::For { | 384 | Expr::For { |
333 | iterable, | 385 | iterable, |
334 | pat, | 386 | pat, |
@@ -339,7 +391,7 @@ impl ExprCollector<'_> { | |||
339 | .map(|l| Name::new_lifetime(&l)), | 391 | .map(|l| Name::new_lifetime(&l)), |
340 | }, | 392 | }, |
341 | syntax_ptr, | 393 | syntax_ptr, |
342 | ), vec![iterable, body]) | 394 | ), iterable, body) |
343 | } | 395 | } |
344 | ast::Expr::CallExpr(e) => { | 396 | ast::Expr::CallExpr(e) => { |
345 | let callee = self.collect_expr_opt(e.expr()); | 397 | let callee = self.collect_expr_opt(e.expr()); |
@@ -348,9 +400,7 @@ impl ExprCollector<'_> { | |||
348 | } else { | 400 | } else { |
349 | Vec::new() | 401 | Vec::new() |
350 | }; | 402 | }; |
351 | let mut children_exprs = args.clone(); | 403 | track_parent!(self, self.alloc_expr(Expr::Call { callee, args: args.clone() }, syntax_ptr), callee, vec args) |
352 | children_exprs.push(callee); | ||
353 | (self.alloc_expr(Expr::Call { callee, args }, syntax_ptr), children_exprs) | ||
354 | } | 404 | } |
355 | ast::Expr::MethodCallExpr(e) => { | 405 | ast::Expr::MethodCallExpr(e) => { |
356 | let receiver = self.collect_expr_opt(e.expr()); | 406 | let receiver = self.collect_expr_opt(e.expr()); |
@@ -362,19 +412,24 @@ impl ExprCollector<'_> { | |||
362 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); | 412 | let method_name = e.name_ref().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); |
363 | let generic_args = | 413 | let generic_args = |
364 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); | 414 | e.type_arg_list().and_then(|it| GenericArgs::from_ast(&self.ctx(), it)); |
365 | let mut children_exprs = args.clone(); | 415 | track_parent!( |
366 | children_exprs.push(receiver); | 416 | self, |
367 | ( | ||
368 | self.alloc_expr( | 417 | self.alloc_expr( |
369 | Expr::MethodCall { receiver, method_name, args, generic_args }, | 418 | Expr::MethodCall { |
419 | receiver, | ||
420 | method_name, | ||
421 | args: args.clone(), | ||
422 | generic_args | ||
423 | }, | ||
370 | syntax_ptr, | 424 | syntax_ptr, |
371 | ), | 425 | ), |
372 | children_exprs, | 426 | receiver, |
427 | vec args | ||
373 | ) | 428 | ) |
374 | } | 429 | } |
375 | ast::Expr::MatchExpr(e) => { | 430 | ast::Expr::MatchExpr(e) => { |
376 | let expr = self.collect_expr_opt(e.expr()); | 431 | let expr = self.collect_expr_opt(e.expr()); |
377 | let (arms, mut children_exprs): (Vec<_>, Vec<_>) = | 432 | let (arms, children_exprs): (Vec<_>, Vec<_>) = |
378 | if let Some(match_arm_list) = e.match_arm_list() { | 433 | if let Some(match_arm_list) = e.match_arm_list() { |
379 | match_arm_list | 434 | match_arm_list |
380 | .arms() | 435 | .arms() |
@@ -396,8 +451,7 @@ impl ExprCollector<'_> { | |||
396 | } else { | 451 | } else { |
397 | (vec![], vec![]) | 452 | (vec![], vec![]) |
398 | }; | 453 | }; |
399 | children_exprs.push(expr); | 454 | track_parent!(self, self.alloc_expr(Expr::Match { expr, arms: arms.clone() }, syntax_ptr), expr, vec children_exprs) |
400 | (self.alloc_expr(Expr::Match { expr, arms }, syntax_ptr), children_exprs) | ||
401 | } | 455 | } |
402 | ast::Expr::PathExpr(e) => { | 456 | ast::Expr::PathExpr(e) => { |
403 | let path = e | 457 | let path = e |
@@ -405,7 +459,7 @@ impl ExprCollector<'_> { | |||
405 | .and_then(|path| self.expander.parse_path(path)) | 459 | .and_then(|path| self.expander.parse_path(path)) |
406 | .map(Expr::Path) | 460 | .map(Expr::Path) |
407 | .unwrap_or(Expr::Missing); | 461 | .unwrap_or(Expr::Missing); |
408 | (self.alloc_expr(path, syntax_ptr), vec![]) | 462 | self.alloc_expr(path, syntax_ptr) |
409 | } | 463 | } |
410 | ast::Expr::ContinueExpr(e) => (self.alloc_expr( | 464 | ast::Expr::ContinueExpr(e) => (self.alloc_expr( |
411 | Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, | 465 | Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, |
@@ -413,21 +467,21 @@ impl ExprCollector<'_> { | |||
413 | ), vec![]), | 467 | ), vec![]), |
414 | ast::Expr::BreakExpr(e) => { | 468 | ast::Expr::BreakExpr(e) => { |
415 | let expr = e.expr().map(|e| self.collect_expr(e)); | 469 | let expr = e.expr().map(|e| self.collect_expr(e)); |
416 | (self.alloc_expr( | 470 | track_parent!(self, self.alloc_expr( |
417 | Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, | 471 | Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, |
418 | syntax_ptr, | 472 | syntax_ptr, |
419 | ), expr.into_iter().collect()) | 473 | ), opt expr) |
420 | } | 474 | } |
421 | ast::Expr::ParenExpr(e) => { | 475 | ast::Expr::ParenExpr(e) => { |
422 | let inner = self.collect_expr_opt(e.expr()); | 476 | let inner = self.collect_expr_opt(e.expr()); |
423 | // make the paren expr point to the inner expression as well | 477 | // make the paren expr point to the inner expression as well |
424 | let src = self.expander.to_source(syntax_ptr); | 478 | let src = self.expander.to_source(syntax_ptr); |
425 | self.source_map.expr_map.insert(src, inner); | 479 | self.source_map.expr_map.insert(src, inner); |
426 | (inner, vec![]) | 480 | inner |
427 | } | 481 | } |
428 | ast::Expr::ReturnExpr(e) => { | 482 | ast::Expr::ReturnExpr(e) => { |
429 | let expr = e.expr().map(|e| self.collect_expr(e)); | 483 | let expr = e.expr().map(|e| self.collect_expr(e)); |
430 | (self.alloc_expr(Expr::Return { expr }, syntax_ptr), expr.into_iter().collect()) | 484 | track_parent!(self, self.alloc_expr(Expr::Return { expr }, syntax_ptr), opt expr) |
431 | } | 485 | } |
432 | ast::Expr::RecordLit(e) => { | 486 | ast::Expr::RecordLit(e) => { |
433 | let path = e.path().and_then(|path| self.expander.parse_path(path)); | 487 | let path = e.path().and_then(|path| self.expander.parse_path(path)); |
@@ -463,7 +517,7 @@ impl ExprCollector<'_> { | |||
463 | let src = self.expander.to_source(ptr); | 517 | let src = self.expander.to_source(ptr); |
464 | self.source_map.field_map.insert((res, i), src); | 518 | self.source_map.field_map.insert((res, i), src); |
465 | } | 519 | } |
466 | (res, children) | 520 | track_parent!(self, res, vec children) |
467 | } | 521 | } |
468 | ast::Expr::FieldExpr(e) => { | 522 | ast::Expr::FieldExpr(e) => { |
469 | let expr = self.collect_expr_opt(e.expr()); | 523 | let expr = self.collect_expr_opt(e.expr()); |
@@ -471,20 +525,24 @@ impl ExprCollector<'_> { | |||
471 | Some(kind) => kind.as_name(), | 525 | Some(kind) => kind.as_name(), |
472 | _ => Name::missing(), | 526 | _ => Name::missing(), |
473 | }; | 527 | }; |
474 | (self.alloc_expr(Expr::Field { expr, name }, syntax_ptr), vec![expr]) | 528 | track_parent!(self, self.alloc_expr(Expr::Field { expr, name }, syntax_ptr), expr) |
475 | } | 529 | } |
476 | ast::Expr::AwaitExpr(e) => { | 530 | ast::Expr::AwaitExpr(e) => { |
477 | let expr = self.collect_expr_opt(e.expr()); | 531 | let expr = self.collect_expr_opt(e.expr()); |
478 | (self.alloc_expr(Expr::Await { expr }, syntax_ptr), vec![expr]) | 532 | track_parent!(self, self.alloc_expr(Expr::Await { expr }, syntax_ptr), expr) |
479 | } | 533 | } |
480 | ast::Expr::TryExpr(e) => { | 534 | ast::Expr::TryExpr(e) => { |
481 | let expr = self.collect_expr_opt(e.expr()); | 535 | let expr = self.collect_expr_opt(e.expr()); |
482 | (self.alloc_expr(Expr::Try { expr }, syntax_ptr), vec![expr]) | 536 | track_parent!(self, self.alloc_expr(Expr::Try { expr }, syntax_ptr), expr) |
483 | } | 537 | } |
484 | ast::Expr::CastExpr(e) => { | 538 | ast::Expr::CastExpr(e) => { |
485 | let expr = self.collect_expr_opt(e.expr()); | 539 | let expr = self.collect_expr_opt(e.expr()); |
486 | let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.type_ref()); | 540 | let type_ref = TypeRef::from_ast_opt(&self.ctx(), e.type_ref()); |
487 | (self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr), vec![expr]) | 541 | track_parent!( |
542 | self, | ||
543 | self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr), | ||
544 | expr | ||
545 | ) | ||
488 | } | 546 | } |
489 | ast::Expr::RefExpr(e) => { | 547 | ast::Expr::RefExpr(e) => { |
490 | let expr = self.collect_expr_opt(e.expr()); | 548 | let expr = self.collect_expr_opt(e.expr()); |
@@ -501,15 +559,22 @@ impl ExprCollector<'_> { | |||
501 | Mutability::from_mutable(e.mut_token().is_some()) | 559 | Mutability::from_mutable(e.mut_token().is_some()) |
502 | }; | 560 | }; |
503 | let rawness = Rawness::from_raw(raw_tok); | 561 | let rawness = Rawness::from_raw(raw_tok); |
504 | 562 | track_parent!( | |
505 | self.alloc_expr(Expr::Ref { expr, rawness, mutability }, syntax_ptr) | 563 | self, |
564 | self.alloc_expr(Expr::Ref { expr, rawness, mutability }, syntax_ptr), | ||
565 | expr | ||
566 | ) | ||
506 | } | 567 | } |
507 | ast::Expr::PrefixExpr(e) => { | 568 | ast::Expr::PrefixExpr(e) => { |
508 | let expr = self.collect_expr_opt(e.expr()); | 569 | let expr = self.collect_expr_opt(e.expr()); |
509 | if let Some(op) = e.op_kind() { | 570 | if let Some(op) = e.op_kind() { |
510 | (self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr), vec![expr]) | 571 | track_parent!( |
572 | self, | ||
573 | self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr), | ||
574 | expr | ||
575 | ) | ||
511 | } else { | 576 | } else { |
512 | (self.alloc_expr(Expr::Missing, syntax_ptr), vec![]) | 577 | self.alloc_expr(Expr::Missing, syntax_ptr) |
513 | } | 578 | } |
514 | } | 579 | } |
515 | ast::Expr::LambdaExpr(e) => { | 580 | ast::Expr::LambdaExpr(e) => { |
@@ -529,24 +594,30 @@ impl ExprCollector<'_> { | |||
529 | .and_then(|r| r.type_ref()) | 594 | .and_then(|r| r.type_ref()) |
530 | .map(|it| TypeRef::from_ast(&self.ctx(), it)); | 595 | .map(|it| TypeRef::from_ast(&self.ctx(), it)); |
531 | let body = self.collect_expr_opt(e.body()); | 596 | let body = self.collect_expr_opt(e.body()); |
532 | ( | 597 | track_parent!( |
598 | self, | ||
533 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr), | 599 | self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr), |
534 | vec![body], | 600 | body, |
535 | ) | 601 | ) |
536 | } | 602 | } |
537 | ast::Expr::BinExpr(e) => { | 603 | ast::Expr::BinExpr(e) => { |
538 | let lhs = self.collect_expr_opt(e.lhs()); | 604 | let lhs = self.collect_expr_opt(e.lhs()); |
539 | let rhs = self.collect_expr_opt(e.rhs()); | 605 | let rhs = self.collect_expr_opt(e.rhs()); |
540 | let op = e.op_kind().map(BinaryOp::from); | 606 | let op = e.op_kind().map(BinaryOp::from); |
541 | (self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr), vec![lhs, rhs]) | 607 | track_parent!( |
608 | self, | ||
609 | self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr), | ||
610 | lhs, | ||
611 | rhs | ||
612 | ) | ||
542 | } | 613 | } |
543 | ast::Expr::TupleExpr(e) => { | 614 | ast::Expr::TupleExpr(e) => { |
544 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect::<Vec<_>>(); | 615 | let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect::<Vec<_>>(); |
545 | (self.alloc_expr(Expr::Tuple { exprs: exprs.clone() }, syntax_ptr), exprs) | 616 | track_parent!(self, self.alloc_expr(Expr::Tuple { exprs: exprs.clone() }, syntax_ptr), vec exprs) |
546 | } | 617 | } |
547 | ast::Expr::BoxExpr(e) => { | 618 | ast::Expr::BoxExpr(e) => { |
548 | let expr = self.collect_expr_opt(e.expr()); | 619 | let expr = self.collect_expr_opt(e.expr()); |
549 | (self.alloc_expr(Expr::Box { expr }, syntax_ptr), vec![expr]) | 620 | track_parent!(self, self.alloc_expr(Expr::Box { expr }, syntax_ptr), expr) |
550 | } | 621 | } |
551 | 622 | ||
552 | ast::Expr::ArrayExpr(e) => { | 623 | ast::Expr::ArrayExpr(e) => { |
@@ -555,45 +626,51 @@ impl ExprCollector<'_> { | |||
555 | match kind { | 626 | match kind { |
556 | ArrayExprKind::ElementList(e) => { | 627 | ArrayExprKind::ElementList(e) => { |
557 | let exprs = e.map(|expr| self.collect_expr(expr)).collect::<Vec<_>>(); | 628 | let exprs = e.map(|expr| self.collect_expr(expr)).collect::<Vec<_>>(); |
558 | ( | 629 | track_parent!(self, |
559 | self.alloc_expr( | 630 | self.alloc_expr( |
560 | Expr::Array(Array::ElementList(exprs.clone())), | 631 | Expr::Array(Array::ElementList(exprs.clone())), |
561 | syntax_ptr, | 632 | syntax_ptr, |
562 | ), | 633 | ), |
563 | exprs, | 634 | vec exprs, |
564 | ) | 635 | ) |
565 | } | 636 | } |
566 | ArrayExprKind::Repeat { initializer, repeat } => { | 637 | ArrayExprKind::Repeat { initializer, repeat } => { |
567 | let initializer = self.collect_expr_opt(initializer); | 638 | let initializer = self.collect_expr_opt(initializer); |
568 | let repeat = self.collect_expr_opt(repeat); | 639 | let repeat = self.collect_expr_opt(repeat); |
569 | ( | 640 | track_parent!( |
641 | self, | ||
570 | self.alloc_expr( | 642 | self.alloc_expr( |
571 | Expr::Array(Array::Repeat { initializer, repeat }), | 643 | Expr::Array(Array::Repeat { initializer, repeat }), |
572 | syntax_ptr, | 644 | syntax_ptr, |
573 | ), | 645 | ), |
574 | vec![initializer, repeat], | 646 | initializer, |
647 | repeat, | ||
575 | ) | 648 | ) |
576 | } | 649 | } |
577 | } | 650 | } |
578 | } | 651 | } |
579 | 652 | ||
580 | ast::Expr::Literal(e) => { | 653 | ast::Expr::Literal(e) => self.alloc_expr(Expr::Literal(e.kind().into()), syntax_ptr), |
581 | (self.alloc_expr(Expr::Literal(e.kind().into()), syntax_ptr), vec![]) | ||
582 | } | ||
583 | ast::Expr::IndexExpr(e) => { | 654 | ast::Expr::IndexExpr(e) => { |
584 | let base = self.collect_expr_opt(e.base()); | 655 | let base = self.collect_expr_opt(e.base()); |
585 | let index = self.collect_expr_opt(e.index()); | 656 | let index = self.collect_expr_opt(e.index()); |
586 | (self.alloc_expr(Expr::Index { base, index }, syntax_ptr), vec![base, index]) | 657 | track_parent!( |
658 | self, | ||
659 | self.alloc_expr(Expr::Index { base, index }, syntax_ptr), | ||
660 | base, | ||
661 | index | ||
662 | ) | ||
587 | } | 663 | } |
588 | ast::Expr::RangeExpr(e) => { | 664 | ast::Expr::RangeExpr(e) => { |
589 | let lhs = e.start().map(|lhs| self.collect_expr(lhs)); | 665 | let lhs = e.start().map(|lhs| self.collect_expr(lhs)); |
590 | let rhs = e.end().map(|rhs| self.collect_expr(rhs)); | 666 | let rhs = e.end().map(|rhs| self.collect_expr(rhs)); |
591 | match e.op_kind() { | 667 | match e.op_kind() { |
592 | Some(range_type) => ( | 668 | Some(range_type) => track_parent!( |
669 | self, | ||
593 | self.alloc_expr(Expr::Range { lhs, rhs, range_type }, syntax_ptr), | 670 | self.alloc_expr(Expr::Range { lhs, rhs, range_type }, syntax_ptr), |
594 | lhs.into_iter().chain(rhs.into_iter()).collect(), | 671 | opt lhs, opt rhs |
595 | ), | 672 | ), |
596 | None => (self.alloc_expr(Expr::Missing, syntax_ptr), vec![]), | 673 | None => self.alloc_expr(Expr::Missing, syntax_ptr), |
597 | } | 674 | } |
598 | } | 675 | } |
599 | ast::Expr::MacroCall(e) => { | 676 | ast::Expr::MacroCall(e) => { |
@@ -607,7 +684,7 @@ impl ExprCollector<'_> { | |||
607 | self.body.item_scope.define_legacy_macro(name, mac); | 684 | self.body.item_scope.define_legacy_macro(name, mac); |
608 | 685 | ||
609 | // FIXME: do we still need to allocate this as missing ? | 686 | // FIXME: do we still need to allocate this as missing ? |
610 | (self.alloc_expr(Expr::Missing, syntax_ptr), vec![]) | 687 | self.alloc_expr(Expr::Missing, syntax_ptr) |
611 | } else { | 688 | } else { |
612 | let macro_call = self.expander.to_source(AstPtr::new(&e)); | 689 | let macro_call = self.expander.to_source(AstPtr::new(&e)); |
613 | match self.expander.enter_expand(self.db, Some(&self.body.item_scope), e) { | 690 | match self.expander.enter_expand(self.db, Some(&self.body.item_scope), e) { |
@@ -620,15 +697,15 @@ impl ExprCollector<'_> { | |||
620 | self.item_trees.insert(self.expander.current_file_id, item_tree); | 697 | self.item_trees.insert(self.expander.current_file_id, item_tree); |
621 | let id = self.collect_expr(expansion); | 698 | let id = self.collect_expr(expansion); |
622 | self.expander.exit(self.db, mark); | 699 | self.expander.exit(self.db, mark); |
623 | (id, vec![]) | 700 | id |
624 | } | 701 | } |
625 | None => (self.alloc_expr(Expr::Missing, syntax_ptr), vec![]), | 702 | None => self.alloc_expr(Expr::Missing, syntax_ptr), |
626 | } | 703 | } |
627 | } | 704 | } |
628 | } | 705 | } |
629 | 706 | ||
630 | // FIXME implement HIR for these: | 707 | // FIXME implement HIR for these: |
631 | ast::Expr::Label(_e) => (self.alloc_expr(Expr::Missing, syntax_ptr), vec![]), | 708 | ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), |
632 | } | 709 | } |
633 | } | 710 | } |
634 | 711 | ||