aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/body
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-12-15 14:37:37 +0000
committerJonas Schievink <[email protected]>2020-12-15 14:37:37 +0000
commitc1cb5953820f26d4d0a614650bc8c50cbc5a3ce6 (patch)
tree01ba67d97ce6f261154df59b268fe924af9add2a /crates/hir_def/src/body
parent39aae835fd70d06092c1be1add6eef3984439529 (diff)
Move to upstream `macro_rules!` model
Diffstat (limited to 'crates/hir_def/src/body')
-rw-r--r--crates/hir_def/src/body/lower.rs134
1 files changed, 69 insertions, 65 deletions
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 6c0de3ee8..bdba4c33e 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -566,66 +566,52 @@ impl ExprCollector<'_> {
566 syntax_ptr: AstPtr<ast::Expr>, 566 syntax_ptr: AstPtr<ast::Expr>,
567 mut collector: F, 567 mut collector: F,
568 ) { 568 ) {
569 if let Some(name) = e.is_macro_rules().map(|it| it.as_name()) { 569 // File containing the macro call. Expansion errors will be attached here.
570 let mac = MacroDefId { 570 let outer_file = self.expander.current_file_id;
571 krate: Some(self.expander.module.krate),
572 ast_id: Some(self.expander.ast_id(&e)),
573 kind: MacroDefKind::Declarative,
574 local_inner: false,
575 };
576 self.body.item_scope.define_legacy_macro(name, mac);
577 571
578 // FIXME: do we still need to allocate this as missing ? 572 let macro_call = self.expander.to_source(AstPtr::new(&e));
579 collector(self, None); 573 let res = self.expander.enter_expand(self.db, Some(&self.body.item_scope), e);
580 } else { 574
581 // File containing the macro call. Expansion errors will be attached here. 575 match &res.err {
582 let outer_file = self.expander.current_file_id; 576 Some(ExpandError::UnresolvedProcMacro) => {
583 577 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro(
584 let macro_call = self.expander.to_source(AstPtr::new(&e)); 578 UnresolvedProcMacro {
585 let res = self.expander.enter_expand(self.db, Some(&self.body.item_scope), e);
586
587 match &res.err {
588 Some(ExpandError::UnresolvedProcMacro) => {
589 self.source_map.diagnostics.push(BodyDiagnostic::UnresolvedProcMacro(
590 UnresolvedProcMacro {
591 file: outer_file,
592 node: syntax_ptr.into(),
593 precise_location: None,
594 macro_name: None,
595 },
596 ));
597 }
598 Some(err) => {
599 self.source_map.diagnostics.push(BodyDiagnostic::MacroError(MacroError {
600 file: outer_file, 579 file: outer_file,
601 node: syntax_ptr.into(), 580 node: syntax_ptr.into(),
602 message: err.to_string(), 581 precise_location: None,
603 })); 582 macro_name: None,
604 } 583 },
605 None => {} 584 ));
585 }
586 Some(err) => {
587 self.source_map.diagnostics.push(BodyDiagnostic::MacroError(MacroError {
588 file: outer_file,
589 node: syntax_ptr.into(),
590 message: err.to_string(),
591 }));
606 } 592 }
593 None => {}
594 }
607 595
608 match res.value { 596 match res.value {
609 Some((mark, expansion)) => { 597 Some((mark, expansion)) => {
610 // FIXME: Statements are too complicated to recover from error for now. 598 // FIXME: Statements are too complicated to recover from error for now.
611 // It is because we don't have any hygenine for local variable expansion right now. 599 // It is because we don't have any hygenine for local variable expansion right now.
612 if T::can_cast(syntax::SyntaxKind::MACRO_STMTS) && res.err.is_some() { 600 if T::can_cast(syntax::SyntaxKind::MACRO_STMTS) && res.err.is_some() {
613 self.expander.exit(self.db, mark); 601 self.expander.exit(self.db, mark);
614 collector(self, None); 602 collector(self, None);
615 } else { 603 } else {
616 self.source_map 604 self.source_map.expansions.insert(macro_call, self.expander.current_file_id);
617 .expansions
618 .insert(macro_call, self.expander.current_file_id);
619 605
620 let item_tree = self.db.item_tree(self.expander.current_file_id); 606 let item_tree = self.db.item_tree(self.expander.current_file_id);
621 self.item_trees.insert(self.expander.current_file_id, item_tree); 607 self.item_trees.insert(self.expander.current_file_id, item_tree);
622 608
623 collector(self, Some(expansion)); 609 let id = collector(self, Some(expansion));
624 self.expander.exit(self.db, mark); 610 self.expander.exit(self.db, mark);
625 } 611 id
626 } 612 }
627 None => collector(self, None),
628 } 613 }
614 None => collector(self, None),
629 } 615 }
630 } 616 }
631 617
@@ -785,26 +771,44 @@ impl ExprCollector<'_> {
785 | ast::Item::ExternCrate(_) 771 | ast::Item::ExternCrate(_)
786 | ast::Item::Module(_) 772 | ast::Item::Module(_)
787 | ast::Item::MacroCall(_) => return None, 773 | ast::Item::MacroCall(_) => return None,
774 ast::Item::MacroRules(def) => {
775 return Some(Either::Right(def));
776 }
788 }; 777 };
789 778
790 Some((def, name)) 779 Some(Either::Left((def, name)))
791 }) 780 })
792 .collect::<Vec<_>>(); 781 .collect::<Vec<_>>();
793 782
794 for (def, name) in items { 783 for either in items {
795 self.body.item_scope.define_def(def); 784 match either {
796 if let Some(name) = name { 785 Either::Left((def, name)) => {
797 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly 786 self.body.item_scope.define_def(def);
798 let has_constructor = match def { 787 if let Some(name) = name {
799 ModuleDefId::AdtId(AdtId::StructId(s)) => { 788 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly
800 self.db.struct_data(s).variant_data.kind() != StructKind::Record 789 let has_constructor = match def {
790 ModuleDefId::AdtId(AdtId::StructId(s)) => {
791 self.db.struct_data(s).variant_data.kind() != StructKind::Record
792 }
793 _ => true,
794 };
795 self.body.item_scope.push_res(
796 name.as_name(),
797 crate::per_ns::PerNs::from_def(def, vis, has_constructor),
798 );
801 } 799 }
802 _ => true, 800 }
803 }; 801 Either::Right(e) => {
804 self.body.item_scope.push_res( 802 let mac = MacroDefId {
805 name.as_name(), 803 krate: Some(self.expander.module.krate),
806 crate::per_ns::PerNs::from_def(def, vis, has_constructor), 804 ast_id: Some(self.expander.ast_id(&e)),
807 ); 805 kind: MacroDefKind::Declarative,
806 local_inner: false,
807 };
808 if let Some(name) = e.name() {
809 self.body.item_scope.define_legacy_macro(name.as_name(), mac);
810 }
811 }
808 } 812 }
809 } 813 }
810 } 814 }