aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/expr.rs201
-rw-r--r--crates/ra_hir/src/ids.rs2
-rw-r--r--crates/ra_hir/src/nameres.rs6
-rw-r--r--crates/ra_hir/src/nameres/collector.rs8
-rw-r--r--crates/ra_hir/src/path.rs4
-rw-r--r--crates/ra_hir/src/resolve.rs7
6 files changed, 135 insertions, 93 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 7759a6d4f..7d5257461 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -12,7 +12,7 @@ use ra_syntax::{
12use crate::{ 12use crate::{
13 Path, Name, HirDatabase, Resolver,DefWithBody, Either, 13 Path, Name, HirDatabase, Resolver,DefWithBody, Either,
14 name::AsName, 14 name::AsName,
15 ids::MacroDefId, 15 ids::{MacroCallLoc,HirFileId},
16 type_ref::{Mutability, TypeRef}, 16 type_ref::{Mutability, TypeRef},
17}; 17};
18use crate::{path::GenericArgs, ty::primitive::{IntTy, UncertainIntTy, FloatTy, UncertainFloatTy}}; 18use crate::{path::GenericArgs, ty::primitive::{IntTy, UncertainIntTy, FloatTy, UncertainFloatTy}};
@@ -479,7 +479,8 @@ impl Pat {
479 479
480// Queries 480// Queries
481 481
482pub(crate) struct ExprCollector { 482pub(crate) struct ExprCollector<DB> {
483 db: DB,
483 owner: DefWithBody, 484 owner: DefWithBody,
484 exprs: Arena<ExprId, Expr>, 485 exprs: Arena<ExprId, Expr>,
485 pats: Arena<PatId, Pat>, 486 pats: Arena<PatId, Pat>,
@@ -489,20 +490,10 @@ pub(crate) struct ExprCollector {
489 resolver: Resolver, 490 resolver: Resolver,
490} 491}
491 492
492impl ExprCollector{ 493impl<'a, DB> ExprCollector<&'a DB>
493 fn new(owner: DefWithBody,resolver:Resolver) -> Self { 494where
494 ExprCollector { 495 DB: HirDatabase,
495 owner, 496{
496 resolver,
497 exprs: Arena::default(),
498 pats: Arena::default(),
499 source_map: BodySourceMap::default(),
500 params: Vec::new(),
501 body_expr: None,
502
503 }
504 }
505
506 fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId { 497 fn alloc_expr(&mut self, expr: Expr, syntax_ptr: SyntaxNodePtr) -> ExprId {
507 let id = self.exprs.alloc(expr); 498 let id = self.exprs.alloc(expr);
508 self.source_map.expr_map.insert(syntax_ptr, id); 499 self.source_map.expr_map.insert(syntax_ptr, id);
@@ -522,7 +513,7 @@ impl ExprCollector{
522 self.exprs.alloc(block) 513 self.exprs.alloc(block)
523 } 514 }
524 515
525 fn collect_expr(&mut self, expr: &ast::Expr,db:&impl HirDatabase) -> ExprId { 516 fn collect_expr(&mut self, expr: &ast::Expr) -> ExprId {
526 let syntax_ptr = SyntaxNodePtr::new(expr.syntax()); 517 let syntax_ptr = SyntaxNodePtr::new(expr.syntax());
527 match expr.kind() { 518 match expr.kind() {
528 ast::ExprKind::IfExpr(e) => { 519 ast::ExprKind::IfExpr(e) => {
@@ -530,15 +521,15 @@ impl ExprCollector{
530 // if let -- desugar to match 521 // if let -- desugar to match
531 let pat = self.collect_pat(pat); 522 let pat = self.collect_pat(pat);
532 let match_expr = 523 let match_expr =
533 self.collect_expr_opt(e.condition().expect("checked above").expr(),db); 524 self.collect_expr_opt(e.condition().expect("checked above").expr());
534 let then_branch = self.collect_block_opt(e.then_branch(),db); 525 let then_branch = self.collect_block_opt(e.then_branch());
535 let else_branch = e 526 let else_branch = e
536 .else_branch() 527 .else_branch()
537 .map(|b| match b { 528 .map(|b| match b {
538 ast::ElseBranch::Block(it) => self.collect_block(it,db), 529 ast::ElseBranch::Block(it) => self.collect_block(it),
539 ast::ElseBranch::IfExpr(elif) => { 530 ast::ElseBranch::IfExpr(elif) => {
540 let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap(); 531 let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap();
541 self.collect_expr(expr,db) 532 self.collect_expr(expr)
542 } 533 }
543 }) 534 })
544 .unwrap_or_else(|| self.empty_block()); 535 .unwrap_or_else(|| self.empty_block());
@@ -549,27 +540,27 @@ impl ExprCollector{
549 ]; 540 ];
550 self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr) 541 self.alloc_expr(Expr::Match { expr: match_expr, arms }, syntax_ptr)
551 } else { 542 } else {
552 let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr()),db); 543 let condition = self.collect_expr_opt(e.condition().and_then(|c| c.expr()));
553 let then_branch = self.collect_block_opt(e.then_branch(),db); 544 let then_branch = self.collect_block_opt(e.then_branch());
554 let else_branch = e.else_branch().map(|b| match b { 545 let else_branch = e.else_branch().map(|b| match b {
555 ast::ElseBranch::Block(it) => self.collect_block(it,db), 546 ast::ElseBranch::Block(it) => self.collect_block(it),
556 ast::ElseBranch::IfExpr(elif) => { 547 ast::ElseBranch::IfExpr(elif) => {
557 let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap(); 548 let expr: &ast::Expr = ast::Expr::cast(elif.syntax()).unwrap();
558 self.collect_expr(expr,db) 549 self.collect_expr(expr)
559 } 550 }
560 }); 551 });
561 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) 552 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
562 } 553 }
563 } 554 }
564 ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block(),db), 555 ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()),
565 ast::ExprKind::LoopExpr(e) => { 556 ast::ExprKind::LoopExpr(e) => {
566 let body = self.collect_block_opt(e.loop_body(),db); 557 let body = self.collect_block_opt(e.loop_body());
567 self.alloc_expr(Expr::Loop { body }, syntax_ptr) 558 self.alloc_expr(Expr::Loop { body }, syntax_ptr)
568 } 559 }
569 ast::ExprKind::WhileExpr(e) => { 560 ast::ExprKind::WhileExpr(e) => {
570 let condition = if let Some(condition) = e.condition() { 561 let condition = if let Some(condition) = e.condition() {
571 if condition.pat().is_none() { 562 if condition.pat().is_none() {
572 self.collect_expr_opt(condition.expr(),db) 563 self.collect_expr_opt(condition.expr())
573 } else { 564 } else {
574 // FIXME handle while let 565 // FIXME handle while let
575 return self.alloc_expr(Expr::Missing, syntax_ptr); 566 return self.alloc_expr(Expr::Missing, syntax_ptr);
@@ -577,28 +568,28 @@ impl ExprCollector{
577 } else { 568 } else {
578 self.exprs.alloc(Expr::Missing) 569 self.exprs.alloc(Expr::Missing)
579 }; 570 };
580 let body = self.collect_block_opt(e.loop_body(),db); 571 let body = self.collect_block_opt(e.loop_body());
581 self.alloc_expr(Expr::While { condition, body }, syntax_ptr) 572 self.alloc_expr(Expr::While { condition, body }, syntax_ptr)
582 } 573 }
583 ast::ExprKind::ForExpr(e) => { 574 ast::ExprKind::ForExpr(e) => {
584 let iterable = self.collect_expr_opt(e.iterable(),db); 575 let iterable = self.collect_expr_opt(e.iterable());
585 let pat = self.collect_pat_opt(e.pat()); 576 let pat = self.collect_pat_opt(e.pat());
586 let body = self.collect_block_opt(e.loop_body(),db); 577 let body = self.collect_block_opt(e.loop_body());
587 self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr) 578 self.alloc_expr(Expr::For { iterable, pat, body }, syntax_ptr)
588 } 579 }
589 ast::ExprKind::CallExpr(e) => { 580 ast::ExprKind::CallExpr(e) => {
590 let callee = self.collect_expr_opt(e.expr(),db); 581 let callee = self.collect_expr_opt(e.expr());
591 let args = if let Some(arg_list) = e.arg_list() { 582 let args = if let Some(arg_list) = e.arg_list() {
592 arg_list.args().map(|e| self.collect_expr(e,db)).collect() 583 arg_list.args().map(|e| self.collect_expr(e)).collect()
593 } else { 584 } else {
594 Vec::new() 585 Vec::new()
595 }; 586 };
596 self.alloc_expr(Expr::Call { callee, args }, syntax_ptr) 587 self.alloc_expr(Expr::Call { callee, args }, syntax_ptr)
597 } 588 }
598 ast::ExprKind::MethodCallExpr(e) => { 589 ast::ExprKind::MethodCallExpr(e) => {
599 let receiver = self.collect_expr_opt(e.expr(),db); 590 let receiver = self.collect_expr_opt(e.expr());
600 let args = if let Some(arg_list) = e.arg_list() { 591 let args = if let Some(arg_list) = e.arg_list() {
601 arg_list.args().map(|e| self.collect_expr(e,db)).collect() 592 arg_list.args().map(|e| self.collect_expr(e)).collect()
602 } else { 593 } else {
603 Vec::new() 594 Vec::new()
604 }; 595 };
@@ -610,17 +601,17 @@ impl ExprCollector{
610 ) 601 )
611 } 602 }
612 ast::ExprKind::MatchExpr(e) => { 603 ast::ExprKind::MatchExpr(e) => {
613 let expr = self.collect_expr_opt(e.expr(),db); 604 let expr = self.collect_expr_opt(e.expr());
614 let arms = if let Some(match_arm_list) = e.match_arm_list() { 605 let arms = if let Some(match_arm_list) = e.match_arm_list() {
615 match_arm_list 606 match_arm_list
616 .arms() 607 .arms()
617 .map(|arm| MatchArm { 608 .map(|arm| MatchArm {
618 pats: arm.pats().map(|p| self.collect_pat(p)).collect(), 609 pats: arm.pats().map(|p| self.collect_pat(p)).collect(),
619 expr: self.collect_expr_opt(arm.expr(),db), 610 expr: self.collect_expr_opt(arm.expr()),
620 guard: arm 611 guard: arm
621 .guard() 612 .guard()
622 .and_then(|guard| guard.expr()) 613 .and_then(|guard| guard.expr())
623 .map(|e| self.collect_expr(e,db)), 614 .map(|e| self.collect_expr(e)),
624 }) 615 })
625 .collect() 616 .collect()
626 } else { 617 } else {
@@ -638,17 +629,17 @@ impl ExprCollector{
638 self.alloc_expr(Expr::Continue, syntax_ptr) 629 self.alloc_expr(Expr::Continue, syntax_ptr)
639 } 630 }
640 ast::ExprKind::BreakExpr(e) => { 631 ast::ExprKind::BreakExpr(e) => {
641 let expr = e.expr().map(|e| self.collect_expr(e,db)); 632 let expr = e.expr().map(|e| self.collect_expr(e));
642 self.alloc_expr(Expr::Break { expr }, syntax_ptr) 633 self.alloc_expr(Expr::Break { expr }, syntax_ptr)
643 } 634 }
644 ast::ExprKind::ParenExpr(e) => { 635 ast::ExprKind::ParenExpr(e) => {
645 let inner = self.collect_expr_opt(e.expr(),db); 636 let inner = self.collect_expr_opt(e.expr());
646 // make the paren expr point to the inner expression as well 637 // make the paren expr point to the inner expression as well
647 self.source_map.expr_map.insert(syntax_ptr, inner); 638 self.source_map.expr_map.insert(syntax_ptr, inner);
648 inner 639 inner
649 } 640 }
650 ast::ExprKind::ReturnExpr(e) => { 641 ast::ExprKind::ReturnExpr(e) => {
651 let expr = e.expr().map(|e| self.collect_expr(e,db)); 642 let expr = e.expr().map(|e| self.collect_expr(e));
652 self.alloc_expr(Expr::Return { expr }, syntax_ptr) 643 self.alloc_expr(Expr::Return { expr }, syntax_ptr)
653 } 644 }
654 ast::ExprKind::StructLit(e) => { 645 ast::ExprKind::StructLit(e) => {
@@ -663,7 +654,7 @@ impl ExprCollector{
663 .map(|nr| nr.as_name()) 654 .map(|nr| nr.as_name())
664 .unwrap_or_else(Name::missing), 655 .unwrap_or_else(Name::missing),
665 expr: if let Some(e) = field.expr() { 656 expr: if let Some(e) = field.expr() {
666 self.collect_expr(e,db) 657 self.collect_expr(e)
667 } else if let Some(nr) = field.name_ref() { 658 } else if let Some(nr) = field.name_ref() {
668 // field shorthand 659 // field shorthand
669 let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr))); 660 let id = self.exprs.alloc(Expr::Path(Path::from_name_ref(nr)));
@@ -682,7 +673,7 @@ impl ExprCollector{
682 } else { 673 } else {
683 Vec::new() 674 Vec::new()
684 }; 675 };
685 let spread = e.spread().map(|s| self.collect_expr(s,db)); 676 let spread = e.spread().map(|s| self.collect_expr(s));
686 let res = self.alloc_expr(Expr::StructLit { path, fields, spread }, syntax_ptr); 677 let res = self.alloc_expr(Expr::StructLit { path, fields, spread }, syntax_ptr);
687 for (i, ptr) in field_ptrs.into_iter().enumerate() { 678 for (i, ptr) in field_ptrs.into_iter().enumerate() {
688 self.source_map.field_map.insert((res, i), ptr); 679 self.source_map.field_map.insert((res, i), ptr);
@@ -690,7 +681,7 @@ impl ExprCollector{
690 res 681 res
691 } 682 }
692 ast::ExprKind::FieldExpr(e) => { 683 ast::ExprKind::FieldExpr(e) => {
693 let expr = self.collect_expr_opt(e.expr(),db); 684 let expr = self.collect_expr_opt(e.expr());
694 let name = match e.field_access() { 685 let name = match e.field_access() {
695 Some(kind) => kind.as_name(), 686 Some(kind) => kind.as_name(),
696 _ => Name::missing(), 687 _ => Name::missing(),
@@ -698,21 +689,21 @@ impl ExprCollector{
698 self.alloc_expr(Expr::Field { expr, name }, syntax_ptr) 689 self.alloc_expr(Expr::Field { expr, name }, syntax_ptr)
699 } 690 }
700 ast::ExprKind::TryExpr(e) => { 691 ast::ExprKind::TryExpr(e) => {
701 let expr = self.collect_expr_opt(e.expr(),db); 692 let expr = self.collect_expr_opt(e.expr());
702 self.alloc_expr(Expr::Try { expr }, syntax_ptr) 693 self.alloc_expr(Expr::Try { expr }, syntax_ptr)
703 } 694 }
704 ast::ExprKind::CastExpr(e) => { 695 ast::ExprKind::CastExpr(e) => {
705 let expr = self.collect_expr_opt(e.expr(),db); 696 let expr = self.collect_expr_opt(e.expr());
706 let type_ref = TypeRef::from_ast_opt(e.type_ref()); 697 let type_ref = TypeRef::from_ast_opt(e.type_ref());
707 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr) 698 self.alloc_expr(Expr::Cast { expr, type_ref }, syntax_ptr)
708 } 699 }
709 ast::ExprKind::RefExpr(e) => { 700 ast::ExprKind::RefExpr(e) => {
710 let expr = self.collect_expr_opt(e.expr(),db); 701 let expr = self.collect_expr_opt(e.expr());
711 let mutability = Mutability::from_mutable(e.is_mut()); 702 let mutability = Mutability::from_mutable(e.is_mut());
712 self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr) 703 self.alloc_expr(Expr::Ref { expr, mutability }, syntax_ptr)
713 } 704 }
714 ast::ExprKind::PrefixExpr(e) => { 705 ast::ExprKind::PrefixExpr(e) => {
715 let expr = self.collect_expr_opt(e.expr(),db); 706 let expr = self.collect_expr_opt(e.expr());
716 if let Some(op) = e.op_kind() { 707 if let Some(op) = e.op_kind() {
717 self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr) 708 self.alloc_expr(Expr::UnaryOp { expr, op }, syntax_ptr)
718 } else { 709 } else {
@@ -730,17 +721,17 @@ impl ExprCollector{
730 arg_types.push(type_ref); 721 arg_types.push(type_ref);
731 } 722 }
732 } 723 }
733 let body = self.collect_expr_opt(e.body(),db); 724 let body = self.collect_expr_opt(e.body());
734 self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) 725 self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr)
735 } 726 }
736 ast::ExprKind::BinExpr(e) => { 727 ast::ExprKind::BinExpr(e) => {
737 let lhs = self.collect_expr_opt(e.lhs(),db); 728 let lhs = self.collect_expr_opt(e.lhs());
738 let rhs = self.collect_expr_opt(e.rhs(),db); 729 let rhs = self.collect_expr_opt(e.rhs());
739 let op = e.op_kind(); 730 let op = e.op_kind();
740 self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr) 731 self.alloc_expr(Expr::BinaryOp { lhs, rhs, op }, syntax_ptr)
741 } 732 }
742 ast::ExprKind::TupleExpr(e) => { 733 ast::ExprKind::TupleExpr(e) => {
743 let exprs = e.exprs().map(|expr| self.collect_expr(expr,db)).collect(); 734 let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect();
744 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) 735 self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr)
745 } 736 }
746 737
@@ -749,12 +740,12 @@ impl ExprCollector{
749 740
750 match kind { 741 match kind {
751 ArrayExprKind::ElementList(e) => { 742 ArrayExprKind::ElementList(e) => {
752 let exprs = e.map(|expr| self.collect_expr(expr,db)).collect(); 743 let exprs = e.map(|expr| self.collect_expr(expr)).collect();
753 self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr) 744 self.alloc_expr(Expr::Array(Array::ElementList(exprs)), syntax_ptr)
754 } 745 }
755 ArrayExprKind::Repeat { initializer, repeat } => { 746 ArrayExprKind::Repeat { initializer, repeat } => {
756 let initializer = self.collect_expr_opt(initializer,db); 747 let initializer = self.collect_expr_opt(initializer);
757 let repeat = self.collect_expr_opt(repeat,db); 748 let repeat = self.collect_expr_opt(repeat);
758 self.alloc_expr( 749 self.alloc_expr(
759 Expr::Array(Array::Repeat { initializer, repeat }), 750 Expr::Array(Array::Repeat { initializer, repeat }),
760 syntax_ptr, 751 syntax_ptr,
@@ -799,52 +790,79 @@ impl ExprCollector{
799 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 790 ast::ExprKind::IndexExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
800 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), 791 ast::ExprKind::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr),
801 ast::ExprKind::MacroCall(e) => { 792 ast::ExprKind::MacroCall(e) => {
802 793 // very hacky.TODO change to use the macro resolution
803 let name = e.name().map(|nr| nr.as_name()).unwrap_or_else(Name::missing); 794 let name = e
804 795 .path()
805 let res = self.resolver.resolve_name(db,&name); 796 .and_then(Path::from_ast)
806 797 .and_then(|path| path.expand_macro_expr())
807 // match res { 798 .unwrap_or_else(Name::missing);
808 799
809 // } 800 if let Some(macro_id) = self.resolver.resolve_macro_call(&name) {
810 801 if let Some((module, _)) = self.resolver.module() {
811 // let resolver = Resolver 802 // we do this to get the ast_id for the macro call
812 803 // if we used the ast_id from the macro_id variable
813 self.alloc_expr(Expr::Missing, syntax_ptr) 804 // it gives us the ast_id of the defenition site
814 }, 805 let module = module.mk_module(module.root());
806 let hir_file_id = module.definition_source(self.db).0;
807 let ast_id =
808 self.db.ast_id_map(hir_file_id).ast_id(e).with_file_id(hir_file_id);
809
810 let call_loc = MacroCallLoc { def: *macro_id, ast_id };
811 let call_id = call_loc.id(self.db);
812 let file_id: HirFileId = call_id.into();
813
814 log::debug!(
815 "expanded macro ast {}",
816 self.db.hir_parse(file_id).syntax().debug_dump()
817 );
818
819 self.db
820 .hir_parse(file_id)
821 .syntax()
822 .descendants()
823 .find_map(ast::Expr::cast)
824 .map(|expr| self.collect_expr(expr))
825 .unwrap_or(self.alloc_expr(Expr::Missing, syntax_ptr))
826 } else {
827 self.alloc_expr(Expr::Missing, syntax_ptr)
828 }
829 } else {
830 self.alloc_expr(Expr::Missing, syntax_ptr)
831 }
832 }
815 } 833 }
816 } 834 }
817 835
818 fn collect_expr_opt(&mut self, expr: Option<&ast::Expr>,db:&impl HirDatabase) -> ExprId { 836 fn collect_expr_opt(&mut self, expr: Option<&ast::Expr>) -> ExprId {
819 if let Some(expr) = expr { 837 if let Some(expr) = expr {
820 self.collect_expr(expr,db) 838 self.collect_expr(expr)
821 } else { 839 } else {
822 self.exprs.alloc(Expr::Missing) 840 self.exprs.alloc(Expr::Missing)
823 } 841 }
824 } 842 }
825 843
826 fn collect_block(&mut self, block: &ast::Block,db:&impl HirDatabase) -> ExprId { 844 fn collect_block(&mut self, block: &ast::Block) -> ExprId {
827 let statements = block 845 let statements = block
828 .statements() 846 .statements()
829 .map(|s| match s.kind() { 847 .map(|s| match s.kind() {
830 ast::StmtKind::LetStmt(stmt) => { 848 ast::StmtKind::LetStmt(stmt) => {
831 let pat = self.collect_pat_opt(stmt.pat()); 849 let pat = self.collect_pat_opt(stmt.pat());
832 let type_ref = stmt.ascribed_type().map(TypeRef::from_ast); 850 let type_ref = stmt.ascribed_type().map(TypeRef::from_ast);
833 let initializer = stmt.initializer().map(|e| self.collect_expr(e,db)); 851 let initializer = stmt.initializer().map(|e| self.collect_expr(e));
834 Statement::Let { pat, type_ref, initializer } 852 Statement::Let { pat, type_ref, initializer }
835 } 853 }
836 ast::StmtKind::ExprStmt(stmt) => { 854 ast::StmtKind::ExprStmt(stmt) => {
837 Statement::Expr(self.collect_expr_opt(stmt.expr(),db)) 855 Statement::Expr(self.collect_expr_opt(stmt.expr()))
838 } 856 }
839 }) 857 })
840 .collect(); 858 .collect();
841 let tail = block.expr().map(|e| self.collect_expr(e,db)); 859 let tail = block.expr().map(|e| self.collect_expr(e));
842 self.alloc_expr(Expr::Block { statements, tail }, SyntaxNodePtr::new(block.syntax())) 860 self.alloc_expr(Expr::Block { statements, tail }, SyntaxNodePtr::new(block.syntax()))
843 } 861 }
844 862
845 fn collect_block_opt(&mut self, block: Option<&ast::Block>,db:&impl HirDatabase) -> ExprId { 863 fn collect_block_opt(&mut self, block: Option<&ast::Block>) -> ExprId {
846 if let Some(block) = block { 864 if let Some(block) = block {
847 self.collect_block(block,db) 865 self.collect_block(block)
848 } else { 866 } else {
849 self.exprs.alloc(Expr::Missing) 867 self.exprs.alloc(Expr::Missing)
850 } 868 }
@@ -917,17 +935,17 @@ impl ExprCollector{
917 } 935 }
918 } 936 }
919 937
920 fn collect_const_body(&mut self, node: &ast::ConstDef,db:&impl HirDatabase) { 938 fn collect_const_body(&mut self, node: &ast::ConstDef) {
921 let body = self.collect_expr_opt(node.body(),db); 939 let body = self.collect_expr_opt(node.body());
922 self.body_expr = Some(body); 940 self.body_expr = Some(body);
923 } 941 }
924 942
925 fn collect_static_body(&mut self, node: &ast::StaticDef,db:&impl HirDatabase) { 943 fn collect_static_body(&mut self, node: &ast::StaticDef) {
926 let body = self.collect_expr_opt(node.body(),db); 944 let body = self.collect_expr_opt(node.body());
927 self.body_expr = Some(body); 945 self.body_expr = Some(body);
928 } 946 }
929 947
930 fn collect_fn_body(&mut self, node: &ast::FnDef,db:&impl HirDatabase) { 948 fn collect_fn_body(&mut self, node: &ast::FnDef) {
931 if let Some(param_list) = node.param_list() { 949 if let Some(param_list) = node.param_list() {
932 if let Some(self_param) = param_list.self_param() { 950 if let Some(self_param) = param_list.self_param() {
933 let ptr = AstPtr::new(self_param); 951 let ptr = AstPtr::new(self_param);
@@ -953,7 +971,7 @@ impl ExprCollector{
953 } 971 }
954 }; 972 };
955 973
956 let body = self.collect_block_opt(node.body(),db); 974 let body = self.collect_block_opt(node.body());
957 self.body_expr = Some(body); 975 self.body_expr = Some(body);
958 } 976 }
959 977
@@ -973,14 +991,21 @@ pub(crate) fn body_with_source_map_query(
973 db: &impl HirDatabase, 991 db: &impl HirDatabase,
974 def: DefWithBody, 992 def: DefWithBody,
975) -> (Arc<Body>, Arc<BodySourceMap>) { 993) -> (Arc<Body>, Arc<BodySourceMap>) {
976 994 let mut collector = ExprCollector {
977 let mut resolver = def.resolver(db); 995 db,
978 let mut collector = ExprCollector::new(def,resolver); 996 owner: def,
997 resolver: def.resolver(db),
998 exprs: Arena::default(),
999 pats: Arena::default(),
1000 source_map: BodySourceMap::default(),
1001 params: Vec::new(),
1002 body_expr: None,
1003 };
979 1004
980 match def { 1005 match def {
981 DefWithBody::Const(ref c) => collector.collect_const_body(&c.source(db).1,db), 1006 DefWithBody::Const(ref c) => collector.collect_const_body(&c.source(db).1),
982 DefWithBody::Function(ref f) => collector.collect_fn_body(&f.source(db).1,db), 1007 DefWithBody::Function(ref f) => collector.collect_fn_body(&f.source(db).1),
983 DefWithBody::Static(ref s) => collector.collect_static_body(&s.source(db).1,db), 1008 DefWithBody::Static(ref s) => collector.collect_static_body(&s.source(db).1),
984 } 1009 }
985 1010
986 let (body, source_map) = collector.finish(); 1011 let (body, source_map) = collector.finish();
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index c7849c995..a07624a19 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -101,7 +101,7 @@ fn parse_macro(
101 return Err(format!("Total tokens count exceed limit : count = {}", count)); 101 return Err(format!("Total tokens count exceed limit : count = {}", count));
102 } 102 }
103 103
104 Ok(mbe::token_tree_to_ast_item_list(&tt)) 104 Some(mbe::token_tree_to_ast_item_list(&tt))
105} 105}
106 106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 107#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs
index fbfff4fd7..a450d7b84 100644
--- a/crates/ra_hir/src/nameres.rs
+++ b/crates/ra_hir/src/nameres.rs
@@ -104,6 +104,7 @@ pub struct CrateDefMap {
104 /// However, do we want to put it as a global variable? 104 /// However, do we want to put it as a global variable?
105 poison_macros: FxHashSet<MacroDefId>, 105 poison_macros: FxHashSet<MacroDefId>,
106 106
107 local_macros: FxHashMap<Name, MacroDefId>,
107 diagnostics: Vec<DefDiagnostic>, 108 diagnostics: Vec<DefDiagnostic>,
108} 109}
109 110
@@ -209,6 +210,7 @@ impl CrateDefMap {
209 modules, 210 modules,
210 public_macros: FxHashMap::default(), 211 public_macros: FxHashMap::default(),
211 poison_macros: FxHashSet::default(), 212 poison_macros: FxHashSet::default(),
213 local_macros: FxHashMap::default(),
212 diagnostics: Vec::new(), 214 diagnostics: Vec::new(),
213 } 215 }
214 }; 216 };
@@ -270,6 +272,10 @@ impl CrateDefMap {
270 (res.resolved_def, res.segment_index) 272 (res.resolved_def, res.segment_index)
271 } 273 }
272 274
275 pub(crate) fn find_macro(&self, name: &Name) -> Option<&MacroDefId> {
276 self.public_macros.get(name).or(self.local_macros.get(name))
277 }
278
273 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change 279 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
274 // the result. 280 // the result.
275 fn resolve_path_fp( 281 fn resolve_path_fp(
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 4590a5184..762a61604 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -131,6 +131,8 @@ where
131 fn define_macro(&mut self, name: Name, macro_id: MacroDefId, export: bool) { 131 fn define_macro(&mut self, name: Name, macro_id: MacroDefId, export: bool) {
132 if export { 132 if export {
133 self.def_map.public_macros.insert(name.clone(), macro_id); 133 self.def_map.public_macros.insert(name.clone(), macro_id);
134 } else {
135 self.def_map.local_macros.insert(name.clone(), macro_id);
134 } 136 }
135 self.global_macro_scope.insert(name, macro_id); 137 self.global_macro_scope.insert(name, macro_id);
136 } 138 }
@@ -517,10 +519,10 @@ where
517 519
518 // Case 2: try to expand macro_rules from this crate, triggering 520 // Case 2: try to expand macro_rules from this crate, triggering
519 // recursive item collection. 521 // recursive item collection.
520 if let Some(&macro_id) = 522 if let Some(macro_id) =
521 mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) 523 mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(&name))
522 { 524 {
523 let macro_call_id = MacroCallLoc { def: macro_id, ast_id }.id(self.def_collector.db); 525 let macro_call_id = MacroCallLoc { def: *macro_id, ast_id }.id(self.def_collector.db);
524 526
525 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_id); 527 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_id);
526 return; 528 return;
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs
index 5449cddfd..1b129c752 100644
--- a/crates/ra_hir/src/path.rs
+++ b/crates/ra_hir/src/path.rs
@@ -126,6 +126,10 @@ impl Path {
126 } 126 }
127 self.segments.first().map(|s| &s.name) 127 self.segments.first().map(|s| &s.name)
128 } 128 }
129
130 pub fn expand_macro_expr(&self) -> Option<Name> {
131 self.as_ident().and_then(|name| Some(name.clone()))
132 }
129} 133}
130 134
131impl GenericArgs { 135impl GenericArgs {
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index f2c85eb66..1def032f9 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -6,6 +6,7 @@ use rustc_hash::FxHashMap;
6use crate::{ 6use crate::{
7 ModuleDef, 7 ModuleDef,
8 code_model_api::Crate, 8 code_model_api::Crate,
9 MacroDefId,
9 db::HirDatabase, 10 db::HirDatabase,
10 name::{Name, KnownName}, 11 name::{Name, KnownName},
11 nameres::{PerNs, CrateDefMap, CrateModuleId}, 12 nameres::{PerNs, CrateDefMap, CrateModuleId},
@@ -130,6 +131,10 @@ impl Resolver {
130 resolution 131 resolution
131 } 132 }
132 133
134 pub fn resolve_macro_call(&self, name: &Name) -> Option<&MacroDefId> {
135 self.module().and_then(|(module, _)| module.find_macro(name))
136 }
137
133 /// Returns the resolved path segments 138 /// Returns the resolved path segments
134 /// Which may be fully resolved, empty or partially resolved. 139 /// Which may be fully resolved, empty or partially resolved.
135 pub(crate) fn resolve_path_segments(&self, db: &impl HirDatabase, path: &Path) -> PathResult { 140 pub(crate) fn resolve_path_segments(&self, db: &impl HirDatabase, path: &Path) -> PathResult {
@@ -192,7 +197,7 @@ impl Resolver {
192 .flatten() 197 .flatten()
193 } 198 }
194 199
195 fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { 200 pub(crate) fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> {
196 self.scopes.iter().rev().find_map(|scope| match scope { 201 self.scopes.iter().rev().find_map(|scope| match scope {
197 Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)), 202 Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)),
198 203