aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/nameres/collector.rs40
-rw-r--r--crates/ra_hir/src/nameres/mod_resolution.rs232
-rw-r--r--crates/ra_hir/src/nameres/tests/macros.rs29
-rw-r--r--crates/ra_hir/src/nameres/tests/mod_resolution.rs214
4 files changed, 233 insertions, 282 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index cef2dc9d2..88aee7437 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -2,7 +2,7 @@
2 2
3use ra_cfg::CfgOptions; 3use ra_cfg::CfgOptions;
4use ra_db::FileId; 4use ra_db::FileId;
5use ra_syntax::{ast, SmolStr}; 5use ra_syntax::ast;
6use rustc_hash::FxHashMap; 6use rustc_hash::FxHashMap;
7use test_utils::tested_by; 7use test_utils::tested_by;
8 8
@@ -11,10 +11,8 @@ use crate::{
11 ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind}, 11 ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind},
12 name::MACRO_RULES, 12 name::MACRO_RULES,
13 nameres::{ 13 nameres::{
14 diagnostics::DefDiagnostic, 14 diagnostics::DefDiagnostic, mod_resolution::ModDir, raw, Crate, CrateDefMap, CrateModuleId,
15 mod_resolution::{resolve_submodule, ParentModule}, 15 ModuleData, ModuleDef, PerNs, ReachedFixedPoint, Resolution, ResolveMode,
16 raw, Crate, CrateDefMap, CrateModuleId, ModuleData, ModuleDef, PerNs, ReachedFixedPoint,
17 Resolution, ResolveMode,
18 }, 16 },
19 Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static, 17 Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static,
20 Struct, Trait, TypeAlias, Union, 18 Struct, Trait, TypeAlias, Union,
@@ -45,6 +43,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
45 glob_imports: FxHashMap::default(), 43 glob_imports: FxHashMap::default(),
46 unresolved_imports: Vec::new(), 44 unresolved_imports: Vec::new(),
47 unexpanded_macros: Vec::new(), 45 unexpanded_macros: Vec::new(),
46 mod_dirs: FxHashMap::default(),
48 macro_stack_monitor: MacroStackMonitor::default(), 47 macro_stack_monitor: MacroStackMonitor::default(),
49 cfg_options, 48 cfg_options,
50 }; 49 };
@@ -87,6 +86,7 @@ struct DefCollector<'a, DB> {
87 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, 86 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
88 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, 87 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>,
89 unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>, 88 unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>,
89 mod_dirs: FxHashMap<CrateModuleId, ModDir>,
90 90
91 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly 91 /// Some macro use `$tt:tt which mean we have to handle the macro perfectly
92 /// To prevent stack overflow, we add a deep counter here for prevent that. 92 /// To prevent stack overflow, we add a deep counter here for prevent that.
@@ -107,11 +107,10 @@ where
107 self.def_map.modules[module_id].definition = Some(file_id); 107 self.def_map.modules[module_id].definition = Some(file_id);
108 ModCollector { 108 ModCollector {
109 def_collector: &mut *self, 109 def_collector: &mut *self,
110 attr_path: None,
111 module_id, 110 module_id,
112 file_id: file_id.into(), 111 file_id: file_id.into(),
113 raw_items: &raw_items, 112 raw_items: &raw_items,
114 parent_module: None, 113 mod_dir: ModDir::root(),
115 } 114 }
116 .collect(raw_items.items()); 115 .collect(raw_items.items());
117 116
@@ -481,13 +480,13 @@ where
481 if !self.macro_stack_monitor.is_poison(macro_def_id) { 480 if !self.macro_stack_monitor.is_poison(macro_def_id) {
482 let file_id: HirFileId = macro_call_id.as_file(MacroFileKind::Items); 481 let file_id: HirFileId = macro_call_id.as_file(MacroFileKind::Items);
483 let raw_items = self.db.raw_items(file_id); 482 let raw_items = self.db.raw_items(file_id);
483 let mod_dir = self.mod_dirs[&module_id].clone();
484 ModCollector { 484 ModCollector {
485 def_collector: &mut *self, 485 def_collector: &mut *self,
486 file_id, 486 file_id,
487 attr_path: None,
488 module_id, 487 module_id,
489 raw_items: &raw_items, 488 raw_items: &raw_items,
490 parent_module: None, 489 mod_dir,
491 } 490 }
492 .collect(raw_items.items()); 491 .collect(raw_items.items());
493 } else { 492 } else {
@@ -508,9 +507,8 @@ struct ModCollector<'a, D> {
508 def_collector: D, 507 def_collector: D,
509 module_id: CrateModuleId, 508 module_id: CrateModuleId,
510 file_id: HirFileId, 509 file_id: HirFileId,
511 attr_path: Option<&'a SmolStr>,
512 raw_items: &'a raw::RawItems, 510 raw_items: &'a raw::RawItems,
513 parent_module: Option<ParentModule<'a>>, 511 mod_dir: ModDir,
514} 512}
515 513
516impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>> 514impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>>
@@ -518,6 +516,10 @@ where
518 DB: DefDatabase, 516 DB: DefDatabase,
519{ 517{
520 fn collect(&mut self, items: &[raw::RawItem]) { 518 fn collect(&mut self, items: &[raw::RawItem]) {
519 // Note: don't assert that inserted value is fresh: it's simply not true
520 // for macros.
521 self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
522
521 // Prelude module is always considered to be `#[macro_use]`. 523 // Prelude module is always considered to be `#[macro_use]`.
522 if let Some(prelude_module) = self.def_collector.def_map.prelude { 524 if let Some(prelude_module) = self.def_collector.def_map.prelude {
523 if prelude_module.krate != self.def_collector.def_map.krate { 525 if prelude_module.krate != self.def_collector.def_map.krate {
@@ -561,15 +563,13 @@ where
561 raw::ModuleData::Definition { name, items, ast_id, attr_path, is_macro_use } => { 563 raw::ModuleData::Definition { name, items, ast_id, attr_path, is_macro_use } => {
562 let module_id = 564 let module_id =
563 self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); 565 self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None);
564 let parent_module = ParentModule { name, attr_path: attr_path.as_ref() };
565 566
566 ModCollector { 567 ModCollector {
567 def_collector: &mut *self.def_collector, 568 def_collector: &mut *self.def_collector,
568 module_id, 569 module_id,
569 attr_path: attr_path.as_ref(),
570 file_id: self.file_id, 570 file_id: self.file_id,
571 raw_items: self.raw_items, 571 raw_items: self.raw_items,
572 parent_module: Some(parent_module), 572 mod_dir: self.mod_dir.descend_into_definition(name, attr_path.as_ref()),
573 } 573 }
574 .collect(&*items); 574 .collect(&*items);
575 if *is_macro_use { 575 if *is_macro_use {
@@ -579,26 +579,21 @@ where
579 // out of line module, resolve, parse and recurse 579 // out of line module, resolve, parse and recurse
580 raw::ModuleData::Declaration { name, ast_id, attr_path, is_macro_use } => { 580 raw::ModuleData::Declaration { name, ast_id, attr_path, is_macro_use } => {
581 let ast_id = ast_id.with_file_id(self.file_id); 581 let ast_id = ast_id.with_file_id(self.file_id);
582 let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); 582 match self.mod_dir.resolve_submodule(
583 match resolve_submodule(
584 self.def_collector.db, 583 self.def_collector.db,
585 self.file_id, 584 self.file_id,
586 self.attr_path,
587 name, 585 name,
588 is_root,
589 attr_path.as_ref(), 586 attr_path.as_ref(),
590 self.parent_module,
591 ) { 587 ) {
592 Ok(file_id) => { 588 Ok((file_id, mod_dir)) => {
593 let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); 589 let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
594 let raw_items = self.def_collector.db.raw_items(file_id.into()); 590 let raw_items = self.def_collector.db.raw_items(file_id.into());
595 ModCollector { 591 ModCollector {
596 def_collector: &mut *self.def_collector, 592 def_collector: &mut *self.def_collector,
597 module_id, 593 module_id,
598 attr_path: attr_path.as_ref(),
599 file_id: file_id.into(), 594 file_id: file_id.into(),
600 raw_items: &raw_items, 595 raw_items: &raw_items,
601 parent_module: None, 596 mod_dir,
602 } 597 }
603 .collect(raw_items.items()); 598 .collect(raw_items.items());
604 if *is_macro_use { 599 if *is_macro_use {
@@ -747,6 +742,7 @@ mod tests {
747 glob_imports: FxHashMap::default(), 742 glob_imports: FxHashMap::default(),
748 unresolved_imports: Vec::new(), 743 unresolved_imports: Vec::new(),
749 unexpanded_macros: Vec::new(), 744 unexpanded_macros: Vec::new(),
745 mod_dirs: FxHashMap::default(),
750 macro_stack_monitor: monitor, 746 macro_stack_monitor: monitor,
751 cfg_options: &CfgOptions::default(), 747 cfg_options: &CfgOptions::default(),
752 }; 748 };
diff --git a/crates/ra_hir/src/nameres/mod_resolution.rs b/crates/ra_hir/src/nameres/mod_resolution.rs
index 3aa32bd66..f50f9abe6 100644
--- a/crates/ra_hir/src/nameres/mod_resolution.rs
+++ b/crates/ra_hir/src/nameres/mod_resolution.rs
@@ -1,111 +1,105 @@
1//! This module resolves `mod foo;` declaration to file. 1//! This module resolves `mod foo;` declaration to file.
2use std::borrow::Cow;
2 3
3use std::{borrow::Cow, sync::Arc}; 4use ra_db::FileId;
4
5use ra_db::{FileId, SourceRoot};
6use ra_syntax::SmolStr; 5use ra_syntax::SmolStr;
7use relative_path::RelativePathBuf; 6use relative_path::{RelativePath, RelativePathBuf};
8 7
9use crate::{db::DefDatabase, HirFileId, Name}; 8use crate::{db::DefDatabase, HirFileId, Name};
10 9
11#[derive(Clone, Copy)] 10#[derive(Clone, Debug)]
12pub(super) struct ParentModule<'a> { 11pub(super) struct ModDir {
13 pub(super) name: &'a Name, 12 /// `.` for `mod.rs`, `lib.rs`
14 pub(super) attr_path: Option<&'a SmolStr>, 13 /// `./foo` for `foo.rs`
14 /// `./foo/bar` for `mod bar { mod x; }` nested in `foo.rs`
15 path: RelativePathBuf,
16 /// inside `./foo.rs`, mods with `#[path]` should *not* be relative to `./foo/`
17 root_non_dir_owner: bool,
15} 18}
16 19
17impl<'a> ParentModule<'a> { 20impl ModDir {
18 fn attribute_path(&self) -> Option<&SmolStr> { 21 pub(super) fn root() -> ModDir {
19 self.attr_path.filter(|p| !p.is_empty()) 22 ModDir { path: RelativePathBuf::default(), root_non_dir_owner: false }
20 } 23 }
21}
22
23pub(super) fn resolve_submodule(
24 db: &impl DefDatabase,
25 file_id: HirFileId,
26 mod_attr_path: Option<&SmolStr>,
27 name: &Name,
28 is_root: bool,
29 attr_path: Option<&SmolStr>,
30 parent_module: Option<ParentModule<'_>>,
31) -> Result<FileId, RelativePathBuf> {
32 let file_id = file_id.original_file(db);
33 let source_root_id = db.file_source_root(file_id);
34 let path = db.file_relative_path(file_id);
35 let root = RelativePathBuf::default();
36 let dir_path = path.parent().unwrap_or(&root);
37 let mod_name = path.file_stem().unwrap_or("unknown");
38 24
39 let resolve_mode = match (attr_path.filter(|p| !p.is_empty()), parent_module) { 25 pub(super) fn descend_into_definition(
40 (Some(file_path), Some(parent_module)) => { 26 &self,
41 let file_path = normalize_attribute_path(file_path); 27 name: &Name,
42 match parent_module.attribute_path() { 28 attr_path: Option<&SmolStr>,
43 Some(parent_module_attr_path) => { 29 ) -> ModDir {
44 let path = dir_path 30 let mut path = self.path.clone();
45 .join(format!( 31 match attr_path {
46 "{}/{}", 32 None => path.push(&name.to_string()),
47 normalize_attribute_path(parent_module_attr_path), 33 Some(attr_path) => {
48 file_path 34 if self.root_non_dir_owner {
49 )) 35 path = path
50 .normalize(); 36 .parent()
51 ResolutionMode::InlineModuleWithAttributePath( 37 .map(|it| it.to_relative_path_buf())
52 InsideInlineModuleMode::WithAttributePath(path), 38 .unwrap_or_else(RelativePathBuf::new);
53 )
54 }
55 None => {
56 let path =
57 dir_path.join(format!("{}/{}", parent_module.name, file_path)).normalize();
58 ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath(
59 path,
60 ))
61 } 39 }
40 let attr_path = &*normalize_attribute_path(attr_path);
41 path.push(RelativePath::new(attr_path));
62 } 42 }
63 } 43 }
64 (None, Some(parent_module)) => match parent_module.attribute_path() { 44 ModDir { path, root_non_dir_owner: false }
65 Some(parent_module_attr_path) => { 45 }
66 let path = dir_path.join(format!( 46
67 "{}/{}.rs", 47 pub(super) fn resolve_submodule(
68 normalize_attribute_path(parent_module_attr_path), 48 &self,
69 name 49 db: &impl DefDatabase,
70 )); 50 file_id: HirFileId,
71 ResolutionMode::InlineModuleWithAttributePath(InsideInlineModuleMode::File(path)) 51 name: &Name,
52 attr_path: Option<&SmolStr>,
53 ) -> Result<(FileId, ModDir), RelativePathBuf> {
54 let empty_path = RelativePathBuf::default();
55 let file_id = file_id.original_file(db);
56 let base_dir = {
57 let path = db.file_relative_path(file_id);
58 path.parent().unwrap_or(&empty_path).join(&self.path)
59 };
60
61 let mut candidate_files = Vec::new();
62 match attr_path {
63 Some(attr) => {
64 let base = if self.root_non_dir_owner {
65 base_dir.parent().unwrap_or(&empty_path)
66 } else {
67 &base_dir
68 };
69 candidate_files.push(base.join(&*normalize_attribute_path(attr)))
72 } 70 }
73 None => { 71 None => {
74 let path = dir_path.join(format!("{}/{}.rs", parent_module.name, name)); 72 candidate_files.push(base_dir.join(&format!("{}.rs", name)));
75 ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path)) 73 candidate_files.push(base_dir.join(&format!("{}/mod.rs", name)));
76 } 74 }
77 }, 75 };
78 (Some(file_path), None) => { 76
79 let file_path = normalize_attribute_path(file_path); 77 let source_root_id = db.file_source_root(file_id);
80 let path = dir_path.join(file_path.as_ref()).normalize(); 78 let source_root = db.source_root(source_root_id);
81 ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path)) 79 for candidate in candidate_files.iter() {
82 } 80 let candidate = candidate.normalize();
83 (None, None) => { 81 if let Some(file_id) = source_root.file_by_relative_path(&candidate) {
84 let is_dir_owner = is_root || mod_name == "mod" || mod_attr_path.is_some(); 82 let mut root_non_dir_owner = false;
85 if is_dir_owner { 83 let mut mod_path = RelativePathBuf::new();
86 let file_mod = dir_path.join(format!("{}.rs", name)); 84 if !(candidate.ends_with("mod.rs") || attr_path.is_some()) {
87 let dir_mod = dir_path.join(format!("{}/mod.rs", name)); 85 root_non_dir_owner = true;
88 ResolutionMode::OutOfLine(OutOfLineMode::RootOrModRs { 86 mod_path.push(&name.to_string());
89 file: file_mod, 87 }
90 directory: dir_mod, 88 return Ok((file_id, ModDir { path: mod_path, root_non_dir_owner }));
91 })
92 } else {
93 let path = dir_path.join(format!("{}/{}.rs", mod_name, name));
94 ResolutionMode::OutOfLine(OutOfLineMode::FileInDirectory(path))
95 } 89 }
96 } 90 }
97 }; 91 let suggestion = candidate_files.first().unwrap();
98 92 Err(base_dir.join(suggestion))
99 resolve_mode.resolve(db.source_root(source_root_id)) 93 }
100} 94}
101 95
102fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> { 96fn normalize_attribute_path(file_path: &str) -> Cow<str> {
103 let current_dir = "./"; 97 let current_dir = "./";
104 let windows_path_separator = r#"\"#; 98 let windows_path_separator = r#"\"#;
105 let current_dir_normalize = if file_path.starts_with(current_dir) { 99 let current_dir_normalize = if file_path.starts_with(current_dir) {
106 &file_path[current_dir.len()..] 100 &file_path[current_dir.len()..]
107 } else { 101 } else {
108 file_path.as_str() 102 file_path
109 }; 103 };
110 if current_dir_normalize.contains(windows_path_separator) { 104 if current_dir_normalize.contains(windows_path_separator) {
111 Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/")) 105 Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/"))
@@ -113,75 +107,3 @@ fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> {
113 Cow::Borrowed(current_dir_normalize) 107 Cow::Borrowed(current_dir_normalize)
114 } 108 }
115} 109}
116
117enum OutOfLineMode {
118 RootOrModRs { file: RelativePathBuf, directory: RelativePathBuf },
119 FileInDirectory(RelativePathBuf),
120 WithAttributePath(RelativePathBuf),
121}
122
123impl OutOfLineMode {
124 pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
125 match self {
126 OutOfLineMode::RootOrModRs { file, directory } => {
127 match source_root.file_by_relative_path(file) {
128 None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()),
129 file_id => resolve_find_result(file_id, file),
130 }
131 }
132 OutOfLineMode::FileInDirectory(path) => resolve_simple_path(source_root, path),
133 OutOfLineMode::WithAttributePath(path) => resolve_simple_path(source_root, path),
134 }
135 }
136}
137
138enum InsideInlineModuleMode {
139 File(RelativePathBuf),
140 WithAttributePath(RelativePathBuf),
141}
142
143impl InsideInlineModuleMode {
144 pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
145 match self {
146 InsideInlineModuleMode::File(path) => resolve_simple_path(source_root, path),
147 InsideInlineModuleMode::WithAttributePath(path) => {
148 resolve_simple_path(source_root, path)
149 }
150 }
151 }
152}
153
154enum ResolutionMode {
155 OutOfLine(OutOfLineMode),
156 InsideInlineModule(InsideInlineModuleMode),
157 InlineModuleWithAttributePath(InsideInlineModuleMode),
158}
159
160impl ResolutionMode {
161 pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
162 use self::ResolutionMode::*;
163
164 match self {
165 OutOfLine(mode) => mode.resolve(source_root),
166 InsideInlineModule(mode) => mode.resolve(source_root),
167 InlineModuleWithAttributePath(mode) => mode.resolve(source_root),
168 }
169 }
170}
171
172fn resolve_simple_path(
173 source_root: Arc<SourceRoot>,
174 path: &RelativePathBuf,
175) -> Result<FileId, RelativePathBuf> {
176 resolve_find_result(source_root.file_by_relative_path(path), path)
177}
178
179fn resolve_find_result(
180 file_id: Option<FileId>,
181 path: &RelativePathBuf,
182) -> Result<FileId, RelativePathBuf> {
183 match file_id {
184 Some(file_id) => Ok(file_id.clone()),
185 None => Err(path.clone()),
186 }
187}
diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs
index e4b408394..4f52ad2c5 100644
--- a/crates/ra_hir/src/nameres/tests/macros.rs
+++ b/crates/ra_hir/src/nameres/tests/macros.rs
@@ -38,21 +38,34 @@ fn macro_rules_can_define_modules() {
38 } 38 }
39 m!(n1); 39 m!(n1);
40 40
41 mod m {
42 m!(n3)
43 }
44
41 //- /n1.rs 45 //- /n1.rs
42 m!(n2) 46 m!(n2)
43 //- /n1/n2.rs 47 //- /n1/n2.rs
44 struct X; 48 struct X;
49 //- /m/n3.rs
50 struct Y;
45 ", 51 ",
46 ); 52 );
47 assert_snapshot!(map, @r###" 53 assert_snapshot!(map, @r###"
48 ⋮crate 54 crate
49 ⋮n1: t 55 m: t
50 56 n1: t
51 ⋮crate::n1 57
52 ⋮n2: t 58 crate::m
53 59 n3: t
54 ⋮crate::n1::n2 60
55 ⋮X: t v 61 crate::m::n3
62 Y: t v
63
64 crate::n1
65 n2: t
66
67 crate::n1::n2
68 X: t v
56 "###); 69 "###);
57} 70}
58 71
diff --git a/crates/ra_hir/src/nameres/tests/mod_resolution.rs b/crates/ra_hir/src/nameres/tests/mod_resolution.rs
index e3e6f1e95..f569aacdc 100644
--- a/crates/ra_hir/src/nameres/tests/mod_resolution.rs
+++ b/crates/ra_hir/src/nameres/tests/mod_resolution.rs
@@ -26,6 +26,33 @@ fn name_res_works_for_broken_modules() {
26} 26}
27 27
28#[test] 28#[test]
29fn nested_module_resolution() {
30 let map = def_map(
31 "
32 //- /lib.rs
33 mod n1;
34
35 //- /n1.rs
36 mod n2;
37
38 //- /n1/n2.rs
39 struct X;
40 ",
41 );
42
43 assert_snapshot!(map, @r###"
44 ⋮crate
45 ⋮n1: t
46
47 ⋮crate::n1
48 ⋮n2: t
49
50 ⋮crate::n1::n2
51 ⋮X: t v
52 "###);
53}
54
55#[test]
29fn module_resolution_works_for_non_standard_filenames() { 56fn module_resolution_works_for_non_standard_filenames() {
30 let map = def_map_with_crate_graph( 57 let map = def_map_with_crate_graph(
31 " 58 "
@@ -53,18 +80,15 @@ fn module_resolution_works_for_non_standard_filenames() {
53 80
54#[test] 81#[test]
55fn module_resolution_works_for_raw_modules() { 82fn module_resolution_works_for_raw_modules() {
56 let map = def_map_with_crate_graph( 83 let map = def_map(
57 " 84 "
58 //- /library.rs 85 //- /lib.rs
59 mod r#async; 86 mod r#async;
60 use self::r#async::Bar; 87 use self::r#async::Bar;
61 88
62 //- /async.rs 89 //- /async.rs
63 pub struct Bar; 90 pub struct Bar;
64 ", 91 ",
65 crate_graph! {
66 "library": ("/library.rs", []),
67 },
68 ); 92 );
69 93
70 assert_snapshot!(map, @r###" 94 assert_snapshot!(map, @r###"
@@ -79,9 +103,9 @@ fn module_resolution_works_for_raw_modules() {
79 103
80#[test] 104#[test]
81fn module_resolution_decl_path() { 105fn module_resolution_decl_path() {
82 let map = def_map_with_crate_graph( 106 let map = def_map(
83 r###" 107 r###"
84 //- /library.rs 108 //- /lib.rs
85 #[path = "bar/baz/foo.rs"] 109 #[path = "bar/baz/foo.rs"]
86 mod foo; 110 mod foo;
87 use self::foo::Bar; 111 use self::foo::Bar;
@@ -89,9 +113,6 @@ fn module_resolution_decl_path() {
89 //- /bar/baz/foo.rs 113 //- /bar/baz/foo.rs
90 pub struct Bar; 114 pub struct Bar;
91 "###, 115 "###,
92 crate_graph! {
93 "library": ("/library.rs", []),
94 },
95 ); 116 );
96 117
97 assert_snapshot!(map, @r###" 118 assert_snapshot!(map, @r###"
@@ -106,7 +127,7 @@ fn module_resolution_decl_path() {
106 127
107#[test] 128#[test]
108fn module_resolution_module_with_path_in_mod_rs() { 129fn module_resolution_module_with_path_in_mod_rs() {
109 let map = def_map_with_crate_graph( 130 let map = def_map(
110 r###" 131 r###"
111 //- /main.rs 132 //- /main.rs
112 mod foo; 133 mod foo;
@@ -120,9 +141,6 @@ fn module_resolution_module_with_path_in_mod_rs() {
120 //- /foo/baz.rs 141 //- /foo/baz.rs
121 pub struct Baz; 142 pub struct Baz;
122 "###, 143 "###,
123 crate_graph! {
124 "main": ("/main.rs", []),
125 },
126 ); 144 );
127 145
128 assert_snapshot!(map, @r###" 146 assert_snapshot!(map, @r###"
@@ -140,7 +158,7 @@ fn module_resolution_module_with_path_in_mod_rs() {
140 158
141#[test] 159#[test]
142fn module_resolution_module_with_path_non_crate_root() { 160fn module_resolution_module_with_path_non_crate_root() {
143 let map = def_map_with_crate_graph( 161 let map = def_map(
144 r###" 162 r###"
145 //- /main.rs 163 //- /main.rs
146 mod foo; 164 mod foo;
@@ -154,9 +172,6 @@ fn module_resolution_module_with_path_non_crate_root() {
154 //- /baz.rs 172 //- /baz.rs
155 pub struct Baz; 173 pub struct Baz;
156 "###, 174 "###,
157 crate_graph! {
158 "main": ("/main.rs", []),
159 },
160 ); 175 );
161 176
162 assert_snapshot!(map, @r###" 177 assert_snapshot!(map, @r###"
@@ -174,7 +189,7 @@ fn module_resolution_module_with_path_non_crate_root() {
174 189
175#[test] 190#[test]
176fn module_resolution_module_decl_path_super() { 191fn module_resolution_module_decl_path_super() {
177 let map = def_map_with_crate_graph( 192 let map = def_map(
178 r###" 193 r###"
179 //- /main.rs 194 //- /main.rs
180 #[path = "bar/baz/module.rs"] 195 #[path = "bar/baz/module.rs"]
@@ -184,9 +199,6 @@ fn module_resolution_module_decl_path_super() {
184 //- /bar/baz/module.rs 199 //- /bar/baz/module.rs
185 use super::Baz; 200 use super::Baz;
186 "###, 201 "###,
187 crate_graph! {
188 "main": ("/main.rs", []),
189 },
190 ); 202 );
191 203
192 assert_snapshot!(map, @r###" 204 assert_snapshot!(map, @r###"
@@ -201,7 +213,7 @@ fn module_resolution_module_decl_path_super() {
201 213
202#[test] 214#[test]
203fn module_resolution_explicit_path_mod_rs() { 215fn module_resolution_explicit_path_mod_rs() {
204 let map = def_map_with_crate_graph( 216 let map = def_map(
205 r###" 217 r###"
206 //- /main.rs 218 //- /main.rs
207 #[path = "module/mod.rs"] 219 #[path = "module/mod.rs"]
@@ -210,9 +222,6 @@ fn module_resolution_explicit_path_mod_rs() {
210 //- /module/mod.rs 222 //- /module/mod.rs
211 pub struct Baz; 223 pub struct Baz;
212 "###, 224 "###,
213 crate_graph! {
214 "main": ("/main.rs", []),
215 },
216 ); 225 );
217 226
218 assert_snapshot!(map, @r###" 227 assert_snapshot!(map, @r###"
@@ -226,7 +235,7 @@ fn module_resolution_explicit_path_mod_rs() {
226 235
227#[test] 236#[test]
228fn module_resolution_relative_path() { 237fn module_resolution_relative_path() {
229 let map = def_map_with_crate_graph( 238 let map = def_map(
230 r###" 239 r###"
231 //- /main.rs 240 //- /main.rs
232 mod foo; 241 mod foo;
@@ -238,9 +247,6 @@ fn module_resolution_relative_path() {
238 //- /sub.rs 247 //- /sub.rs
239 pub struct Baz; 248 pub struct Baz;
240 "###, 249 "###,
241 crate_graph! {
242 "main": ("/main.rs", []),
243 },
244 ); 250 );
245 251
246 assert_snapshot!(map, @r###" 252 assert_snapshot!(map, @r###"
@@ -257,7 +263,7 @@ fn module_resolution_relative_path() {
257 263
258#[test] 264#[test]
259fn module_resolution_relative_path_2() { 265fn module_resolution_relative_path_2() {
260 let map = def_map_with_crate_graph( 266 let map = def_map(
261 r###" 267 r###"
262 //- /main.rs 268 //- /main.rs
263 mod foo; 269 mod foo;
@@ -269,9 +275,6 @@ fn module_resolution_relative_path_2() {
269 //- /sub.rs 275 //- /sub.rs
270 pub struct Baz; 276 pub struct Baz;
271 "###, 277 "###,
272 crate_graph! {
273 "main": ("/main.rs", []),
274 },
275 ); 278 );
276 279
277 assert_snapshot!(map, @r###" 280 assert_snapshot!(map, @r###"
@@ -288,7 +291,7 @@ fn module_resolution_relative_path_2() {
288 291
289#[test] 292#[test]
290fn module_resolution_explicit_path_mod_rs_2() { 293fn module_resolution_explicit_path_mod_rs_2() {
291 let map = def_map_with_crate_graph( 294 let map = def_map(
292 r###" 295 r###"
293 //- /main.rs 296 //- /main.rs
294 #[path = "module/bar/mod.rs"] 297 #[path = "module/bar/mod.rs"]
@@ -297,9 +300,6 @@ fn module_resolution_explicit_path_mod_rs_2() {
297 //- /module/bar/mod.rs 300 //- /module/bar/mod.rs
298 pub struct Baz; 301 pub struct Baz;
299 "###, 302 "###,
300 crate_graph! {
301 "main": ("/main.rs", []),
302 },
303 ); 303 );
304 304
305 assert_snapshot!(map, @r###" 305 assert_snapshot!(map, @r###"
@@ -313,7 +313,7 @@ fn module_resolution_explicit_path_mod_rs_2() {
313 313
314#[test] 314#[test]
315fn module_resolution_explicit_path_mod_rs_with_win_separator() { 315fn module_resolution_explicit_path_mod_rs_with_win_separator() {
316 let map = def_map_with_crate_graph( 316 let map = def_map(
317 r###" 317 r###"
318 //- /main.rs 318 //- /main.rs
319 #[path = "module\bar\mod.rs"] 319 #[path = "module\bar\mod.rs"]
@@ -322,9 +322,6 @@ fn module_resolution_explicit_path_mod_rs_with_win_separator() {
322 //- /module/bar/mod.rs 322 //- /module/bar/mod.rs
323 pub struct Baz; 323 pub struct Baz;
324 "###, 324 "###,
325 crate_graph! {
326 "main": ("/main.rs", []),
327 },
328 ); 325 );
329 326
330 assert_snapshot!(map, @r###" 327 assert_snapshot!(map, @r###"
@@ -338,7 +335,7 @@ fn module_resolution_explicit_path_mod_rs_with_win_separator() {
338 335
339#[test] 336#[test]
340fn module_resolution_decl_inside_inline_module_with_path_attribute() { 337fn module_resolution_decl_inside_inline_module_with_path_attribute() {
341 let map = def_map_with_crate_graph( 338 let map = def_map(
342 r###" 339 r###"
343 //- /main.rs 340 //- /main.rs
344 #[path = "models"] 341 #[path = "models"]
@@ -349,9 +346,6 @@ fn module_resolution_decl_inside_inline_module_with_path_attribute() {
349 //- /models/bar.rs 346 //- /models/bar.rs
350 pub struct Baz; 347 pub struct Baz;
351 "###, 348 "###,
352 crate_graph! {
353 "main": ("/main.rs", []),
354 },
355 ); 349 );
356 350
357 assert_snapshot!(map, @r###" 351 assert_snapshot!(map, @r###"
@@ -368,7 +362,7 @@ fn module_resolution_decl_inside_inline_module_with_path_attribute() {
368 362
369#[test] 363#[test]
370fn module_resolution_decl_inside_inline_module() { 364fn module_resolution_decl_inside_inline_module() {
371 let map = def_map_with_crate_graph( 365 let map = def_map(
372 r###" 366 r###"
373 //- /main.rs 367 //- /main.rs
374 mod foo { 368 mod foo {
@@ -378,9 +372,6 @@ fn module_resolution_decl_inside_inline_module() {
378 //- /foo/bar.rs 372 //- /foo/bar.rs
379 pub struct Baz; 373 pub struct Baz;
380 "###, 374 "###,
381 crate_graph! {
382 "main": ("/main.rs", []),
383 },
384 ); 375 );
385 376
386 assert_snapshot!(map, @r###" 377 assert_snapshot!(map, @r###"
@@ -397,7 +388,7 @@ fn module_resolution_decl_inside_inline_module() {
397 388
398#[test] 389#[test]
399fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { 390fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
400 let map = def_map_with_crate_graph( 391 let map = def_map(
401 r###" 392 r###"
402 //- /main.rs 393 //- /main.rs
403 #[path = "models/db"] 394 #[path = "models/db"]
@@ -408,9 +399,6 @@ fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
408 //- /models/db/bar.rs 399 //- /models/db/bar.rs
409 pub struct Baz; 400 pub struct Baz;
410 "###, 401 "###,
411 crate_graph! {
412 "main": ("/main.rs", []),
413 },
414 ); 402 );
415 403
416 assert_snapshot!(map, @r###" 404 assert_snapshot!(map, @r###"
@@ -427,7 +415,7 @@ fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
427 415
428#[test] 416#[test]
429fn module_resolution_decl_inside_inline_module_3() { 417fn module_resolution_decl_inside_inline_module_3() {
430 let map = def_map_with_crate_graph( 418 let map = def_map(
431 r###" 419 r###"
432 //- /main.rs 420 //- /main.rs
433 #[path = "models/db"] 421 #[path = "models/db"]
@@ -439,9 +427,6 @@ fn module_resolution_decl_inside_inline_module_3() {
439 //- /models/db/users.rs 427 //- /models/db/users.rs
440 pub struct Baz; 428 pub struct Baz;
441 "###, 429 "###,
442 crate_graph! {
443 "main": ("/main.rs", []),
444 },
445 ); 430 );
446 431
447 assert_snapshot!(map, @r###" 432 assert_snapshot!(map, @r###"
@@ -458,7 +443,7 @@ fn module_resolution_decl_inside_inline_module_3() {
458 443
459#[test] 444#[test]
460fn module_resolution_decl_inside_inline_module_empty_path() { 445fn module_resolution_decl_inside_inline_module_empty_path() {
461 let map = def_map_with_crate_graph( 446 let map = def_map(
462 r###" 447 r###"
463 //- /main.rs 448 //- /main.rs
464 #[path = ""] 449 #[path = ""]
@@ -467,12 +452,9 @@ fn module_resolution_decl_inside_inline_module_empty_path() {
467 mod bar; 452 mod bar;
468 } 453 }
469 454
470 //- /foo/users.rs 455 //- /users.rs
471 pub struct Baz; 456 pub struct Baz;
472 "###, 457 "###,
473 crate_graph! {
474 "main": ("/main.rs", []),
475 },
476 ); 458 );
477 459
478 assert_snapshot!(map, @r###" 460 assert_snapshot!(map, @r###"
@@ -489,32 +471,25 @@ fn module_resolution_decl_inside_inline_module_empty_path() {
489 471
490#[test] 472#[test]
491fn module_resolution_decl_empty_path() { 473fn module_resolution_decl_empty_path() {
492 let map = def_map_with_crate_graph( 474 let map = def_map(
493 r###" 475 r###"
494 //- /main.rs 476 //- /main.rs
495 #[path = ""] 477 #[path = ""] // Should try to read `/` (a directory)
496 mod foo; 478 mod foo;
497 479
498 //- /foo.rs 480 //- /foo.rs
499 pub struct Baz; 481 pub struct Baz;
500 "###, 482 "###,
501 crate_graph! {
502 "main": ("/main.rs", []),
503 },
504 ); 483 );
505 484
506 assert_snapshot!(map, @r###" 485 assert_snapshot!(map, @r###"
507 ⋮crate 486 ⋮crate
508 ⋮foo: t
509
510 ⋮crate::foo
511 ⋮Baz: t v
512 "###); 487 "###);
513} 488}
514 489
515#[test] 490#[test]
516fn module_resolution_decl_inside_inline_module_relative_path() { 491fn module_resolution_decl_inside_inline_module_relative_path() {
517 let map = def_map_with_crate_graph( 492 let map = def_map(
518 r###" 493 r###"
519 //- /main.rs 494 //- /main.rs
520 #[path = "./models"] 495 #[path = "./models"]
@@ -525,9 +500,6 @@ fn module_resolution_decl_inside_inline_module_relative_path() {
525 //- /models/bar.rs 500 //- /models/bar.rs
526 pub struct Baz; 501 pub struct Baz;
527 "###, 502 "###,
528 crate_graph! {
529 "main": ("/main.rs", []),
530 },
531 ); 503 );
532 504
533 assert_snapshot!(map, @r###" 505 assert_snapshot!(map, @r###"
@@ -544,7 +516,7 @@ fn module_resolution_decl_inside_inline_module_relative_path() {
544 516
545#[test] 517#[test]
546fn module_resolution_decl_inside_inline_module_in_crate_root() { 518fn module_resolution_decl_inside_inline_module_in_crate_root() {
547 let map = def_map_with_crate_graph( 519 let map = def_map(
548 r###" 520 r###"
549 //- /main.rs 521 //- /main.rs
550 mod foo { 522 mod foo {
@@ -556,9 +528,6 @@ fn module_resolution_decl_inside_inline_module_in_crate_root() {
556 //- /foo/baz.rs 528 //- /foo/baz.rs
557 pub struct Baz; 529 pub struct Baz;
558 "###, 530 "###,
559 crate_graph! {
560 "main": ("/main.rs", []),
561 },
562 ); 531 );
563 532
564 assert_snapshot!(map, @r###" 533 assert_snapshot!(map, @r###"
@@ -576,7 +545,7 @@ fn module_resolution_decl_inside_inline_module_in_crate_root() {
576 545
577#[test] 546#[test]
578fn module_resolution_decl_inside_inline_module_in_mod_rs() { 547fn module_resolution_decl_inside_inline_module_in_mod_rs() {
579 let map = def_map_with_crate_graph( 548 let map = def_map(
580 r###" 549 r###"
581 //- /main.rs 550 //- /main.rs
582 mod foo; 551 mod foo;
@@ -591,9 +560,6 @@ fn module_resolution_decl_inside_inline_module_in_mod_rs() {
591 //- /foo/bar/qwe.rs 560 //- /foo/bar/qwe.rs
592 pub struct Baz; 561 pub struct Baz;
593 "###, 562 "###,
594 crate_graph! {
595 "main": ("/main.rs", []),
596 },
597 ); 563 );
598 564
599 assert_snapshot!(map, @r###" 565 assert_snapshot!(map, @r###"
@@ -614,7 +580,7 @@ fn module_resolution_decl_inside_inline_module_in_mod_rs() {
614 580
615#[test] 581#[test]
616fn module_resolution_decl_inside_inline_module_in_non_crate_root() { 582fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
617 let map = def_map_with_crate_graph( 583 let map = def_map(
618 r###" 584 r###"
619 //- /main.rs 585 //- /main.rs
620 mod foo; 586 mod foo;
@@ -626,12 +592,9 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
626 } 592 }
627 use self::bar::baz::Baz; 593 use self::bar::baz::Baz;
628 594
629 //- /bar/qwe.rs 595 //- /foo/bar/qwe.rs
630 pub struct Baz; 596 pub struct Baz;
631 "###, 597 "###,
632 crate_graph! {
633 "main": ("/main.rs", []),
634 },
635 ); 598 );
636 599
637 assert_snapshot!(map, @r###" 600 assert_snapshot!(map, @r###"
@@ -652,7 +615,7 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
652 615
653#[test] 616#[test]
654fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() { 617fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
655 let map = def_map_with_crate_graph( 618 let map = def_map(
656 r###" 619 r###"
657 //- /main.rs 620 //- /main.rs
658 mod foo; 621 mod foo;
@@ -667,9 +630,6 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
667 //- /bar/baz.rs 630 //- /bar/baz.rs
668 pub struct Baz; 631 pub struct Baz;
669 "###, 632 "###,
670 crate_graph! {
671 "main": ("/main.rs", []),
672 },
673 ); 633 );
674 634
675 assert_snapshot!(map, @r###" 635 assert_snapshot!(map, @r###"
@@ -709,7 +669,7 @@ fn unresolved_module_diagnostics() {
709 669
710#[test] 670#[test]
711fn module_resolution_decl_inside_module_in_non_crate_root_2() { 671fn module_resolution_decl_inside_module_in_non_crate_root_2() {
712 let map = def_map_with_crate_graph( 672 let map = def_map(
713 r###" 673 r###"
714 //- /main.rs 674 //- /main.rs
715 #[path="module/m2.rs"] 675 #[path="module/m2.rs"]
@@ -721,9 +681,6 @@ fn module_resolution_decl_inside_module_in_non_crate_root_2() {
721 //- /module/submod.rs 681 //- /module/submod.rs
722 pub struct Baz; 682 pub struct Baz;
723 "###, 683 "###,
724 crate_graph! {
725 "main": ("/main.rs", []),
726 },
727 ); 684 );
728 685
729 assert_snapshot!(map, @r###" 686 assert_snapshot!(map, @r###"
@@ -737,3 +694,66 @@ fn module_resolution_decl_inside_module_in_non_crate_root_2() {
737 ⋮Baz: t v 694 ⋮Baz: t v
738 "###); 695 "###);
739} 696}
697
698#[test]
699fn nested_out_of_line_module() {
700 let map = def_map(
701 r###"
702 //- /lib.rs
703 mod a {
704 mod b {
705 mod c;
706 }
707 }
708
709 //- /a/b/c.rs
710 struct X;
711 "###,
712 );
713
714 assert_snapshot!(map, @r###"
715 crate
716 a: t
717
718 crate::a
719 b: t
720
721 crate::a::b
722 c: t
723
724 crate::a::b::c
725 X: t v
726 "###);
727}
728
729#[test]
730fn nested_out_of_line_module_with_path() {
731 let map = def_map(
732 r###"
733 //- /lib.rs
734 mod a {
735 #[path = "d/e"]
736 mod b {
737 mod c;
738 }
739 }
740
741 //- /a/d/e/c.rs
742 struct X;
743 "###,
744 );
745
746 assert_snapshot!(map, @r###"
747 crate
748 a: t
749
750 crate::a
751 b: t
752
753 crate::a::b
754 c: t
755
756 crate::a::b::c
757 X: t v
758 "###);
759}