aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs98
-rw-r--r--crates/ra_hir_def/src/body/scope.rs13
-rw-r--r--crates/ra_hir_def/src/item_scope.rs79
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs49
-rw-r--r--crates/ra_hir_def/src/nameres/tests/globs.rs90
-rw-r--r--crates/ra_hir_def/src/nameres/tests/mod_resolution.rs16
6 files changed, 264 insertions, 81 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 3ced648e5..a7e2e0982 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -5,7 +5,7 @@ use either::Either;
5use hir_expand::{ 5use hir_expand::{
6 hygiene::Hygiene, 6 hygiene::Hygiene,
7 name::{name, AsName, Name}, 7 name::{name, AsName, Name},
8 AstId, HirFileId, MacroDefId, MacroDefKind, 8 HirFileId, MacroDefId, MacroDefKind,
9}; 9};
10use ra_arena::Arena; 10use ra_arena::Arena;
11use ra_syntax::{ 11use ra_syntax::{
@@ -27,7 +27,7 @@ use crate::{
27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, 27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
28 }, 28 },
29 item_scope::BuiltinShadowMode, 29 item_scope::BuiltinShadowMode,
30 item_tree::{FileItemTreeId, ItemTree, ItemTreeNode}, 30 item_tree::{ItemTree, ItemTreeId, ItemTreeNode},
31 path::{GenericArgs, Path}, 31 path::{GenericArgs, Path},
32 type_ref::{Mutability, Rawness, TypeRef}, 32 type_ref::{Mutability, Rawness, TypeRef},
33 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, 33 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId,
@@ -37,7 +37,7 @@ use crate::{
37use super::{ExprSource, PatSource}; 37use super::{ExprSource, PatSource};
38use ast::AstChildren; 38use ast::AstChildren;
39use rustc_hash::FxHashMap; 39use rustc_hash::FxHashMap;
40use std::sync::Arc; 40use std::{any::type_name, sync::Arc};
41 41
42pub(crate) struct LowerCtx { 42pub(crate) struct LowerCtx {
43 hygiene: Hygiene, 43 hygiene: Hygiene,
@@ -561,17 +561,30 @@ impl ExprCollector<'_> {
561 } 561 }
562 } 562 }
563 563
564 fn find_inner_item<S: ItemTreeNode>(&self, id: AstId<ast::ModuleItem>) -> FileItemTreeId<S> { 564 fn find_inner_item<N: ItemTreeNode>(&self, ast: &N::Source) -> Option<ItemTreeId<N>> {
565 let id = self.expander.ast_id(ast);
565 let tree = &self.item_trees[&id.file_id]; 566 let tree = &self.item_trees[&id.file_id];
566 567
567 // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes 568 // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes
568 569
569 // Root file (non-macro). 570 // Root file (non-macro).
570 tree.all_inner_items() 571 let item_tree_id = tree
572 .all_inner_items()
571 .chain(tree.top_level_items().iter().copied()) 573 .chain(tree.top_level_items().iter().copied())
572 .filter_map(|mod_item| mod_item.downcast::<S>()) 574 .filter_map(|mod_item| mod_item.downcast::<N>())
573 .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value) 575 .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value.upcast())
574 .unwrap_or_else(|| panic!("couldn't find inner item for {:?}", id)) 576 .or_else(|| {
577 log::debug!(
578 "couldn't find inner {} item for {:?} (AST: `{}` - {:?})",
579 type_name::<N>(),
580 id,
581 ast.syntax(),
582 ast.syntax(),
583 );
584 None
585 })?;
586
587 Some(ItemTreeId::new(id.file_id, item_tree_id))
575 } 588 }
576 589
577 fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { 590 fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
@@ -611,82 +624,45 @@ impl ExprCollector<'_> {
611 .filter_map(|item| { 624 .filter_map(|item| {
612 let (def, name): (ModuleDefId, Option<ast::Name>) = match item { 625 let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
613 ast::ModuleItem::FnDef(def) => { 626 ast::ModuleItem::FnDef(def) => {
614 let ast_id = self.expander.ast_id(&def); 627 let id = self.find_inner_item(&def)?;
615 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
616 ( 628 (
617 FunctionLoc { container: container.into(), id: ast_id.with_value(id) } 629 FunctionLoc { container: container.into(), id }.intern(self.db).into(),
618 .intern(self.db)
619 .into(),
620 def.name(), 630 def.name(),
621 ) 631 )
622 } 632 }
623 ast::ModuleItem::TypeAliasDef(def) => { 633 ast::ModuleItem::TypeAliasDef(def) => {
624 let ast_id = self.expander.ast_id(&def); 634 let id = self.find_inner_item(&def)?;
625 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
626 ( 635 (
627 TypeAliasLoc { container: container.into(), id: ast_id.with_value(id) } 636 TypeAliasLoc { container: container.into(), id }.intern(self.db).into(),
628 .intern(self.db)
629 .into(),
630 def.name(), 637 def.name(),
631 ) 638 )
632 } 639 }
633 ast::ModuleItem::ConstDef(def) => { 640 ast::ModuleItem::ConstDef(def) => {
634 let ast_id = self.expander.ast_id(&def); 641 let id = self.find_inner_item(&def)?;
635 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
636 ( 642 (
637 ConstLoc { container: container.into(), id: ast_id.with_value(id) } 643 ConstLoc { container: container.into(), id }.intern(self.db).into(),
638 .intern(self.db)
639 .into(),
640 def.name(), 644 def.name(),
641 ) 645 )
642 } 646 }
643 ast::ModuleItem::StaticDef(def) => { 647 ast::ModuleItem::StaticDef(def) => {
644 let ast_id = self.expander.ast_id(&def); 648 let id = self.find_inner_item(&def)?;
645 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 649 (StaticLoc { container, id }.intern(self.db).into(), def.name())
646 (
647 StaticLoc { container, id: ast_id.with_value(id) }
648 .intern(self.db)
649 .into(),
650 def.name(),
651 )
652 } 650 }
653 ast::ModuleItem::StructDef(def) => { 651 ast::ModuleItem::StructDef(def) => {
654 let ast_id = self.expander.ast_id(&def); 652 let id = self.find_inner_item(&def)?;
655 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 653 (StructLoc { container, id }.intern(self.db).into(), def.name())
656 (
657 StructLoc { container, id: ast_id.with_value(id) }
658 .intern(self.db)
659 .into(),
660 def.name(),
661 )
662 } 654 }
663 ast::ModuleItem::EnumDef(def) => { 655 ast::ModuleItem::EnumDef(def) => {
664 let ast_id = self.expander.ast_id(&def); 656 let id = self.find_inner_item(&def)?;
665 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 657 (EnumLoc { container, id }.intern(self.db).into(), def.name())
666 (
667 EnumLoc { container, id: ast_id.with_value(id) }.intern(self.db).into(),
668 def.name(),
669 )
670 } 658 }
671 ast::ModuleItem::UnionDef(def) => { 659 ast::ModuleItem::UnionDef(def) => {
672 let ast_id = self.expander.ast_id(&def); 660 let id = self.find_inner_item(&def)?;
673 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 661 (UnionLoc { container, id }.intern(self.db).into(), def.name())
674 (
675 UnionLoc { container, id: ast_id.with_value(id) }
676 .intern(self.db)
677 .into(),
678 def.name(),
679 )
680 } 662 }
681 ast::ModuleItem::TraitDef(def) => { 663 ast::ModuleItem::TraitDef(def) => {
682 let ast_id = self.expander.ast_id(&def); 664 let id = self.find_inner_item(&def)?;
683 let id = self.find_inner_item(ast_id.map(|id| id.upcast())); 665 (TraitLoc { container, id }.intern(self.db).into(), def.name())
684 (
685 TraitLoc { container, id: ast_id.with_value(id) }
686 .intern(self.db)
687 .into(),
688 def.name(),
689 )
690 } 666 }
691 ast::ModuleItem::ExternBlock(_) => return None, // FIXME: collect from extern blocks 667 ast::ModuleItem::ExternBlock(_) => return None, // FIXME: collect from extern blocks
692 ast::ModuleItem::ImplDef(_) 668 ast::ModuleItem::ImplDef(_)
diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs
index 81397b063..99e876683 100644
--- a/crates/ra_hir_def/src/body/scope.rs
+++ b/crates/ra_hir_def/src/body/scope.rs
@@ -337,6 +337,19 @@ fn foo() {
337 ); 337 );
338 } 338 }
339 339
340 #[test]
341 fn broken_inner_item() {
342 do_check(
343 r"
344 fn foo() {
345 trait {}
346 <|>
347 }
348 ",
349 &[],
350 );
351 }
352
340 fn do_check_local_name(ra_fixture: &str, expected_offset: u32) { 353 fn do_check_local_name(ra_fixture: &str, expected_offset: u32) {
341 let (db, position) = TestDB::with_position(ra_fixture); 354 let (db, position) = TestDB::with_position(ra_fixture);
342 let file_id = position.file_id; 355 let file_id = position.file_id;
diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs
index c81b966c3..4d446c707 100644
--- a/crates/ra_hir_def/src/item_scope.rs
+++ b/crates/ra_hir_def/src/item_scope.rs
@@ -4,14 +4,27 @@
4use hir_expand::name::Name; 4use hir_expand::name::Name;
5use once_cell::sync::Lazy; 5use once_cell::sync::Lazy;
6use ra_db::CrateId; 6use ra_db::CrateId;
7use rustc_hash::FxHashMap; 7use rustc_hash::{FxHashMap, FxHashSet};
8use test_utils::mark; 8use test_utils::mark;
9 9
10use crate::{ 10use crate::{
11 db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId, 11 db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId,
12 Lookup, MacroDefId, ModuleDefId, TraitId, 12 LocalModuleId, Lookup, MacroDefId, ModuleDefId, TraitId,
13}; 13};
14 14
15#[derive(Copy, Clone)]
16pub(crate) enum ImportType {
17 Glob,
18 Named,
19}
20
21#[derive(Debug, Default)]
22pub struct PerNsGlobImports {
23 types: FxHashSet<(LocalModuleId, Name)>,
24 values: FxHashSet<(LocalModuleId, Name)>,
25 macros: FxHashSet<(LocalModuleId, Name)>,
26}
27
15#[derive(Debug, Default, PartialEq, Eq)] 28#[derive(Debug, Default, PartialEq, Eq)]
16pub struct ItemScope { 29pub struct ItemScope {
17 visible: FxHashMap<Name, PerNs>, 30 visible: FxHashMap<Name, PerNs>,
@@ -127,16 +140,62 @@ impl ItemScope {
127 let mut changed = false; 140 let mut changed = false;
128 let existing = self.visible.entry(name).or_default(); 141 let existing = self.visible.entry(name).or_default();
129 142
143 if existing.types.is_none() && def.types.is_some() {
144 existing.types = def.types;
145 changed = true;
146 }
147
148 if existing.values.is_none() && def.values.is_some() {
149 existing.values = def.values;
150 changed = true;
151 }
152
153 if existing.macros.is_none() && def.macros.is_some() {
154 existing.macros = def.macros;
155 changed = true;
156 }
157
158 changed
159 }
160
161 pub(crate) fn push_res_with_import(
162 &mut self,
163 glob_imports: &mut PerNsGlobImports,
164 lookup: (LocalModuleId, Name),
165 def: PerNs,
166 def_import_type: ImportType,
167 ) -> bool {
168 let mut changed = false;
169 let existing = self.visible.entry(lookup.1.clone()).or_default();
170
130 macro_rules! check_changed { 171 macro_rules! check_changed {
131 ($changed:ident, $existing:expr, $def:expr) => { 172 (
132 match ($existing, $def) { 173 $changed:ident,
174 ( $existing:ident / $def:ident ) . $field:ident,
175 $glob_imports:ident [ $lookup:ident ],
176 $def_import_type:ident
177 ) => {
178 match ($existing.$field, $def.$field) {
133 (None, Some(_)) => { 179 (None, Some(_)) => {
134 $existing = $def; 180 match $def_import_type {
181 ImportType::Glob => {
182 $glob_imports.$field.insert($lookup.clone());
183 }
184 ImportType::Named => {
185 $glob_imports.$field.remove(&$lookup);
186 }
187 }
188
189 $existing.$field = $def.$field;
135 $changed = true; 190 $changed = true;
136 } 191 }
137 (Some(e), Some(d)) if e.0 != d.0 => { 192 (Some(_), Some(_))
193 if $glob_imports.$field.contains(&$lookup)
194 && matches!($def_import_type, ImportType::Named) =>
195 {
138 mark::hit!(import_shadowed); 196 mark::hit!(import_shadowed);
139 $existing = $def; 197 $glob_imports.$field.remove(&$lookup);
198 $existing.$field = $def.$field;
140 $changed = true; 199 $changed = true;
141 } 200 }
142 _ => {} 201 _ => {}
@@ -144,9 +203,9 @@ impl ItemScope {
144 }; 203 };
145 } 204 }
146 205
147 check_changed!(changed, existing.types, def.types); 206 check_changed!(changed, (existing / def).types, glob_imports[lookup], def_import_type);
148 check_changed!(changed, existing.values, def.values); 207 check_changed!(changed, (existing / def).values, glob_imports[lookup], def_import_type);
149 check_changed!(changed, existing.macros, def.macros); 208 check_changed!(changed, (existing / def).macros, glob_imports[lookup], def_import_type);
150 209
151 changed 210 changed
152 } 211 }
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 2ced4f66b..a35ac1024 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -20,6 +20,7 @@ use test_utils::mark;
20use crate::{ 20use crate::{
21 attr::Attrs, 21 attr::Attrs,
22 db::DefDatabase, 22 db::DefDatabase,
23 item_scope::{ImportType, PerNsGlobImports},
23 item_tree::{ 24 item_tree::{
24 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind, 25 self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind,
25 }, 26 },
@@ -80,6 +81,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr
80 mod_dirs: FxHashMap::default(), 81 mod_dirs: FxHashMap::default(),
81 cfg_options, 82 cfg_options,
82 proc_macros, 83 proc_macros,
84 from_glob_import: Default::default(),
83 }; 85 };
84 collector.collect(); 86 collector.collect();
85 collector.finish() 87 collector.finish()
@@ -186,6 +188,7 @@ struct DefCollector<'a> {
186 mod_dirs: FxHashMap<LocalModuleId, ModDir>, 188 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
187 cfg_options: &'a CfgOptions, 189 cfg_options: &'a CfgOptions,
188 proc_macros: Vec<(Name, ProcMacroExpander)>, 190 proc_macros: Vec<(Name, ProcMacroExpander)>,
191 from_glob_import: PerNsGlobImports,
189} 192}
190 193
191impl DefCollector<'_> { 194impl DefCollector<'_> {
@@ -305,6 +308,7 @@ impl DefCollector<'_> {
305 self.def_map.root, 308 self.def_map.root,
306 &[(name, PerNs::macros(macro_, Visibility::Public))], 309 &[(name, PerNs::macros(macro_, Visibility::Public))],
307 Visibility::Public, 310 Visibility::Public,
311 ImportType::Named,
308 ); 312 );
309 } 313 }
310 } 314 }
@@ -330,6 +334,7 @@ impl DefCollector<'_> {
330 self.def_map.root, 334 self.def_map.root,
331 &[(name, PerNs::macros(macro_, Visibility::Public))], 335 &[(name, PerNs::macros(macro_, Visibility::Public))],
332 Visibility::Public, 336 Visibility::Public,
337 ImportType::Named,
333 ); 338 );
334 } 339 }
335 340
@@ -383,7 +388,6 @@ impl DefCollector<'_> {
383 let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new()); 388 let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
384 for mut directive in imports { 389 for mut directive in imports {
385 directive.status = self.resolve_import(directive.module_id, &directive.import); 390 directive.status = self.resolve_import(directive.module_id, &directive.import);
386
387 match directive.status { 391 match directive.status {
388 PartialResolvedImport::Indeterminate(_) => { 392 PartialResolvedImport::Indeterminate(_) => {
389 self.record_resolved_import(&directive); 393 self.record_resolved_import(&directive);
@@ -477,7 +481,7 @@ impl DefCollector<'_> {
477 .filter(|(_, res)| !res.is_none()) 481 .filter(|(_, res)| !res.is_none())
478 .collect::<Vec<_>>(); 482 .collect::<Vec<_>>();
479 483
480 self.update(module_id, &items, vis); 484 self.update(module_id, &items, vis, ImportType::Glob);
481 } else { 485 } else {
482 // glob import from same crate => we do an initial 486 // glob import from same crate => we do an initial
483 // import, and then need to propagate any further 487 // import, and then need to propagate any further
@@ -499,7 +503,7 @@ impl DefCollector<'_> {
499 .filter(|(_, res)| !res.is_none()) 503 .filter(|(_, res)| !res.is_none())
500 .collect::<Vec<_>>(); 504 .collect::<Vec<_>>();
501 505
502 self.update(module_id, &items, vis); 506 self.update(module_id, &items, vis, ImportType::Glob);
503 // record the glob import in case we add further items 507 // record the glob import in case we add further items
504 let glob = self.glob_imports.entry(m.local_id).or_default(); 508 let glob = self.glob_imports.entry(m.local_id).or_default();
505 if !glob.iter().any(|(mid, _)| *mid == module_id) { 509 if !glob.iter().any(|(mid, _)| *mid == module_id) {
@@ -529,7 +533,7 @@ impl DefCollector<'_> {
529 (name, res) 533 (name, res)
530 }) 534 })
531 .collect::<Vec<_>>(); 535 .collect::<Vec<_>>();
532 self.update(module_id, &resolutions, vis); 536 self.update(module_id, &resolutions, vis, ImportType::Glob);
533 } 537 }
534 Some(d) => { 538 Some(d) => {
535 log::debug!("glob import {:?} from non-module/enum {:?}", import, d); 539 log::debug!("glob import {:?} from non-module/enum {:?}", import, d);
@@ -555,15 +559,21 @@ impl DefCollector<'_> {
555 } 559 }
556 } 560 }
557 561
558 self.update(module_id, &[(name, def)], vis); 562 self.update(module_id, &[(name, def)], vis, ImportType::Named);
559 } 563 }
560 None => mark::hit!(bogus_paths), 564 None => mark::hit!(bogus_paths),
561 } 565 }
562 } 566 }
563 } 567 }
564 568
565 fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, PerNs)], vis: Visibility) { 569 fn update(
566 self.update_recursive(module_id, resolutions, vis, 0) 570 &mut self,
571 module_id: LocalModuleId,
572 resolutions: &[(Name, PerNs)],
573 vis: Visibility,
574 import_type: ImportType,
575 ) {
576 self.update_recursive(module_id, resolutions, vis, import_type, 0)
567 } 577 }
568 578
569 fn update_recursive( 579 fn update_recursive(
@@ -573,6 +583,7 @@ impl DefCollector<'_> {
573 // All resolutions are imported with this visibility; the visibilies in 583 // All resolutions are imported with this visibility; the visibilies in
574 // the `PerNs` values are ignored and overwritten 584 // the `PerNs` values are ignored and overwritten
575 vis: Visibility, 585 vis: Visibility,
586 import_type: ImportType,
576 depth: usize, 587 depth: usize,
577 ) { 588 ) {
578 if depth > 100 { 589 if depth > 100 {
@@ -582,7 +593,12 @@ impl DefCollector<'_> {
582 let scope = &mut self.def_map.modules[module_id].scope; 593 let scope = &mut self.def_map.modules[module_id].scope;
583 let mut changed = false; 594 let mut changed = false;
584 for (name, res) in resolutions { 595 for (name, res) in resolutions {
585 changed |= scope.push_res(name.clone(), res.with_visibility(vis)); 596 changed |= scope.push_res_with_import(
597 &mut self.from_glob_import,
598 (module_id, name.clone()),
599 res.with_visibility(vis),
600 import_type,
601 );
586 } 602 }
587 603
588 if !changed { 604 if !changed {
@@ -601,7 +617,13 @@ impl DefCollector<'_> {
601 if !vis.is_visible_from_def_map(&self.def_map, glob_importing_module) { 617 if !vis.is_visible_from_def_map(&self.def_map, glob_importing_module) {
602 continue; 618 continue;
603 } 619 }
604 self.update_recursive(glob_importing_module, resolutions, glob_import_vis, depth + 1); 620 self.update_recursive(
621 glob_importing_module,
622 resolutions,
623 glob_import_vis,
624 ImportType::Glob,
625 depth + 1,
626 );
605 } 627 }
606 } 628 }
607 629
@@ -923,6 +945,7 @@ impl ModCollector<'_, '_> {
923 self.module_id, 945 self.module_id,
924 &[(name.clone(), PerNs::from_def(id, vis, has_constructor))], 946 &[(name.clone(), PerNs::from_def(id, vis, has_constructor))],
925 vis, 947 vis,
948 ImportType::Named,
926 ) 949 )
927 } 950 }
928 } 951 }
@@ -1025,7 +1048,12 @@ impl ModCollector<'_, '_> {
1025 let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; 1048 let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res };
1026 let def: ModuleDefId = module.into(); 1049 let def: ModuleDefId = module.into();
1027 self.def_collector.def_map.modules[self.module_id].scope.define_def(def); 1050 self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
1028 self.def_collector.update(self.module_id, &[(name, PerNs::from_def(def, vis, false))], vis); 1051 self.def_collector.update(
1052 self.module_id,
1053 &[(name, PerNs::from_def(def, vis, false))],
1054 vis,
1055 ImportType::Named,
1056 );
1029 res 1057 res
1030 } 1058 }
1031 1059
@@ -1154,6 +1182,7 @@ mod tests {
1154 mod_dirs: FxHashMap::default(), 1182 mod_dirs: FxHashMap::default(),
1155 cfg_options: &CfgOptions::default(), 1183 cfg_options: &CfgOptions::default(),
1156 proc_macros: Default::default(), 1184 proc_macros: Default::default(),
1185 from_glob_import: Default::default(),
1157 }; 1186 };
1158 collector.collect(); 1187 collector.collect();
1159 collector.def_map 1188 collector.def_map
diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs
index 2f440975a..7f3d7509c 100644
--- a/crates/ra_hir_def/src/nameres/tests/globs.rs
+++ b/crates/ra_hir_def/src/nameres/tests/globs.rs
@@ -276,3 +276,93 @@ fn glob_shadowed_def() {
276 "### 276 "###
277 ); 277 );
278} 278}
279
280#[test]
281fn glob_shadowed_def_reversed() {
282 let map = def_map(
283 r###"
284 //- /lib.rs
285 mod foo;
286 mod bar;
287
288 use bar::baz;
289 use foo::*;
290
291 use baz::Bar;
292
293 //- /foo.rs
294 pub mod baz {
295 pub struct Foo;
296 }
297
298 //- /bar.rs
299 pub mod baz {
300 pub struct Bar;
301 }
302 "###,
303 );
304 assert_snapshot!(map, @r###"
305 ⋮crate
306 ⋮Bar: t v
307 ⋮bar: t
308 ⋮baz: t
309 ⋮foo: t
310
311 ⋮crate::bar
312 ⋮baz: t
313
314 ⋮crate::bar::baz
315 ⋮Bar: t v
316
317 ⋮crate::foo
318 ⋮baz: t
319
320 ⋮crate::foo::baz
321 ⋮Foo: t v
322 "###
323 );
324}
325
326#[test]
327fn glob_shadowed_def_dependencies() {
328 let map = def_map(
329 r###"
330 //- /lib.rs
331 mod a { pub mod foo { pub struct X; } }
332 mod b { pub use super::a::foo; }
333 mod c { pub mod foo { pub struct Y; } }
334 mod d {
335 use super::c::foo;
336 use super::b::*;
337 use foo::Y;
338 }
339 "###,
340 );
341 assert_snapshot!(map, @r###"
342 ⋮crate
343 ⋮a: t
344 ⋮b: t
345 ⋮c: t
346 ⋮d: t
347
348 ⋮crate::d
349 ⋮Y: t v
350 ⋮foo: t
351
352 ⋮crate::c
353 ⋮foo: t
354
355 ⋮crate::c::foo
356 ⋮Y: t v
357
358 ⋮crate::b
359 ⋮foo: t
360
361 ⋮crate::a
362 ⋮foo: t
363
364 ⋮crate::a::foo
365 ⋮X: t v
366 "###
367 );
368}
diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
index e9a5e4cba..753684201 100644
--- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs
@@ -335,6 +335,22 @@ fn module_resolution_relative_path_2() {
335} 335}
336 336
337#[test] 337#[test]
338fn module_resolution_relative_path_outside_root() {
339 let map = def_map(
340 r###"
341 //- /main.rs
342
343 #[path="../../../../../outside.rs"]
344 mod foo;
345 "###,
346 );
347
348 assert_snapshot!(map, @r###"
349 ⋮crate
350 "###);
351}
352
353#[test]
338fn module_resolution_explicit_path_mod_rs_2() { 354fn module_resolution_explicit_path_mod_rs_2() {
339 let map = def_map( 355 let map = def_map(
340 r###" 356 r###"