diff options
Diffstat (limited to 'crates/hir_def/src/body')
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 134 |
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 | } |