diff options
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/attr.rs | 41 | ||||
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 34 | ||||
-rw-r--r-- | crates/hir_def/src/child_by_source.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 5 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 13 | ||||
-rw-r--r-- | crates/hir_def/src/nameres.rs | 28 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 23 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/path_resolution.rs | 51 |
9 files changed, 132 insertions, 69 deletions
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index d9df7564d..786fad6e1 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -9,7 +9,7 @@ use std::{ | |||
9 | use base_db::CrateId; | 9 | use base_db::CrateId; |
10 | use cfg::{CfgExpr, CfgOptions}; | 10 | use cfg::{CfgExpr, CfgOptions}; |
11 | use either::Either; | 11 | use either::Either; |
12 | use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile}; | 12 | use hir_expand::{hygiene::Hygiene, name::AsName, AstId, AttrId, InFile}; |
13 | use itertools::Itertools; | 13 | use itertools::Itertools; |
14 | use la_arena::ArenaMap; | 14 | use la_arena::ArenaMap; |
15 | use mbe::ast_to_token_tree; | 15 | use mbe::ast_to_token_tree; |
@@ -98,13 +98,16 @@ impl RawAttrs { | |||
98 | pub(crate) fn new(owner: &dyn ast::AttrsOwner, hygiene: &Hygiene) -> Self { | 98 | pub(crate) fn new(owner: &dyn ast::AttrsOwner, hygiene: &Hygiene) -> Self { |
99 | let entries = collect_attrs(owner) | 99 | let entries = collect_attrs(owner) |
100 | .enumerate() | 100 | .enumerate() |
101 | .flat_map(|(i, attr)| match attr { | 101 | .flat_map(|(i, attr)| { |
102 | Either::Left(attr) => Attr::from_src(attr, hygiene, i as u32), | 102 | let index = AttrId(i as u32); |
103 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { | 103 | match attr { |
104 | index: i as u32, | 104 | Either::Left(attr) => Attr::from_src(attr, hygiene, index), |
105 | input: Some(AttrInput::Literal(SmolStr::new(doc))), | 105 | Either::Right(comment) => comment.doc_comment().map(|doc| Attr { |
106 | path: Interned::new(ModPath::from(hir_expand::name!(doc))), | 106 | id: index, |
107 | }), | 107 | input: Some(AttrInput::Literal(SmolStr::new(doc))), |
108 | path: Interned::new(ModPath::from(hir_expand::name!(doc))), | ||
109 | }), | ||
110 | } | ||
108 | }) | 111 | }) |
109 | .collect::<Arc<_>>(); | 112 | .collect::<Arc<_>>(); |
110 | 113 | ||
@@ -161,7 +164,7 @@ impl RawAttrs { | |||
161 | let cfg = parts.next().unwrap(); | 164 | let cfg = parts.next().unwrap(); |
162 | let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() }; | 165 | let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() }; |
163 | let cfg = CfgExpr::parse(&cfg); | 166 | let cfg = CfgExpr::parse(&cfg); |
164 | let index = attr.index; | 167 | let index = attr.id; |
165 | let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| { | 168 | let attrs = parts.filter(|a| !a.is_empty()).filter_map(|attr| { |
166 | let tree = Subtree { delimiter: None, token_trees: attr.to_vec() }; | 169 | let tree = Subtree { delimiter: None, token_trees: attr.to_vec() }; |
167 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; | 170 | let attr = ast::Attr::parse(&format!("#[{}]", tree)).ok()?; |
@@ -468,7 +471,7 @@ impl AttrsWithOwner { | |||
468 | ) -> Option<(Documentation, DocsRangeMap)> { | 471 | ) -> Option<(Documentation, DocsRangeMap)> { |
469 | // FIXME: code duplication in `docs` above | 472 | // FIXME: code duplication in `docs` above |
470 | let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_ref()? { | 473 | let docs = self.by_key("doc").attrs().flat_map(|attr| match attr.input.as_ref()? { |
471 | AttrInput::Literal(s) => Some((s, attr.index)), | 474 | AttrInput::Literal(s) => Some((s, attr.id)), |
472 | AttrInput::TokenTree(_) => None, | 475 | AttrInput::TokenTree(_) => None, |
473 | }); | 476 | }); |
474 | let indent = docs | 477 | let indent = docs |
@@ -560,8 +563,8 @@ impl AttrSourceMap { | |||
560 | /// the attribute represented by `Attr`. | 563 | /// the attribute represented by `Attr`. |
561 | pub fn source_of(&self, attr: &Attr) -> InFile<&Either<ast::Attr, ast::Comment>> { | 564 | pub fn source_of(&self, attr: &Attr) -> InFile<&Either<ast::Attr, ast::Comment>> { |
562 | self.attrs | 565 | self.attrs |
563 | .get(attr.index as usize) | 566 | .get(attr.id.0 as usize) |
564 | .unwrap_or_else(|| panic!("cannot find `Attr` at index {}", attr.index)) | 567 | .unwrap_or_else(|| panic!("cannot find `Attr` at index {:?}", attr.id)) |
565 | .as_ref() | 568 | .as_ref() |
566 | } | 569 | } |
567 | } | 570 | } |
@@ -572,7 +575,7 @@ pub struct DocsRangeMap { | |||
572 | // (docstring-line-range, attr_index, attr-string-range) | 575 | // (docstring-line-range, attr_index, attr-string-range) |
573 | // a mapping from the text range of a line of the [`Documentation`] to the attribute index and | 576 | // a mapping from the text range of a line of the [`Documentation`] to the attribute index and |
574 | // the original (untrimmed) syntax doc line | 577 | // the original (untrimmed) syntax doc line |
575 | mapping: Vec<(TextRange, u32, TextRange)>, | 578 | mapping: Vec<(TextRange, AttrId, TextRange)>, |
576 | } | 579 | } |
577 | 580 | ||
578 | impl DocsRangeMap { | 581 | impl DocsRangeMap { |
@@ -585,7 +588,7 @@ impl DocsRangeMap { | |||
585 | 588 | ||
586 | let relative_range = range - line_docs_range.start(); | 589 | let relative_range = range - line_docs_range.start(); |
587 | 590 | ||
588 | let &InFile { file_id, value: ref source } = &self.source[idx as usize]; | 591 | let &InFile { file_id, value: ref source } = &self.source[idx.0 as usize]; |
589 | match source { | 592 | match source { |
590 | Either::Left(_) => None, // FIXME, figure out a nice way to handle doc attributes here | 593 | Either::Left(_) => None, // FIXME, figure out a nice way to handle doc attributes here |
591 | // as well as for whats done in syntax highlight doc injection | 594 | // as well as for whats done in syntax highlight doc injection |
@@ -606,7 +609,7 @@ impl DocsRangeMap { | |||
606 | 609 | ||
607 | #[derive(Debug, Clone, PartialEq, Eq)] | 610 | #[derive(Debug, Clone, PartialEq, Eq)] |
608 | pub struct Attr { | 611 | pub struct Attr { |
609 | index: u32, | 612 | pub(crate) id: AttrId, |
610 | pub(crate) path: Interned<ModPath>, | 613 | pub(crate) path: Interned<ModPath>, |
611 | pub(crate) input: Option<AttrInput>, | 614 | pub(crate) input: Option<AttrInput>, |
612 | } | 615 | } |
@@ -620,7 +623,7 @@ pub enum AttrInput { | |||
620 | } | 623 | } |
621 | 624 | ||
622 | impl Attr { | 625 | impl Attr { |
623 | fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option<Attr> { | 626 | fn from_src(ast: ast::Attr, hygiene: &Hygiene, id: AttrId) -> Option<Attr> { |
624 | let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?); | 627 | let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?); |
625 | let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { | 628 | let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { |
626 | let value = match lit.kind() { | 629 | let value = match lit.kind() { |
@@ -633,7 +636,7 @@ impl Attr { | |||
633 | } else { | 636 | } else { |
634 | None | 637 | None |
635 | }; | 638 | }; |
636 | Some(Attr { index, path, input }) | 639 | Some(Attr { id, path, input }) |
637 | } | 640 | } |
638 | 641 | ||
639 | /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths | 642 | /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths |
@@ -748,9 +751,7 @@ fn collect_attrs( | |||
748 | .chain(inner_docs.into_iter().flatten()) | 751 | .chain(inner_docs.into_iter().flatten()) |
749 | .map(|docs_text| (docs_text.syntax().text_range().start(), Either::Right(docs_text))); | 752 | .map(|docs_text| (docs_text.syntax().text_range().start(), Either::Right(docs_text))); |
750 | // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved | 753 | // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved |
751 | let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect(); | 754 | docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).map(|(_, attr)| attr) |
752 | |||
753 | attrs.into_iter().map(|(_, attr)| attr) | ||
754 | } | 755 | } |
755 | 756 | ||
756 | pub(crate) fn variants_attrs_source_map( | 757 | pub(crate) fn variants_attrs_source_map( |
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index bfb75a8a5..ed07d6928 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -531,8 +531,9 @@ impl ExprCollector<'_> { | |||
531 | } | 531 | } |
532 | } | 532 | } |
533 | ast::Expr::MacroCall(e) => { | 533 | ast::Expr::MacroCall(e) => { |
534 | let macro_ptr = AstPtr::new(&e); | ||
534 | let mut ids = vec![]; | 535 | let mut ids = vec![]; |
535 | self.collect_macro_call(e, syntax_ptr.clone(), true, |this, expansion| { | 536 | self.collect_macro_call(e, macro_ptr, true, |this, expansion| { |
536 | ids.push(match expansion { | 537 | ids.push(match expansion { |
537 | Some(it) => this.collect_expr(it), | 538 | Some(it) => this.collect_expr(it), |
538 | None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), | 539 | None => this.alloc_expr(Expr::Missing, syntax_ptr.clone()), |
@@ -555,7 +556,7 @@ impl ExprCollector<'_> { | |||
555 | fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>( | 556 | fn collect_macro_call<F: FnMut(&mut Self, Option<T>), T: ast::AstNode>( |
556 | &mut self, | 557 | &mut self, |
557 | e: ast::MacroCall, | 558 | e: ast::MacroCall, |
558 | syntax_ptr: AstPtr<ast::Expr>, | 559 | syntax_ptr: AstPtr<ast::MacroCall>, |
559 | is_error_recoverable: bool, | 560 | is_error_recoverable: bool, |
560 | mut collector: F, | 561 | mut collector: F, |
561 | ) { | 562 | ) { |
@@ -643,10 +644,14 @@ impl ExprCollector<'_> { | |||
643 | 644 | ||
644 | // Note that macro could be expended to multiple statements | 645 | // Note that macro could be expended to multiple statements |
645 | if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { | 646 | if let Some(ast::Expr::MacroCall(m)) = stmt.expr() { |
647 | let macro_ptr = AstPtr::new(&m); | ||
646 | let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); | 648 | let syntax_ptr = AstPtr::new(&stmt.expr().unwrap()); |
647 | 649 | ||
648 | self.collect_macro_call(m, syntax_ptr.clone(), false, |this, expansion| { | 650 | self.collect_macro_call( |
649 | match expansion { | 651 | m, |
652 | macro_ptr, | ||
653 | false, | ||
654 | |this, expansion| match expansion { | ||
650 | Some(expansion) => { | 655 | Some(expansion) => { |
651 | let statements: ast::MacroStmts = expansion; | 656 | let statements: ast::MacroStmts = expansion; |
652 | 657 | ||
@@ -660,8 +665,8 @@ impl ExprCollector<'_> { | |||
660 | let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); | 665 | let expr = this.alloc_expr(Expr::Missing, syntax_ptr.clone()); |
661 | this.statements_in_scope.push(Statement::Expr(expr)); | 666 | this.statements_in_scope.push(Statement::Expr(expr)); |
662 | } | 667 | } |
663 | } | 668 | }, |
664 | }); | 669 | ); |
665 | } else { | 670 | } else { |
666 | let expr = self.collect_expr_opt(stmt.expr()); | 671 | let expr = self.collect_expr_opt(stmt.expr()); |
667 | self.statements_in_scope.push(Statement::Expr(expr)); | 672 | self.statements_in_scope.push(Statement::Expr(expr)); |
@@ -848,8 +853,23 @@ impl ExprCollector<'_> { | |||
848 | Pat::Missing | 853 | Pat::Missing |
849 | } | 854 | } |
850 | } | 855 | } |
856 | ast::Pat::MacroPat(mac) => match mac.macro_call() { | ||
857 | Some(call) => { | ||
858 | let macro_ptr = AstPtr::new(&call); | ||
859 | let mut pat = None; | ||
860 | self.collect_macro_call(call, macro_ptr, true, |this, expanded_pat| { | ||
861 | pat = Some(this.collect_pat_opt(expanded_pat)); | ||
862 | }); | ||
863 | |||
864 | match pat { | ||
865 | Some(pat) => return pat, | ||
866 | None => Pat::Missing, | ||
867 | } | ||
868 | } | ||
869 | None => Pat::Missing, | ||
870 | }, | ||
851 | // FIXME: implement | 871 | // FIXME: implement |
852 | ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing, | 872 | ast::Pat::RangePat(_) => Pat::Missing, |
853 | }; | 873 | }; |
854 | let ptr = AstPtr::new(&pat); | 874 | let ptr = AstPtr::new(&pat); |
855 | self.alloc_pat(pattern, Either::Left(ptr)) | 875 | self.alloc_pat(pattern, Either::Left(ptr)) |
diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs index f40a7f80d..f2e809ca9 100644 --- a/crates/hir_def/src/child_by_source.rs +++ b/crates/hir_def/src/child_by_source.rs | |||
@@ -80,6 +80,10 @@ impl ChildBySource for ModuleId { | |||
80 | impl ChildBySource for ItemScope { | 80 | impl ChildBySource for ItemScope { |
81 | fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { | 81 | fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap) { |
82 | self.declarations().for_each(|item| add_module_def(db, res, item)); | 82 | self.declarations().for_each(|item| add_module_def(db, res, item)); |
83 | self.unnamed_consts().for_each(|konst| { | ||
84 | let src = konst.lookup(db).source(db); | ||
85 | res[keys::CONST].insert(src, konst); | ||
86 | }); | ||
83 | self.impls().for_each(|imp| add_impl(db, res, imp)); | 87 | self.impls().for_each(|imp| add_impl(db, res, imp)); |
84 | 88 | ||
85 | fn add_module_def(db: &dyn DefDatabase, map: &mut DynMap, item: ModuleDefId) { | 89 | fn add_module_def(db: &dyn DefDatabase, map: &mut DynMap, item: ModuleDefId) { |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 240662486..94e08f835 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -99,6 +99,11 @@ impl ItemTree { | |||
99 | // items. | 99 | // items. |
100 | ctx.lower_macro_stmts(stmts) | 100 | ctx.lower_macro_stmts(stmts) |
101 | }, | 101 | }, |
102 | ast::Pat(_pat) => { | ||
103 | // FIXME: This occurs because macros in pattern position are treated as inner | ||
104 | // items and expanded during block DefMap computation | ||
105 | return Default::default(); | ||
106 | }, | ||
102 | ast::Expr(e) => { | 107 | ast::Expr(e) => { |
103 | // Macros can expand to expressions. We return an empty item tree in this case, but | 108 | // Macros can expand to expressions. We return an empty item tree in this case, but |
104 | // still need to collect inner items. | 109 | // still need to collect inner items. |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index c5629af24..45b099cf3 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -189,7 +189,7 @@ impl Ctx { | |||
189 | block_stack.push(self.source_ast_id_map.ast_id(&block)); | 189 | block_stack.push(self.source_ast_id_map.ast_id(&block)); |
190 | }, | 190 | }, |
191 | ast::Item(item) => { | 191 | ast::Item(item) => { |
192 | // FIXME: This triggers for macro calls in expression position | 192 | // FIXME: This triggers for macro calls in expression/pattern/type position |
193 | let mod_items = self.lower_mod_item(&item, true); | 193 | let mod_items = self.lower_mod_item(&item, true); |
194 | let current_block = block_stack.last(); | 194 | let current_block = block_stack.last(); |
195 | if let (Some(mod_items), Some(block)) = (mod_items, current_block) { | 195 | if let (Some(mod_items), Some(block)) = (mod_items, current_block) { |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index e2af0e514..d69116d51 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -62,7 +62,7 @@ use hir_expand::{ | |||
62 | ast_id_map::FileAstId, | 62 | ast_id_map::FileAstId, |
63 | eager::{expand_eager_macro, ErrorEmitted, ErrorSink}, | 63 | eager::{expand_eager_macro, ErrorEmitted, ErrorSink}, |
64 | hygiene::Hygiene, | 64 | hygiene::Hygiene, |
65 | AstId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, | 65 | AstId, AttrId, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, |
66 | }; | 66 | }; |
67 | use la_arena::Idx; | 67 | use la_arena::Idx; |
68 | use nameres::DefMap; | 68 | use nameres::DefMap; |
@@ -690,13 +690,16 @@ fn macro_call_as_call_id( | |||
690 | ) | 690 | ) |
691 | .map(MacroCallId::from) | 691 | .map(MacroCallId::from) |
692 | } else { | 692 | } else { |
693 | Ok(def.as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike(call.ast_id)).into()) | 693 | Ok(def |
694 | .as_lazy_macro(db.upcast(), krate, MacroCallKind::FnLike { ast_id: call.ast_id }) | ||
695 | .into()) | ||
694 | }; | 696 | }; |
695 | Ok(res) | 697 | Ok(res) |
696 | } | 698 | } |
697 | 699 | ||
698 | fn derive_macro_as_call_id( | 700 | fn derive_macro_as_call_id( |
699 | item_attr: &AstIdWithPath<ast::Item>, | 701 | item_attr: &AstIdWithPath<ast::Item>, |
702 | derive_attr: AttrId, | ||
700 | db: &dyn db::DefDatabase, | 703 | db: &dyn db::DefDatabase, |
701 | krate: CrateId, | 704 | krate: CrateId, |
702 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, | 705 | resolver: impl Fn(path::ModPath) -> Option<MacroDefId>, |
@@ -707,7 +710,11 @@ fn derive_macro_as_call_id( | |||
707 | .as_lazy_macro( | 710 | .as_lazy_macro( |
708 | db.upcast(), | 711 | db.upcast(), |
709 | krate, | 712 | krate, |
710 | MacroCallKind::Derive(item_attr.ast_id, last_segment.to_string()), | 713 | MacroCallKind::Derive { |
714 | ast_id: item_attr.ast_id, | ||
715 | derive_name: last_segment.to_string(), | ||
716 | derive_attr, | ||
717 | }, | ||
711 | ) | 718 | ) |
712 | .into(); | 719 | .into(); |
713 | Ok(res) | 720 | Ok(res) |
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs index 7dd68219f..9e181751c 100644 --- a/crates/hir_def/src/nameres.rs +++ b/crates/hir_def/src/nameres.rs | |||
@@ -613,12 +613,12 @@ mod diagnostics { | |||
613 | DiagnosticKind::UnresolvedProcMacro { ast } => { | 613 | DiagnosticKind::UnresolvedProcMacro { ast } => { |
614 | let mut precise_location = None; | 614 | let mut precise_location = None; |
615 | let (file, ast, name) = match ast { | 615 | let (file, ast, name) = match ast { |
616 | MacroCallKind::FnLike(ast) => { | 616 | MacroCallKind::FnLike { ast_id } => { |
617 | let node = ast.to_node(db.upcast()); | 617 | let node = ast_id.to_node(db.upcast()); |
618 | (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None) | 618 | (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node)), None) |
619 | } | 619 | } |
620 | MacroCallKind::Derive(ast, name) => { | 620 | MacroCallKind::Derive { ast_id, derive_name, .. } => { |
621 | let node = ast.to_node(db.upcast()); | 621 | let node = ast_id.to_node(db.upcast()); |
622 | 622 | ||
623 | // Compute the precise location of the macro name's token in the derive | 623 | // Compute the precise location of the macro name's token in the derive |
624 | // list. | 624 | // list. |
@@ -639,7 +639,7 @@ mod diagnostics { | |||
639 | }); | 639 | }); |
640 | for token in tokens { | 640 | for token in tokens { |
641 | if token.kind() == SyntaxKind::IDENT | 641 | if token.kind() == SyntaxKind::IDENT |
642 | && token.text() == name.as_str() | 642 | && token.text() == derive_name.as_str() |
643 | { | 643 | { |
644 | precise_location = Some(token.text_range()); | 644 | precise_location = Some(token.text_range()); |
645 | break 'outer; | 645 | break 'outer; |
@@ -648,9 +648,9 @@ mod diagnostics { | |||
648 | } | 648 | } |
649 | 649 | ||
650 | ( | 650 | ( |
651 | ast.file_id, | 651 | ast_id.file_id, |
652 | SyntaxNodePtr::from(AstPtr::new(&node)), | 652 | SyntaxNodePtr::from(AstPtr::new(&node)), |
653 | Some(name.clone()), | 653 | Some(derive_name.clone()), |
654 | ) | 654 | ) |
655 | } | 655 | } |
656 | }; | 656 | }; |
@@ -669,13 +669,13 @@ mod diagnostics { | |||
669 | 669 | ||
670 | DiagnosticKind::MacroError { ast, message } => { | 670 | DiagnosticKind::MacroError { ast, message } => { |
671 | let (file, ast) = match ast { | 671 | let (file, ast) = match ast { |
672 | MacroCallKind::FnLike(ast) => { | 672 | MacroCallKind::FnLike { ast_id, .. } => { |
673 | let node = ast.to_node(db.upcast()); | 673 | let node = ast_id.to_node(db.upcast()); |
674 | (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node))) | 674 | (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node))) |
675 | } | 675 | } |
676 | MacroCallKind::Derive(ast, _) => { | 676 | MacroCallKind::Derive { ast_id, .. } => { |
677 | let node = ast.to_node(db.upcast()); | 677 | let node = ast_id.to_node(db.upcast()); |
678 | (ast.file_id, SyntaxNodePtr::from(AstPtr::new(&node))) | 678 | (ast_id.file_id, SyntaxNodePtr::from(AstPtr::new(&node))) |
679 | } | 679 | } |
680 | }; | 680 | }; |
681 | sink.push(MacroError { file, node: ast, message: message.clone() }); | 681 | sink.push(MacroError { file, node: ast, message: message.clone() }); |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 6dbbe2d05..fb4ddff5e 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -13,7 +13,7 @@ use hir_expand::{ | |||
13 | builtin_macro::find_builtin_macro, | 13 | builtin_macro::find_builtin_macro, |
14 | name::{AsName, Name}, | 14 | name::{AsName, Name}, |
15 | proc_macro::ProcMacroExpander, | 15 | proc_macro::ProcMacroExpander, |
16 | HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, | 16 | AttrId, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, |
17 | }; | 17 | }; |
18 | use hir_expand::{InFile, MacroCallLoc}; | 18 | use hir_expand::{InFile, MacroCallLoc}; |
19 | use rustc_hash::{FxHashMap, FxHashSet}; | 19 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -216,7 +216,7 @@ struct MacroDirective { | |||
216 | #[derive(Clone, Debug, Eq, PartialEq)] | 216 | #[derive(Clone, Debug, Eq, PartialEq)] |
217 | enum MacroDirectiveKind { | 217 | enum MacroDirectiveKind { |
218 | FnLike { ast_id: AstIdWithPath<ast::MacroCall> }, | 218 | FnLike { ast_id: AstIdWithPath<ast::MacroCall> }, |
219 | Derive { ast_id: AstIdWithPath<ast::Item> }, | 219 | Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId }, |
220 | } | 220 | } |
221 | 221 | ||
222 | struct DefData<'a> { | 222 | struct DefData<'a> { |
@@ -478,7 +478,7 @@ impl DefCollector<'_> { | |||
478 | self.def_map.edition, | 478 | self.def_map.edition, |
479 | ); | 479 | ); |
480 | 480 | ||
481 | let res = self.def_map.resolve_name_in_extern_prelude(&extern_crate.name); | 481 | let res = self.def_map.resolve_name_in_extern_prelude(self.db, &extern_crate.name); |
482 | 482 | ||
483 | if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { | 483 | if let Some(ModuleDefId::ModuleId(m)) = res.take_types() { |
484 | cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); | 484 | cov_mark::hit!(macro_rules_from_other_crates_are_visible_with_macro_use); |
@@ -534,6 +534,7 @@ impl DefCollector<'_> { | |||
534 | log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); | 534 | log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); |
535 | if import.is_extern_crate { | 535 | if import.is_extern_crate { |
536 | let res = self.def_map.resolve_name_in_extern_prelude( | 536 | let res = self.def_map.resolve_name_in_extern_prelude( |
537 | self.db, | ||
537 | &import | 538 | &import |
538 | .path | 539 | .path |
539 | .as_ident() | 540 | .as_ident() |
@@ -831,10 +832,14 @@ impl DefCollector<'_> { | |||
831 | Err(UnresolvedMacro) | Ok(Err(_)) => {} | 832 | Err(UnresolvedMacro) | Ok(Err(_)) => {} |
832 | } | 833 | } |
833 | } | 834 | } |
834 | MacroDirectiveKind::Derive { ast_id } => { | 835 | MacroDirectiveKind::Derive { ast_id, derive_attr } => { |
835 | match derive_macro_as_call_id(ast_id, self.db, self.def_map.krate, |path| { | 836 | match derive_macro_as_call_id( |
836 | self.resolve_derive_macro(directive.module_id, &path) | 837 | ast_id, |
837 | }) { | 838 | *derive_attr, |
839 | self.db, | ||
840 | self.def_map.krate, | ||
841 | |path| self.resolve_derive_macro(directive.module_id, &path), | ||
842 | ) { | ||
838 | Ok(call_id) => { | 843 | Ok(call_id) => { |
839 | resolved.push((directive.module_id, call_id, directive.depth)); | 844 | resolved.push((directive.module_id, call_id, directive.depth)); |
840 | res = ReachedFixedPoint::No; | 845 | res = ReachedFixedPoint::No; |
@@ -1368,7 +1373,7 @@ impl ModCollector<'_, '_> { | |||
1368 | self.def_collector.unexpanded_macros.push(MacroDirective { | 1373 | self.def_collector.unexpanded_macros.push(MacroDirective { |
1369 | module_id: self.module_id, | 1374 | module_id: self.module_id, |
1370 | depth: self.macro_depth + 1, | 1375 | depth: self.macro_depth + 1, |
1371 | kind: MacroDirectiveKind::Derive { ast_id }, | 1376 | kind: MacroDirectiveKind::Derive { ast_id, derive_attr: derive.id }, |
1372 | }); | 1377 | }); |
1373 | } | 1378 | } |
1374 | } | 1379 | } |
@@ -1520,7 +1525,7 @@ impl ModCollector<'_, '_> { | |||
1520 | // Built-in macro failed eager expansion. | 1525 | // Built-in macro failed eager expansion. |
1521 | self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error( | 1526 | self.def_collector.def_map.diagnostics.push(DefDiagnostic::macro_error( |
1522 | self.module_id, | 1527 | self.module_id, |
1523 | MacroCallKind::FnLike(ast_id.ast_id), | 1528 | MacroCallKind::FnLike { ast_id: ast_id.ast_id }, |
1524 | error.unwrap().to_string(), | 1529 | error.unwrap().to_string(), |
1525 | )); | 1530 | )); |
1526 | return; | 1531 | return; |
diff --git a/crates/hir_def/src/nameres/path_resolution.rs b/crates/hir_def/src/nameres/path_resolution.rs index 60471937c..ccc9f22eb 100644 --- a/crates/hir_def/src/nameres/path_resolution.rs +++ b/crates/hir_def/src/nameres/path_resolution.rs | |||
@@ -60,12 +60,26 @@ impl ResolvePathResult { | |||
60 | } | 60 | } |
61 | 61 | ||
62 | impl DefMap { | 62 | impl DefMap { |
63 | pub(super) fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs { | 63 | pub(super) fn resolve_name_in_extern_prelude( |
64 | &self, | ||
65 | db: &dyn DefDatabase, | ||
66 | name: &Name, | ||
67 | ) -> PerNs { | ||
64 | if name == &name!(self) { | 68 | if name == &name!(self) { |
65 | cov_mark::hit!(extern_crate_self_as); | 69 | cov_mark::hit!(extern_crate_self_as); |
66 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); | 70 | return PerNs::types(self.module_id(self.root).into(), Visibility::Public); |
67 | } | 71 | } |
68 | self.extern_prelude | 72 | |
73 | let arc; | ||
74 | let root = match self.block { | ||
75 | Some(_) => { | ||
76 | arc = self.crate_root(db).def_map(db); | ||
77 | &*arc | ||
78 | } | ||
79 | None => self, | ||
80 | }; | ||
81 | |||
82 | root.extern_prelude | ||
69 | .get(name) | 83 | .get(name) |
70 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) | 84 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)) |
71 | } | 85 | } |
@@ -191,7 +205,7 @@ impl DefMap { | |||
191 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), | 205 | None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), |
192 | }; | 206 | }; |
193 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); | 207 | log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); |
194 | self.resolve_name_in_crate_root_or_extern_prelude(&segment) | 208 | self.resolve_name_in_crate_root_or_extern_prelude(db, &segment) |
195 | } | 209 | } |
196 | PathKind::Plain => { | 210 | PathKind::Plain => { |
197 | let (_, segment) = match segments.next() { | 211 | let (_, segment) = match segments.next() { |
@@ -384,24 +398,31 @@ impl DefMap { | |||
384 | } | 398 | } |
385 | } | 399 | } |
386 | }; | 400 | }; |
387 | // Give precedence to names in outer `DefMap`s over the extern prelude; only check prelude | 401 | let from_extern_prelude = self |
388 | // from the crate DefMap. | 402 | .extern_prelude |
389 | let from_extern_prelude = match self.block { | 403 | .get(name) |
390 | Some(_) => PerNs::none(), | 404 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)); |
391 | None => self | ||
392 | .extern_prelude | ||
393 | .get(name) | ||
394 | .map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public)), | ||
395 | }; | ||
396 | 405 | ||
397 | let from_prelude = self.resolve_in_prelude(db, name); | 406 | let from_prelude = self.resolve_in_prelude(db, name); |
398 | 407 | ||
399 | from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) | 408 | from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude) |
400 | } | 409 | } |
401 | 410 | ||
402 | fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { | 411 | fn resolve_name_in_crate_root_or_extern_prelude( |
403 | let from_crate_root = self[self.root].scope.get(name); | 412 | &self, |
404 | let from_extern_prelude = self.resolve_name_in_extern_prelude(name); | 413 | db: &dyn DefDatabase, |
414 | name: &Name, | ||
415 | ) -> PerNs { | ||
416 | let arc; | ||
417 | let crate_def_map = match self.block { | ||
418 | Some(_) => { | ||
419 | arc = self.crate_root(db).def_map(db); | ||
420 | &arc | ||
421 | } | ||
422 | None => self, | ||
423 | }; | ||
424 | let from_crate_root = crate_def_map[crate_def_map.root].scope.get(name); | ||
425 | let from_extern_prelude = self.resolve_name_in_extern_prelude(db, name); | ||
405 | 426 | ||
406 | from_crate_root.or(from_extern_prelude) | 427 | from_crate_root.or(from_extern_prelude) |
407 | } | 428 | } |