diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/body.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 48 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 28 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres.rs | 9 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 48 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/tests.rs | 22 | ||||
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir_def/src/visibility.rs | 33 |
8 files changed, 177 insertions, 38 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 57ba45b45..2bc405a59 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs | |||
@@ -47,13 +47,19 @@ impl Expander { | |||
47 | pub(crate) fn enter_expand<T: ast::AstNode, DB: DefDatabase>( | 47 | pub(crate) fn enter_expand<T: ast::AstNode, DB: DefDatabase>( |
48 | &mut self, | 48 | &mut self, |
49 | db: &DB, | 49 | db: &DB, |
50 | local_scope: Option<&ItemScope>, | ||
50 | macro_call: ast::MacroCall, | 51 | macro_call: ast::MacroCall, |
51 | ) -> Option<(Mark, T)> { | 52 | ) -> Option<(Mark, T)> { |
52 | let macro_call = InFile::new(self.current_file_id, ¯o_call); | 53 | let macro_call = InFile::new(self.current_file_id, ¯o_call); |
53 | 54 | ||
54 | if let Some(call_id) = | 55 | if let Some(call_id) = macro_call.as_call_id(db, |path| { |
55 | macro_call.as_call_id(db, |path| self.resolve_path_as_macro(db, &path)) | 56 | if let Some(local_scope) = local_scope { |
56 | { | 57 | if let Some(def) = path.as_ident().and_then(|n| local_scope.get_legacy_macro(n)) { |
58 | return Some(def); | ||
59 | } | ||
60 | } | ||
61 | self.resolve_path_as_macro(db, &path) | ||
62 | }) { | ||
57 | let file_id = call_id.as_file(); | 63 | let file_id = call_id.as_file(); |
58 | if let Some(node) = db.parse_or_expand(file_id) { | 64 | if let Some(node) = db.parse_or_expand(file_id) { |
59 | if let Some(expr) = T::cast(node) { | 65 | if let Some(expr) = T::cast(node) { |
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index ec1b0c2e7..54b5591d3 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -3,7 +3,10 @@ | |||
3 | 3 | ||
4 | use either::Either; | 4 | use either::Either; |
5 | 5 | ||
6 | use hir_expand::name::{name, AsName, Name}; | 6 | use hir_expand::{ |
7 | name::{name, AsName, Name}, | ||
8 | MacroDefId, MacroDefKind, | ||
9 | }; | ||
7 | use ra_arena::Arena; | 10 | use ra_arena::Arena; |
8 | use ra_syntax::{ | 11 | use ra_syntax::{ |
9 | ast::{ | 12 | ast::{ |
@@ -452,19 +455,30 @@ where | |||
452 | None => self.alloc_expr(Expr::Missing, syntax_ptr), | 455 | None => self.alloc_expr(Expr::Missing, syntax_ptr), |
453 | } | 456 | } |
454 | } | 457 | } |
455 | // FIXME expand to statements in statement position | ||
456 | ast::Expr::MacroCall(e) => { | 458 | ast::Expr::MacroCall(e) => { |
457 | let macro_call = self.expander.to_source(AstPtr::new(&e)); | 459 | if let Some(name) = is_macro_rules(&e) { |
458 | match self.expander.enter_expand(self.db, e) { | 460 | let mac = MacroDefId { |
459 | Some((mark, expansion)) => { | 461 | krate: Some(self.expander.module.krate), |
460 | self.source_map | 462 | ast_id: Some(self.expander.ast_id(&e)), |
461 | .expansions | 463 | kind: MacroDefKind::Declarative, |
462 | .insert(macro_call, self.expander.current_file_id); | 464 | }; |
463 | let id = self.collect_expr(expansion); | 465 | self.body.item_scope.define_legacy_macro(name, mac); |
464 | self.expander.exit(self.db, mark); | 466 | |
465 | id | 467 | // FIXME: do we still need to allocate this as missing ? |
468 | self.alloc_expr(Expr::Missing, syntax_ptr) | ||
469 | } else { | ||
470 | let macro_call = self.expander.to_source(AstPtr::new(&e)); | ||
471 | match self.expander.enter_expand(self.db, Some(&self.body.item_scope), e) { | ||
472 | Some((mark, expansion)) => { | ||
473 | self.source_map | ||
474 | .expansions | ||
475 | .insert(macro_call, self.expander.current_file_id); | ||
476 | let id = self.collect_expr(expansion); | ||
477 | self.expander.exit(self.db, mark); | ||
478 | id | ||
479 | } | ||
480 | None => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
466 | } | 481 | } |
467 | None => self.alloc_expr(Expr::Missing, syntax_ptr), | ||
468 | } | 482 | } |
469 | } | 483 | } |
470 | 484 | ||
@@ -686,6 +700,16 @@ where | |||
686 | } | 700 | } |
687 | } | 701 | } |
688 | 702 | ||
703 | fn is_macro_rules(m: &ast::MacroCall) -> Option<Name> { | ||
704 | let name = m.path()?.segment()?.name_ref()?.as_name(); | ||
705 | |||
706 | if name == name![macro_rules] { | ||
707 | Some(m.name()?.as_name()) | ||
708 | } else { | ||
709 | None | ||
710 | } | ||
711 | } | ||
712 | |||
689 | impl From<ast::BinOp> for BinaryOp { | 713 | impl From<ast::BinOp> for BinaryOp { |
690 | fn from(ast_op: ast::BinOp) -> Self { | 714 | fn from(ast_op: ast::BinOp) -> Self { |
691 | match ast_op { | 715 | match ast_op { |
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index a72eb5369..c0b16b7fa 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs | |||
@@ -34,7 +34,8 @@ pub struct FunctionData { | |||
34 | 34 | ||
35 | impl FunctionData { | 35 | impl FunctionData { |
36 | pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> { | 36 | pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc<FunctionData> { |
37 | let src = func.lookup(db).source(db); | 37 | let loc = func.lookup(db); |
38 | let src = loc.source(db); | ||
38 | let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); | 39 | let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); |
39 | let mut params = Vec::new(); | 40 | let mut params = Vec::new(); |
40 | let mut has_self_param = false; | 41 | let mut has_self_param = false; |
@@ -76,7 +77,9 @@ impl FunctionData { | |||
76 | ret_type | 77 | ret_type |
77 | }; | 78 | }; |
78 | 79 | ||
79 | let visibility = RawVisibility::from_ast(db, src.map(|s| s.visibility())); | 80 | let vis_default = RawVisibility::default_for_container(loc.container); |
81 | let visibility = | ||
82 | RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility())); | ||
80 | 83 | ||
81 | let sig = FunctionData { name, params, ret_type, has_self_param, visibility }; | 84 | let sig = FunctionData { name, params, ret_type, has_self_param, visibility }; |
82 | Arc::new(sig) | 85 | Arc::new(sig) |
@@ -105,10 +108,13 @@ impl TypeAliasData { | |||
105 | db: &impl DefDatabase, | 108 | db: &impl DefDatabase, |
106 | typ: TypeAliasId, | 109 | typ: TypeAliasId, |
107 | ) -> Arc<TypeAliasData> { | 110 | ) -> Arc<TypeAliasData> { |
108 | let node = typ.lookup(db).source(db); | 111 | let loc = typ.lookup(db); |
112 | let node = loc.source(db); | ||
109 | let name = node.value.name().map_or_else(Name::missing, |n| n.as_name()); | 113 | let name = node.value.name().map_or_else(Name::missing, |n| n.as_name()); |
110 | let type_ref = node.value.type_ref().map(TypeRef::from_ast); | 114 | let type_ref = node.value.type_ref().map(TypeRef::from_ast); |
111 | let visibility = RawVisibility::from_ast(db, node.map(|n| n.visibility())); | 115 | let vis_default = RawVisibility::default_for_container(loc.container); |
116 | let visibility = | ||
117 | RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); | ||
112 | Arc::new(TypeAliasData { name, type_ref, visibility }) | 118 | Arc::new(TypeAliasData { name, type_ref, visibility }) |
113 | } | 119 | } |
114 | } | 120 | } |
@@ -230,22 +236,26 @@ pub struct ConstData { | |||
230 | 236 | ||
231 | impl ConstData { | 237 | impl ConstData { |
232 | pub(crate) fn const_data_query(db: &impl DefDatabase, konst: ConstId) -> Arc<ConstData> { | 238 | pub(crate) fn const_data_query(db: &impl DefDatabase, konst: ConstId) -> Arc<ConstData> { |
233 | let node = konst.lookup(db).source(db); | 239 | let loc = konst.lookup(db); |
234 | Arc::new(ConstData::new(db, node)) | 240 | let node = loc.source(db); |
241 | let vis_default = RawVisibility::default_for_container(loc.container); | ||
242 | Arc::new(ConstData::new(db, vis_default, node)) | ||
235 | } | 243 | } |
236 | 244 | ||
237 | pub(crate) fn static_data_query(db: &impl DefDatabase, konst: StaticId) -> Arc<ConstData> { | 245 | pub(crate) fn static_data_query(db: &impl DefDatabase, konst: StaticId) -> Arc<ConstData> { |
238 | let node = konst.lookup(db).source(db); | 246 | let node = konst.lookup(db).source(db); |
239 | Arc::new(ConstData::new(db, node)) | 247 | Arc::new(ConstData::new(db, RawVisibility::private(), node)) |
240 | } | 248 | } |
241 | 249 | ||
242 | fn new<N: NameOwner + TypeAscriptionOwner + VisibilityOwner>( | 250 | fn new<N: NameOwner + TypeAscriptionOwner + VisibilityOwner>( |
243 | db: &impl DefDatabase, | 251 | db: &impl DefDatabase, |
252 | vis_default: RawVisibility, | ||
244 | node: InFile<N>, | 253 | node: InFile<N>, |
245 | ) -> ConstData { | 254 | ) -> ConstData { |
246 | let name = node.value.name().map(|n| n.as_name()); | 255 | let name = node.value.name().map(|n| n.as_name()); |
247 | let type_ref = TypeRef::from_ast_opt(node.value.ascribed_type()); | 256 | let type_ref = TypeRef::from_ast_opt(node.value.ascribed_type()); |
248 | let visibility = RawVisibility::from_ast(db, node.map(|n| n.visibility())); | 257 | let visibility = |
258 | RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); | ||
249 | ConstData { name, type_ref, visibility } | 259 | ConstData { name, type_ref, visibility } |
250 | } | 260 | } |
251 | } | 261 | } |
@@ -280,7 +290,7 @@ fn collect_impl_items_in_macro( | |||
280 | return Vec::new(); | 290 | return Vec::new(); |
281 | } | 291 | } |
282 | 292 | ||
283 | if let Some((mark, items)) = expander.enter_expand(db, m) { | 293 | if let Some((mark, items)) = expander.enter_expand(db, None, m) { |
284 | let items: InFile<ast::MacroItems> = expander.to_source(items); | 294 | let items: InFile<ast::MacroItems> = expander.to_source(items); |
285 | let mut res = collect_impl_items( | 295 | let mut res = collect_impl_items( |
286 | db, | 296 | db, |
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 81eac52ad..03515309e 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs | |||
@@ -177,8 +177,13 @@ pub struct ModuleData { | |||
177 | 177 | ||
178 | impl CrateDefMap { | 178 | impl CrateDefMap { |
179 | pub(crate) fn crate_def_map_query(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> { | 179 | pub(crate) fn crate_def_map_query(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> { |
180 | let _p = profile("crate_def_map_query") | 180 | let _p = profile("crate_def_map_query").detail(|| { |
181 | .detail(|| db.crate_graph()[krate].display_name.clone().unwrap_or_default()); | 181 | db.crate_graph()[krate] |
182 | .display_name | ||
183 | .as_ref() | ||
184 | .map(ToString::to_string) | ||
185 | .unwrap_or_default() | ||
186 | }); | ||
182 | let def_map = { | 187 | let def_map = { |
183 | let edition = db.crate_graph()[krate].edition; | 188 | let edition = db.crate_graph()[krate].edition; |
184 | let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default(); | 189 | let mut modules: Arena<LocalModuleId, ModuleData> = Arena::default(); |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index d0459d9b0..db9838cb5 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -102,6 +102,7 @@ struct MacroDirective { | |||
102 | module_id: LocalModuleId, | 102 | module_id: LocalModuleId, |
103 | ast_id: AstIdWithPath<ast::MacroCall>, | 103 | ast_id: AstIdWithPath<ast::MacroCall>, |
104 | legacy: Option<MacroCallId>, | 104 | legacy: Option<MacroCallId>, |
105 | depth: usize, | ||
105 | } | 106 | } |
106 | 107 | ||
107 | #[derive(Clone, Debug, Eq, PartialEq)] | 108 | #[derive(Clone, Debug, Eq, PartialEq)] |
@@ -134,6 +135,7 @@ where | |||
134 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; | 135 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; |
135 | ModCollector { | 136 | ModCollector { |
136 | def_collector: &mut *self, | 137 | def_collector: &mut *self, |
138 | macro_depth: 0, | ||
137 | module_id, | 139 | module_id, |
138 | file_id: file_id.into(), | 140 | file_id: file_id.into(), |
139 | raw_items: &raw_items, | 141 | raw_items: &raw_items, |
@@ -516,7 +518,7 @@ where | |||
516 | macros.retain(|directive| { | 518 | macros.retain(|directive| { |
517 | if let Some(call_id) = directive.legacy { | 519 | if let Some(call_id) = directive.legacy { |
518 | res = ReachedFixedPoint::No; | 520 | res = ReachedFixedPoint::No; |
519 | resolved.push((directive.module_id, call_id)); | 521 | resolved.push((directive.module_id, call_id, directive.depth)); |
520 | return false; | 522 | return false; |
521 | } | 523 | } |
522 | 524 | ||
@@ -530,7 +532,7 @@ where | |||
530 | ); | 532 | ); |
531 | resolved_res.resolved_def.take_macros() | 533 | resolved_res.resolved_def.take_macros() |
532 | }) { | 534 | }) { |
533 | resolved.push((directive.module_id, call_id)); | 535 | resolved.push((directive.module_id, call_id, directive.depth)); |
534 | res = ReachedFixedPoint::No; | 536 | res = ReachedFixedPoint::No; |
535 | return false; | 537 | return false; |
536 | } | 538 | } |
@@ -541,7 +543,7 @@ where | |||
541 | if let Some(call_id) = | 543 | if let Some(call_id) = |
542 | directive.ast_id.as_call_id(self.db, |path| self.resolve_attribute_macro(&path)) | 544 | directive.ast_id.as_call_id(self.db, |path| self.resolve_attribute_macro(&path)) |
543 | { | 545 | { |
544 | resolved.push((directive.module_id, call_id)); | 546 | resolved.push((directive.module_id, call_id, 0)); |
545 | res = ReachedFixedPoint::No; | 547 | res = ReachedFixedPoint::No; |
546 | return false; | 548 | return false; |
547 | } | 549 | } |
@@ -552,8 +554,12 @@ where | |||
552 | self.unexpanded_macros = macros; | 554 | self.unexpanded_macros = macros; |
553 | self.unexpanded_attribute_macros = attribute_macros; | 555 | self.unexpanded_attribute_macros = attribute_macros; |
554 | 556 | ||
555 | for (module_id, macro_call_id) in resolved { | 557 | for (module_id, macro_call_id, depth) in resolved { |
556 | self.collect_macro_expansion(module_id, macro_call_id); | 558 | if depth > 1024 { |
559 | log::debug!("Max macro expansion depth reached"); | ||
560 | continue; | ||
561 | } | ||
562 | self.collect_macro_expansion(module_id, macro_call_id, depth); | ||
557 | } | 563 | } |
558 | 564 | ||
559 | res | 565 | res |
@@ -573,12 +579,18 @@ where | |||
573 | None | 579 | None |
574 | } | 580 | } |
575 | 581 | ||
576 | fn collect_macro_expansion(&mut self, module_id: LocalModuleId, macro_call_id: MacroCallId) { | 582 | fn collect_macro_expansion( |
583 | &mut self, | ||
584 | module_id: LocalModuleId, | ||
585 | macro_call_id: MacroCallId, | ||
586 | depth: usize, | ||
587 | ) { | ||
577 | let file_id: HirFileId = macro_call_id.as_file(); | 588 | let file_id: HirFileId = macro_call_id.as_file(); |
578 | let raw_items = self.db.raw_items(file_id); | 589 | let raw_items = self.db.raw_items(file_id); |
579 | let mod_dir = self.mod_dirs[&module_id].clone(); | 590 | let mod_dir = self.mod_dirs[&module_id].clone(); |
580 | ModCollector { | 591 | ModCollector { |
581 | def_collector: &mut *self, | 592 | def_collector: &mut *self, |
593 | macro_depth: depth, | ||
582 | file_id, | 594 | file_id, |
583 | module_id, | 595 | module_id, |
584 | raw_items: &raw_items, | 596 | raw_items: &raw_items, |
@@ -595,6 +607,7 @@ where | |||
595 | /// Walks a single module, populating defs, imports and macros | 607 | /// Walks a single module, populating defs, imports and macros |
596 | struct ModCollector<'a, D> { | 608 | struct ModCollector<'a, D> { |
597 | def_collector: D, | 609 | def_collector: D, |
610 | macro_depth: usize, | ||
598 | module_id: LocalModuleId, | 611 | module_id: LocalModuleId, |
599 | file_id: HirFileId, | 612 | file_id: HirFileId, |
600 | raw_items: &'a raw::RawItems, | 613 | raw_items: &'a raw::RawItems, |
@@ -684,6 +697,7 @@ where | |||
684 | 697 | ||
685 | ModCollector { | 698 | ModCollector { |
686 | def_collector: &mut *self.def_collector, | 699 | def_collector: &mut *self.def_collector, |
700 | macro_depth: self.macro_depth, | ||
687 | module_id, | 701 | module_id, |
688 | file_id: self.file_id, | 702 | file_id: self.file_id, |
689 | raw_items: self.raw_items, | 703 | raw_items: self.raw_items, |
@@ -713,6 +727,7 @@ where | |||
713 | let raw_items = self.def_collector.db.raw_items(file_id.into()); | 727 | let raw_items = self.def_collector.db.raw_items(file_id.into()); |
714 | ModCollector { | 728 | ModCollector { |
715 | def_collector: &mut *self.def_collector, | 729 | def_collector: &mut *self.def_collector, |
730 | macro_depth: self.macro_depth, | ||
716 | module_id, | 731 | module_id, |
717 | file_id: file_id.into(), | 732 | file_id: file_id.into(), |
718 | raw_items: &raw_items, | 733 | raw_items: &raw_items, |
@@ -887,6 +902,7 @@ where | |||
887 | module_id: self.module_id, | 902 | module_id: self.module_id, |
888 | ast_id, | 903 | ast_id, |
889 | legacy: Some(macro_call_id), | 904 | legacy: Some(macro_call_id), |
905 | depth: self.macro_depth + 1, | ||
890 | }); | 906 | }); |
891 | 907 | ||
892 | return; | 908 | return; |
@@ -902,6 +918,7 @@ where | |||
902 | module_id: self.module_id, | 918 | module_id: self.module_id, |
903 | ast_id, | 919 | ast_id, |
904 | legacy: None, | 920 | legacy: None, |
921 | depth: self.macro_depth + 1, | ||
905 | }); | 922 | }); |
906 | } | 923 | } |
907 | 924 | ||
@@ -971,13 +988,26 @@ mod tests { | |||
971 | } | 988 | } |
972 | 989 | ||
973 | #[test] | 990 | #[test] |
974 | fn test_macro_expand_will_stop() { | 991 | fn test_macro_expand_will_stop_1() { |
992 | do_resolve( | ||
993 | r#" | ||
994 | macro_rules! foo { | ||
995 | ($($ty:ty)*) => { foo!($($ty)*); } | ||
996 | } | ||
997 | foo!(KABOOM); | ||
998 | "#, | ||
999 | ); | ||
1000 | } | ||
1001 | |||
1002 | #[ignore] // this test does succeed, but takes quite a while :/ | ||
1003 | #[test] | ||
1004 | fn test_macro_expand_will_stop_2() { | ||
975 | do_resolve( | 1005 | do_resolve( |
976 | r#" | 1006 | r#" |
977 | macro_rules! foo { | 1007 | macro_rules! foo { |
978 | ($($ty:ty)*) => { foo!($($ty)*, $($ty)*); } | 1008 | ($($ty:ty)*) => { foo!($($ty)* $($ty)*); } |
979 | } | 1009 | } |
980 | foo!(KABOOM); | 1010 | foo!(KABOOM); |
981 | "#, | 1011 | "#, |
982 | ); | 1012 | ); |
983 | } | 1013 | } |
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index dda5ed699..3f33a75b9 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs | |||
@@ -102,6 +102,28 @@ fn crate_def_map_super_super() { | |||
102 | } | 102 | } |
103 | 103 | ||
104 | #[test] | 104 | #[test] |
105 | fn crate_def_map_fn_mod_same_name() { | ||
106 | let map = def_map( | ||
107 | " | ||
108 | //- /lib.rs | ||
109 | mod m { | ||
110 | pub mod z {} | ||
111 | pub fn z() {} | ||
112 | } | ||
113 | ", | ||
114 | ); | ||
115 | assert_snapshot!(map, @r###" | ||
116 | ⋮crate | ||
117 | ⋮m: t | ||
118 | ⋮ | ||
119 | ⋮crate::m | ||
120 | ⋮z: t v | ||
121 | ⋮ | ||
122 | ⋮crate::m::z | ||
123 | "###) | ||
124 | } | ||
125 | |||
126 | #[test] | ||
105 | fn bogus_paths() { | 127 | fn bogus_paths() { |
106 | covers!(bogus_paths); | 128 | covers!(bogus_paths); |
107 | let map = def_map( | 129 | let map = def_map( |
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 2734d51a0..123fae72a 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs | |||
@@ -381,6 +381,11 @@ impl Resolver { | |||
381 | db: &impl DefDatabase, | 381 | db: &impl DefDatabase, |
382 | path: &ModPath, | 382 | path: &ModPath, |
383 | ) -> Option<MacroDefId> { | 383 | ) -> Option<MacroDefId> { |
384 | // Search item scope legacy macro first | ||
385 | if let Some(def) = self.resolve_local_macro_def(path) { | ||
386 | return Some(def); | ||
387 | } | ||
388 | |||
384 | let (item_map, module) = self.module_scope()?; | 389 | let (item_map, module) = self.module_scope()?; |
385 | item_map.resolve_path(db, module, &path, BuiltinShadowMode::Other).0.take_macros() | 390 | item_map.resolve_path(db, module, &path, BuiltinShadowMode::Other).0.take_macros() |
386 | } | 391 | } |
@@ -413,6 +418,16 @@ impl Resolver { | |||
413 | }) | 418 | }) |
414 | } | 419 | } |
415 | 420 | ||
421 | fn resolve_local_macro_def(&self, path: &ModPath) -> Option<MacroDefId> { | ||
422 | let name = path.as_ident()?; | ||
423 | self.scopes.iter().rev().find_map(|scope| { | ||
424 | if let Scope::LocalItemsScope(body) = scope { | ||
425 | return body.item_scope.get_legacy_macro(name); | ||
426 | } | ||
427 | None | ||
428 | }) | ||
429 | } | ||
430 | |||
416 | pub fn module(&self) -> Option<ModuleId> { | 431 | pub fn module(&self) -> Option<ModuleId> { |
417 | let (def_map, local_id) = self.module_scope()?; | 432 | let (def_map, local_id) = self.module_scope()?; |
418 | Some(ModuleId { krate: def_map.krate, local_id }) | 433 | Some(ModuleId { krate: def_map.krate, local_id }) |
diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs index d8296da4b..e0c59e905 100644 --- a/crates/ra_hir_def/src/visibility.rs +++ b/crates/ra_hir_def/src/visibility.rs | |||
@@ -6,7 +6,7 @@ use ra_syntax::ast; | |||
6 | use crate::{ | 6 | use crate::{ |
7 | db::DefDatabase, | 7 | db::DefDatabase, |
8 | path::{ModPath, PathKind}, | 8 | path::{ModPath, PathKind}, |
9 | ModuleId, | 9 | AssocContainerId, ModuleId, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | /// Visibility of an item, not yet resolved. | 12 | /// Visibility of an item, not yet resolved. |
@@ -20,11 +20,30 @@ pub enum RawVisibility { | |||
20 | } | 20 | } |
21 | 21 | ||
22 | impl RawVisibility { | 22 | impl RawVisibility { |
23 | const fn private() -> RawVisibility { | 23 | pub(crate) const fn private() -> RawVisibility { |
24 | let path = ModPath { kind: PathKind::Super(0), segments: Vec::new() }; | 24 | let path = ModPath { kind: PathKind::Super(0), segments: Vec::new() }; |
25 | RawVisibility::Module(path) | 25 | RawVisibility::Module(path) |
26 | } | 26 | } |
27 | 27 | ||
28 | pub(crate) fn default_for_container(container_id: AssocContainerId) -> Self { | ||
29 | match container_id { | ||
30 | AssocContainerId::TraitId(_) => RawVisibility::Public, | ||
31 | _ => RawVisibility::private(), | ||
32 | } | ||
33 | } | ||
34 | |||
35 | pub(crate) fn from_ast_with_default( | ||
36 | db: &impl DefDatabase, | ||
37 | default: RawVisibility, | ||
38 | node: InFile<Option<ast::Visibility>>, | ||
39 | ) -> RawVisibility { | ||
40 | Self::from_ast_with_hygiene_and_default( | ||
41 | node.value, | ||
42 | default, | ||
43 | &Hygiene::new(db, node.file_id), | ||
44 | ) | ||
45 | } | ||
46 | |||
28 | pub(crate) fn from_ast( | 47 | pub(crate) fn from_ast( |
29 | db: &impl DefDatabase, | 48 | db: &impl DefDatabase, |
30 | node: InFile<Option<ast::Visibility>>, | 49 | node: InFile<Option<ast::Visibility>>, |
@@ -36,8 +55,16 @@ impl RawVisibility { | |||
36 | node: Option<ast::Visibility>, | 55 | node: Option<ast::Visibility>, |
37 | hygiene: &Hygiene, | 56 | hygiene: &Hygiene, |
38 | ) -> RawVisibility { | 57 | ) -> RawVisibility { |
58 | Self::from_ast_with_hygiene_and_default(node, RawVisibility::private(), hygiene) | ||
59 | } | ||
60 | |||
61 | pub(crate) fn from_ast_with_hygiene_and_default( | ||
62 | node: Option<ast::Visibility>, | ||
63 | default: RawVisibility, | ||
64 | hygiene: &Hygiene, | ||
65 | ) -> RawVisibility { | ||
39 | let node = match node { | 66 | let node = match node { |
40 | None => return RawVisibility::private(), | 67 | None => return default, |
41 | Some(node) => node, | 68 | Some(node) => node, |
42 | }; | 69 | }; |
43 | match node.kind() { | 70 | match node.kind() { |