diff options
Diffstat (limited to 'crates/hir_def/src/body')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 129 |
1 files changed, 67 insertions, 62 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 8c8eb8007..7052058f2 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -379,23 +379,22 @@ impl ExprCollector<'_> { | |||
379 | } | 379 | } |
380 | ast::Expr::RecordExpr(e) => { | 380 | ast::Expr::RecordExpr(e) => { |
381 | let path = e.path().and_then(|path| self.expander.parse_path(path)); | 381 | let path = e.path().and_then(|path| self.expander.parse_path(path)); |
382 | let mut field_ptrs = Vec::new(); | ||
383 | let record_lit = if let Some(nfl) = e.record_expr_field_list() { | 382 | let record_lit = if let Some(nfl) = e.record_expr_field_list() { |
384 | let fields = nfl | 383 | let fields = nfl |
385 | .fields() | 384 | .fields() |
386 | .inspect(|field| field_ptrs.push(AstPtr::new(field))) | ||
387 | .filter_map(|field| { | 385 | .filter_map(|field| { |
388 | self.check_cfg(&field)?; | 386 | self.check_cfg(&field)?; |
389 | 387 | ||
390 | let name = field.field_name()?.as_name(); | 388 | let name = field.field_name()?.as_name(); |
391 | 389 | ||
392 | Some(RecordLitField { | 390 | let expr = match field.expr() { |
393 | name, | 391 | Some(e) => self.collect_expr(e), |
394 | expr: match field.expr() { | 392 | None => self.missing_expr(), |
395 | Some(e) => self.collect_expr(e), | 393 | }; |
396 | None => self.missing_expr(), | 394 | let src = self.expander.to_source(AstPtr::new(&field)); |
397 | }, | 395 | self.source_map.field_map.insert(src.clone(), expr); |
398 | }) | 396 | self.source_map.field_map_back.insert(expr, src); |
397 | Some(RecordLitField { name, expr }) | ||
399 | }) | 398 | }) |
400 | .collect(); | 399 | .collect(); |
401 | let spread = nfl.spread().map(|s| self.collect_expr(s)); | 400 | let spread = nfl.spread().map(|s| self.collect_expr(s)); |
@@ -404,12 +403,7 @@ impl ExprCollector<'_> { | |||
404 | Expr::RecordLit { path, fields: Vec::new(), spread: None } | 403 | Expr::RecordLit { path, fields: Vec::new(), spread: None } |
405 | }; | 404 | }; |
406 | 405 | ||
407 | let res = self.alloc_expr(record_lit, syntax_ptr); | 406 | self.alloc_expr(record_lit, syntax_ptr) |
408 | for (i, ptr) in field_ptrs.into_iter().enumerate() { | ||
409 | let src = self.expander.to_source(ptr); | ||
410 | self.source_map.field_map.insert((res, i), src); | ||
411 | } | ||
412 | res | ||
413 | } | 407 | } |
414 | ast::Expr::FieldExpr(e) => { | 408 | ast::Expr::FieldExpr(e) => { |
415 | let expr = self.collect_expr_opt(e.expr()); | 409 | let expr = self.collect_expr_opt(e.expr()); |
@@ -525,7 +519,7 @@ impl ExprCollector<'_> { | |||
525 | } | 519 | } |
526 | ast::Expr::MacroCall(e) => { | 520 | ast::Expr::MacroCall(e) => { |
527 | let mut ids = vec![]; | 521 | let mut ids = vec![]; |
528 | self.collect_macro_call(e, syntax_ptr.clone(), |this, expansion| { | 522 | self.collect_macro_call(e, syntax_ptr.clone(), true, |this, expansion| { |
529 | ids.push(match expansion { | 523 | ids.push(match expansion { |
530 | Some(it) => this.collect_expr(it), | 524 | Some(it) => this.collect_expr(it), |
531 | None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), | 525 | None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), |
@@ -533,6 +527,17 @@ impl ExprCollector<'_> { | |||
533 | }); | 527 | }); |
534 | ids[0] | 528 | ids[0] |
535 | } | 529 | } |
530 | ast::Expr::MacroStmts(e) => { | ||
531 | // FIXME: these statements should be held by some hir containter | ||
532 | for stmt in e.statements() { | ||
533 | self.collect_stmt(stmt); | ||
534 | } | ||
535 | if let Some(expr) = e.expr() { | ||
536 | self.collect_expr(expr) | ||
537 | } else { | ||
538 | self.alloc_expr(Expr::Missing, syntax_ptr) | ||
539 | } | ||
540 | } | ||
536 | } | 541 | } |
537 | } | 542 | } |
538 | 543 | ||
@@ -540,6 +545,7 @@ impl ExprCollector<'_> { | |||
540 | &mut self, | 545 | &mut self, |
541 | e: ast::MacroCall, | 546 | e: ast::MacroCall, |
542 | syntax_ptr: AstPtr<ast::Expr>, | 547 | syntax_ptr: AstPtr<ast::Expr>, |
548 | is_error_recoverable: bool, | ||
543 | mut collector: F, | 549 | mut collector: F, |
544 | ) { | 550 | ) { |
545 | // File containing the macro call. Expansion errors will be attached here. | 551 | // File containing the macro call. Expansion errors will be attached here. |
@@ -573,7 +579,7 @@ impl ExprCollector<'_> { | |||
573 | Some((mark, expansion)) => { | 579 | Some((mark, expansion)) => { |
574 | // FIXME: Statements are too complicated to recover from error for now. | 580 | // FIXME: Statements are too complicated to recover from error for now. |
575 | // It is because we don't have any hygiene for local variable expansion right now. | 581 | // It is because we don't have any hygiene for local variable expansion right now. |
576 | if T::can_cast(syntax::SyntaxKind::MACRO_STMTS) && res.err.is_some() { | 582 | if !is_error_recoverable && res.err.is_some() { |
577 | self.expander.exit(self.db, mark); | 583 | self.expander.exit(self.db, mark); |
578 | collector(self, None); | 584 | collector(self, None); |
579 | } else { | 585 | } else { |
@@ -597,56 +603,55 @@ impl ExprCollector<'_> { | |||
597 | } | 603 | } |
598 | 604 | ||
599 | fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Vec<Statement>> { | 605 | fn collect_stmt(&mut self, s: ast::Stmt) -> Option<Vec<Statement>> { |
600 | let stmt = | 606 | let stmt = match s { |
601 | match s { | 607 | ast::Stmt::LetStmt(stmt) => { |
602 | ast::Stmt::LetStmt(stmt) => { | 608 | self.check_cfg(&stmt)?; |
603 | self.check_cfg(&stmt)?; | 609 | |
604 | 610 | let pat = self.collect_pat_opt(stmt.pat()); | |
605 | let pat = self.collect_pat_opt(stmt.pat()); | 611 | let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); |
606 | let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); | 612 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); |
607 | let initializer = stmt.initializer().map(|e| self.collect_expr(e)); | 613 | vec![Statement::Let { pat, type_ref, initializer }] |
608 | vec![Statement::Let { pat, type_ref, initializer }] | 614 | } |
609 | } | 615 | ast::Stmt::ExprStmt(stmt) => { |
610 | ast::Stmt::ExprStmt(stmt) => { | 616 | self.check_cfg(&stmt)?; |
611 | self.check_cfg(&stmt)?; | 617 | |
612 | 618 | // Note that macro could be expended to multiple statements | |
613 | // Note that macro could be expended to multiple statements | 619 | if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { |
614 | if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { | 620 | let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); |
615 | let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); | 621 | let mut stmts = vec![]; |
616 | let mut stmts = vec![]; | 622 | |
617 | 623 | self.collect_macro_call(m, syntax_ptr.clone(), false, |this, expansion| { | |
618 | self.collect_macro_call(m, syntax_ptr.clone(), |this, expansion| { | 624 | match expansion { |
619 | match expansion { | 625 | Some(expansion) => { |
620 | Some(expansion) => { | 626 | let statements: ast::MacroStmts = expansion; |
621 | let statements: ast::MacroStmts = expansion; | 627 | |
622 | 628 | statements.statements().for_each(|stmt| { | |
623 | statements.statements().for_each(|stmt| { | 629 | if let Some(mut r) = this.collect_stmt(stmt) { |
624 | if let Some(mut r) = this.collect_stmt(stmt) { | 630 | stmts.append(&mut r); |
625 | stmts.append(&mut r); | ||
626 | } | ||
627 | }); | ||
628 | if let Some(expr) = statements.expr() { | ||
629 | stmts.push(Statement::Expr(this.collect_expr(expr))); | ||
630 | } | 631 | } |
631 | } | 632 | }); |
632 | None => { | 633 | if let Some(expr) = statements.expr() { |
633 | stmts.push(Statement::Expr( | 634 | stmts.push(Statement::Expr(this.collect_expr(expr))); |
634 | this.alloc_expr(Expr::Missing, syntax_ptr.clone()), | ||
635 | )); | ||
636 | } | 635 | } |
637 | } | 636 | } |
638 | }); | 637 | None => { |
639 | stmts | 638 | stmts.push(Statement::Expr( |
640 | } else { | 639 | this.alloc_expr(Expr::Missing, syntax_ptr.clone()), |
641 | vec![Statement::Expr(self.collect_expr_opt(stmt.expr()))] | 640 | )); |
642 | } | 641 | } |
642 | } | ||
643 | }); | ||
644 | stmts | ||
645 | } else { | ||
646 | vec![Statement::Expr(self.collect_expr_opt(stmt.expr()))] | ||
643 | } | 647 | } |
644 | ast::Stmt::Item(item) => { | 648 | } |
645 | self.check_cfg(&item)?; | 649 | ast::Stmt::Item(item) => { |
650 | self.check_cfg(&item)?; | ||
646 | 651 | ||
647 | return None; | 652 | return None; |
648 | } | 653 | } |
649 | }; | 654 | }; |
650 | 655 | ||
651 | Some(stmt) | 656 | Some(stmt) |
652 | } | 657 | } |