mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 09:27:27 +00:00
Merge #1979
1979: Refactor and fix some more edge cases around name resolution r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
8bcf40115f
4 changed files with 242 additions and 291 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
use ra_cfg::CfgOptions;
|
||||
use ra_db::FileId;
|
||||
use ra_syntax::{ast, SmolStr};
|
||||
use ra_syntax::ast;
|
||||
use rustc_hash::FxHashMap;
|
||||
use test_utils::tested_by;
|
||||
|
||||
|
@ -11,10 +11,8 @@ use crate::{
|
|||
ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind},
|
||||
name::MACRO_RULES,
|
||||
nameres::{
|
||||
diagnostics::DefDiagnostic,
|
||||
mod_resolution::{resolve_submodule, ParentModule},
|
||||
raw, Crate, CrateDefMap, CrateModuleId, ModuleData, ModuleDef, PerNs, ReachedFixedPoint,
|
||||
Resolution, ResolveMode,
|
||||
diagnostics::DefDiagnostic, mod_resolution::ModDir, raw, Crate, CrateDefMap, CrateModuleId,
|
||||
ModuleData, ModuleDef, PerNs, ReachedFixedPoint, Resolution, ResolveMode,
|
||||
},
|
||||
Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static,
|
||||
Struct, Trait, TypeAlias, Union,
|
||||
|
@ -45,6 +43,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
|
|||
glob_imports: FxHashMap::default(),
|
||||
unresolved_imports: Vec::new(),
|
||||
unexpanded_macros: Vec::new(),
|
||||
mod_dirs: FxHashMap::default(),
|
||||
macro_stack_monitor: MacroStackMonitor::default(),
|
||||
cfg_options,
|
||||
};
|
||||
|
@ -87,6 +86,7 @@ struct DefCollector<'a, DB> {
|
|||
glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
|
||||
unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>,
|
||||
unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>,
|
||||
mod_dirs: FxHashMap<CrateModuleId, ModDir>,
|
||||
|
||||
/// Some macro use `$tt:tt which mean we have to handle the macro perfectly
|
||||
/// To prevent stack overflow, we add a deep counter here for prevent that.
|
||||
|
@ -107,11 +107,10 @@ where
|
|||
self.def_map.modules[module_id].definition = Some(file_id);
|
||||
ModCollector {
|
||||
def_collector: &mut *self,
|
||||
attr_path: None,
|
||||
module_id,
|
||||
file_id: file_id.into(),
|
||||
raw_items: &raw_items,
|
||||
parent_module: None,
|
||||
mod_dir: ModDir::root(),
|
||||
}
|
||||
.collect(raw_items.items());
|
||||
|
||||
|
@ -481,13 +480,13 @@ where
|
|||
if !self.macro_stack_monitor.is_poison(macro_def_id) {
|
||||
let file_id: HirFileId = macro_call_id.as_file(MacroFileKind::Items);
|
||||
let raw_items = self.db.raw_items(file_id);
|
||||
let mod_dir = self.mod_dirs[&module_id].clone();
|
||||
ModCollector {
|
||||
def_collector: &mut *self,
|
||||
file_id,
|
||||
attr_path: None,
|
||||
module_id,
|
||||
raw_items: &raw_items,
|
||||
parent_module: None,
|
||||
mod_dir,
|
||||
}
|
||||
.collect(raw_items.items());
|
||||
} else {
|
||||
|
@ -508,9 +507,8 @@ struct ModCollector<'a, D> {
|
|||
def_collector: D,
|
||||
module_id: CrateModuleId,
|
||||
file_id: HirFileId,
|
||||
attr_path: Option<&'a SmolStr>,
|
||||
raw_items: &'a raw::RawItems,
|
||||
parent_module: Option<ParentModule<'a>>,
|
||||
mod_dir: ModDir,
|
||||
}
|
||||
|
||||
impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>>
|
||||
|
@ -518,6 +516,10 @@ where
|
|||
DB: DefDatabase,
|
||||
{
|
||||
fn collect(&mut self, items: &[raw::RawItem]) {
|
||||
// Note: don't assert that inserted value is fresh: it's simply not true
|
||||
// for macros.
|
||||
self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
|
||||
|
||||
// Prelude module is always considered to be `#[macro_use]`.
|
||||
if let Some(prelude_module) = self.def_collector.def_map.prelude {
|
||||
if prelude_module.krate != self.def_collector.def_map.krate {
|
||||
|
@ -561,15 +563,13 @@ where
|
|||
raw::ModuleData::Definition { name, items, ast_id, attr_path, is_macro_use } => {
|
||||
let module_id =
|
||||
self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None);
|
||||
let parent_module = ParentModule { name, attr_path: attr_path.as_ref() };
|
||||
|
||||
ModCollector {
|
||||
def_collector: &mut *self.def_collector,
|
||||
module_id,
|
||||
attr_path: attr_path.as_ref(),
|
||||
file_id: self.file_id,
|
||||
raw_items: self.raw_items,
|
||||
parent_module: Some(parent_module),
|
||||
mod_dir: self.mod_dir.descend_into_definition(name, attr_path.as_ref()),
|
||||
}
|
||||
.collect(&*items);
|
||||
if *is_macro_use {
|
||||
|
@ -579,26 +579,21 @@ where
|
|||
// out of line module, resolve, parse and recurse
|
||||
raw::ModuleData::Declaration { name, ast_id, attr_path, is_macro_use } => {
|
||||
let ast_id = ast_id.with_file_id(self.file_id);
|
||||
let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none();
|
||||
match resolve_submodule(
|
||||
match self.mod_dir.resolve_submodule(
|
||||
self.def_collector.db,
|
||||
self.file_id,
|
||||
self.attr_path,
|
||||
name,
|
||||
is_root,
|
||||
attr_path.as_ref(),
|
||||
self.parent_module,
|
||||
) {
|
||||
Ok(file_id) => {
|
||||
Ok((file_id, mod_dir)) => {
|
||||
let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
|
||||
let raw_items = self.def_collector.db.raw_items(file_id.into());
|
||||
ModCollector {
|
||||
def_collector: &mut *self.def_collector,
|
||||
module_id,
|
||||
attr_path: attr_path.as_ref(),
|
||||
file_id: file_id.into(),
|
||||
raw_items: &raw_items,
|
||||
parent_module: None,
|
||||
mod_dir,
|
||||
}
|
||||
.collect(raw_items.items());
|
||||
if *is_macro_use {
|
||||
|
@ -747,6 +742,7 @@ mod tests {
|
|||
glob_imports: FxHashMap::default(),
|
||||
unresolved_imports: Vec::new(),
|
||||
unexpanded_macros: Vec::new(),
|
||||
mod_dirs: FxHashMap::default(),
|
||||
macro_stack_monitor: monitor,
|
||||
cfg_options: &CfgOptions::default(),
|
||||
};
|
||||
|
|
|
@ -1,111 +1,105 @@
|
|||
//! This module resolves `mod foo;` declaration to file.
|
||||
use std::borrow::Cow;
|
||||
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
use ra_db::{FileId, SourceRoot};
|
||||
use ra_db::FileId;
|
||||
use ra_syntax::SmolStr;
|
||||
use relative_path::RelativePathBuf;
|
||||
use relative_path::{RelativePath, RelativePathBuf};
|
||||
|
||||
use crate::{db::DefDatabase, HirFileId, Name};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub(super) struct ParentModule<'a> {
|
||||
pub(super) name: &'a Name,
|
||||
pub(super) attr_path: Option<&'a SmolStr>,
|
||||
#[derive(Clone, Debug)]
|
||||
pub(super) struct ModDir {
|
||||
/// `.` for `mod.rs`, `lib.rs`
|
||||
/// `./foo` for `foo.rs`
|
||||
/// `./foo/bar` for `mod bar { mod x; }` nested in `foo.rs`
|
||||
path: RelativePathBuf,
|
||||
/// inside `./foo.rs`, mods with `#[path]` should *not* be relative to `./foo/`
|
||||
root_non_dir_owner: bool,
|
||||
}
|
||||
|
||||
impl<'a> ParentModule<'a> {
|
||||
fn attribute_path(&self) -> Option<&SmolStr> {
|
||||
self.attr_path.filter(|p| !p.is_empty())
|
||||
impl ModDir {
|
||||
pub(super) fn root() -> ModDir {
|
||||
ModDir { path: RelativePathBuf::default(), root_non_dir_owner: false }
|
||||
}
|
||||
|
||||
pub(super) fn descend_into_definition(
|
||||
&self,
|
||||
name: &Name,
|
||||
attr_path: Option<&SmolStr>,
|
||||
) -> ModDir {
|
||||
let mut path = self.path.clone();
|
||||
match attr_path {
|
||||
None => path.push(&name.to_string()),
|
||||
Some(attr_path) => {
|
||||
if self.root_non_dir_owner {
|
||||
path = path
|
||||
.parent()
|
||||
.map(|it| it.to_relative_path_buf())
|
||||
.unwrap_or_else(RelativePathBuf::new);
|
||||
}
|
||||
let attr_path = &*normalize_attribute_path(attr_path);
|
||||
path.push(RelativePath::new(attr_path));
|
||||
}
|
||||
}
|
||||
ModDir { path, root_non_dir_owner: false }
|
||||
}
|
||||
|
||||
pub(super) fn resolve_submodule(
|
||||
&self,
|
||||
db: &impl DefDatabase,
|
||||
file_id: HirFileId,
|
||||
name: &Name,
|
||||
attr_path: Option<&SmolStr>,
|
||||
) -> Result<(FileId, ModDir), RelativePathBuf> {
|
||||
let empty_path = RelativePathBuf::default();
|
||||
let file_id = file_id.original_file(db);
|
||||
let base_dir = {
|
||||
let path = db.file_relative_path(file_id);
|
||||
path.parent().unwrap_or(&empty_path).join(&self.path)
|
||||
};
|
||||
|
||||
let mut candidate_files = Vec::new();
|
||||
match attr_path {
|
||||
Some(attr) => {
|
||||
let base = if self.root_non_dir_owner {
|
||||
base_dir.parent().unwrap_or(&empty_path)
|
||||
} else {
|
||||
&base_dir
|
||||
};
|
||||
candidate_files.push(base.join(&*normalize_attribute_path(attr)))
|
||||
}
|
||||
None => {
|
||||
candidate_files.push(base_dir.join(&format!("{}.rs", name)));
|
||||
candidate_files.push(base_dir.join(&format!("{}/mod.rs", name)));
|
||||
}
|
||||
};
|
||||
|
||||
let source_root_id = db.file_source_root(file_id);
|
||||
let source_root = db.source_root(source_root_id);
|
||||
for candidate in candidate_files.iter() {
|
||||
let candidate = candidate.normalize();
|
||||
if let Some(file_id) = source_root.file_by_relative_path(&candidate) {
|
||||
let mut root_non_dir_owner = false;
|
||||
let mut mod_path = RelativePathBuf::new();
|
||||
if !(candidate.ends_with("mod.rs") || attr_path.is_some()) {
|
||||
root_non_dir_owner = true;
|
||||
mod_path.push(&name.to_string());
|
||||
}
|
||||
return Ok((file_id, ModDir { path: mod_path, root_non_dir_owner }));
|
||||
}
|
||||
}
|
||||
let suggestion = candidate_files.first().unwrap();
|
||||
Err(base_dir.join(suggestion))
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn resolve_submodule(
|
||||
db: &impl DefDatabase,
|
||||
file_id: HirFileId,
|
||||
mod_attr_path: Option<&SmolStr>,
|
||||
name: &Name,
|
||||
is_root: bool,
|
||||
attr_path: Option<&SmolStr>,
|
||||
parent_module: Option<ParentModule<'_>>,
|
||||
) -> Result<FileId, RelativePathBuf> {
|
||||
let file_id = file_id.original_file(db);
|
||||
let source_root_id = db.file_source_root(file_id);
|
||||
let path = db.file_relative_path(file_id);
|
||||
let root = RelativePathBuf::default();
|
||||
let dir_path = path.parent().unwrap_or(&root);
|
||||
let mod_name = path.file_stem().unwrap_or("unknown");
|
||||
|
||||
let resolve_mode = match (attr_path.filter(|p| !p.is_empty()), parent_module) {
|
||||
(Some(file_path), Some(parent_module)) => {
|
||||
let file_path = normalize_attribute_path(file_path);
|
||||
match parent_module.attribute_path() {
|
||||
Some(parent_module_attr_path) => {
|
||||
let path = dir_path
|
||||
.join(format!(
|
||||
"{}/{}",
|
||||
normalize_attribute_path(parent_module_attr_path),
|
||||
file_path
|
||||
))
|
||||
.normalize();
|
||||
ResolutionMode::InlineModuleWithAttributePath(
|
||||
InsideInlineModuleMode::WithAttributePath(path),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
let path =
|
||||
dir_path.join(format!("{}/{}", parent_module.name, file_path)).normalize();
|
||||
ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath(
|
||||
path,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, Some(parent_module)) => match parent_module.attribute_path() {
|
||||
Some(parent_module_attr_path) => {
|
||||
let path = dir_path.join(format!(
|
||||
"{}/{}.rs",
|
||||
normalize_attribute_path(parent_module_attr_path),
|
||||
name
|
||||
));
|
||||
ResolutionMode::InlineModuleWithAttributePath(InsideInlineModuleMode::File(path))
|
||||
}
|
||||
None => {
|
||||
let path = dir_path.join(format!("{}/{}.rs", parent_module.name, name));
|
||||
ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path))
|
||||
}
|
||||
},
|
||||
(Some(file_path), None) => {
|
||||
let file_path = normalize_attribute_path(file_path);
|
||||
let path = dir_path.join(file_path.as_ref()).normalize();
|
||||
ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path))
|
||||
}
|
||||
(None, None) => {
|
||||
let is_dir_owner = is_root || mod_name == "mod" || mod_attr_path.is_some();
|
||||
if is_dir_owner {
|
||||
let file_mod = dir_path.join(format!("{}.rs", name));
|
||||
let dir_mod = dir_path.join(format!("{}/mod.rs", name));
|
||||
ResolutionMode::OutOfLine(OutOfLineMode::RootOrModRs {
|
||||
file: file_mod,
|
||||
directory: dir_mod,
|
||||
})
|
||||
} else {
|
||||
let path = dir_path.join(format!("{}/{}.rs", mod_name, name));
|
||||
ResolutionMode::OutOfLine(OutOfLineMode::FileInDirectory(path))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
resolve_mode.resolve(db.source_root(source_root_id))
|
||||
}
|
||||
|
||||
fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> {
|
||||
fn normalize_attribute_path(file_path: &str) -> Cow<str> {
|
||||
let current_dir = "./";
|
||||
let windows_path_separator = r#"\"#;
|
||||
let current_dir_normalize = if file_path.starts_with(current_dir) {
|
||||
&file_path[current_dir.len()..]
|
||||
} else {
|
||||
file_path.as_str()
|
||||
file_path
|
||||
};
|
||||
if current_dir_normalize.contains(windows_path_separator) {
|
||||
Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/"))
|
||||
|
@ -113,75 +107,3 @@ fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> {
|
|||
Cow::Borrowed(current_dir_normalize)
|
||||
}
|
||||
}
|
||||
|
||||
enum OutOfLineMode {
|
||||
RootOrModRs { file: RelativePathBuf, directory: RelativePathBuf },
|
||||
FileInDirectory(RelativePathBuf),
|
||||
WithAttributePath(RelativePathBuf),
|
||||
}
|
||||
|
||||
impl OutOfLineMode {
|
||||
pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
|
||||
match self {
|
||||
OutOfLineMode::RootOrModRs { file, directory } => {
|
||||
match source_root.file_by_relative_path(file) {
|
||||
None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()),
|
||||
file_id => resolve_find_result(file_id, file),
|
||||
}
|
||||
}
|
||||
OutOfLineMode::FileInDirectory(path) => resolve_simple_path(source_root, path),
|
||||
OutOfLineMode::WithAttributePath(path) => resolve_simple_path(source_root, path),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum InsideInlineModuleMode {
|
||||
File(RelativePathBuf),
|
||||
WithAttributePath(RelativePathBuf),
|
||||
}
|
||||
|
||||
impl InsideInlineModuleMode {
|
||||
pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
|
||||
match self {
|
||||
InsideInlineModuleMode::File(path) => resolve_simple_path(source_root, path),
|
||||
InsideInlineModuleMode::WithAttributePath(path) => {
|
||||
resolve_simple_path(source_root, path)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum ResolutionMode {
|
||||
OutOfLine(OutOfLineMode),
|
||||
InsideInlineModule(InsideInlineModuleMode),
|
||||
InlineModuleWithAttributePath(InsideInlineModuleMode),
|
||||
}
|
||||
|
||||
impl ResolutionMode {
|
||||
pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> {
|
||||
use self::ResolutionMode::*;
|
||||
|
||||
match self {
|
||||
OutOfLine(mode) => mode.resolve(source_root),
|
||||
InsideInlineModule(mode) => mode.resolve(source_root),
|
||||
InlineModuleWithAttributePath(mode) => mode.resolve(source_root),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_simple_path(
|
||||
source_root: Arc<SourceRoot>,
|
||||
path: &RelativePathBuf,
|
||||
) -> Result<FileId, RelativePathBuf> {
|
||||
resolve_find_result(source_root.file_by_relative_path(path), path)
|
||||
}
|
||||
|
||||
fn resolve_find_result(
|
||||
file_id: Option<FileId>,
|
||||
path: &RelativePathBuf,
|
||||
) -> Result<FileId, RelativePathBuf> {
|
||||
match file_id {
|
||||
Some(file_id) => Ok(file_id.clone()),
|
||||
None => Err(path.clone()),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,21 +38,34 @@ fn macro_rules_can_define_modules() {
|
|||
}
|
||||
m!(n1);
|
||||
|
||||
mod m {
|
||||
m!(n3)
|
||||
}
|
||||
|
||||
//- /n1.rs
|
||||
m!(n2)
|
||||
//- /n1/n2.rs
|
||||
struct X;
|
||||
//- /m/n3.rs
|
||||
struct Y;
|
||||
",
|
||||
);
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
⋮n1: t
|
||||
⋮
|
||||
⋮crate::n1
|
||||
⋮n2: t
|
||||
⋮
|
||||
⋮crate::n1::n2
|
||||
⋮X: t v
|
||||
crate
|
||||
m: t
|
||||
n1: t
|
||||
|
||||
crate::m
|
||||
n3: t
|
||||
|
||||
crate::m::n3
|
||||
Y: t v
|
||||
|
||||
crate::n1
|
||||
n2: t
|
||||
|
||||
crate::n1::n2
|
||||
X: t v
|
||||
"###);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,33 @@ fn name_res_works_for_broken_modules() {
|
|||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_module_resolution() {
|
||||
let map = def_map(
|
||||
"
|
||||
//- /lib.rs
|
||||
mod n1;
|
||||
|
||||
//- /n1.rs
|
||||
mod n2;
|
||||
|
||||
//- /n1/n2.rs
|
||||
struct X;
|
||||
",
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
⋮n1: t
|
||||
⋮
|
||||
⋮crate::n1
|
||||
⋮n2: t
|
||||
⋮
|
||||
⋮crate::n1::n2
|
||||
⋮X: t v
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn module_resolution_works_for_non_standard_filenames() {
|
||||
let map = def_map_with_crate_graph(
|
||||
|
@ -53,18 +80,15 @@ fn module_resolution_works_for_non_standard_filenames() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_works_for_raw_modules() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
"
|
||||
//- /library.rs
|
||||
//- /lib.rs
|
||||
mod r#async;
|
||||
use self::r#async::Bar;
|
||||
|
||||
//- /async.rs
|
||||
pub struct Bar;
|
||||
",
|
||||
crate_graph! {
|
||||
"library": ("/library.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -79,9 +103,9 @@ fn module_resolution_works_for_raw_modules() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_path() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /library.rs
|
||||
//- /lib.rs
|
||||
#[path = "bar/baz/foo.rs"]
|
||||
mod foo;
|
||||
use self::foo::Bar;
|
||||
|
@ -89,9 +113,6 @@ fn module_resolution_decl_path() {
|
|||
//- /bar/baz/foo.rs
|
||||
pub struct Bar;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"library": ("/library.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -106,7 +127,7 @@ fn module_resolution_decl_path() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_module_with_path_in_mod_rs() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
@ -120,9 +141,6 @@ fn module_resolution_module_with_path_in_mod_rs() {
|
|||
//- /foo/baz.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -140,7 +158,7 @@ fn module_resolution_module_with_path_in_mod_rs() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_module_with_path_non_crate_root() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
@ -154,9 +172,6 @@ fn module_resolution_module_with_path_non_crate_root() {
|
|||
//- /baz.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -174,7 +189,7 @@ fn module_resolution_module_with_path_non_crate_root() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_module_decl_path_super() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = "bar/baz/module.rs"]
|
||||
|
@ -184,9 +199,6 @@ fn module_resolution_module_decl_path_super() {
|
|||
//- /bar/baz/module.rs
|
||||
use super::Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -201,7 +213,7 @@ fn module_resolution_module_decl_path_super() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_explicit_path_mod_rs() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = "module/mod.rs"]
|
||||
|
@ -210,9 +222,6 @@ fn module_resolution_explicit_path_mod_rs() {
|
|||
//- /module/mod.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -226,7 +235,7 @@ fn module_resolution_explicit_path_mod_rs() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_relative_path() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
@ -238,9 +247,6 @@ fn module_resolution_relative_path() {
|
|||
//- /sub.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -257,7 +263,7 @@ fn module_resolution_relative_path() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_relative_path_2() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
@ -269,9 +275,6 @@ fn module_resolution_relative_path_2() {
|
|||
//- /sub.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -288,7 +291,7 @@ fn module_resolution_relative_path_2() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_explicit_path_mod_rs_2() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = "module/bar/mod.rs"]
|
||||
|
@ -297,9 +300,6 @@ fn module_resolution_explicit_path_mod_rs_2() {
|
|||
//- /module/bar/mod.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -313,7 +313,7 @@ fn module_resolution_explicit_path_mod_rs_2() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_explicit_path_mod_rs_with_win_separator() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = "module\bar\mod.rs"]
|
||||
|
@ -322,9 +322,6 @@ fn module_resolution_explicit_path_mod_rs_with_win_separator() {
|
|||
//- /module/bar/mod.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -338,7 +335,7 @@ fn module_resolution_explicit_path_mod_rs_with_win_separator() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_with_path_attribute() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = "models"]
|
||||
|
@ -349,9 +346,6 @@ fn module_resolution_decl_inside_inline_module_with_path_attribute() {
|
|||
//- /models/bar.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -368,7 +362,7 @@ fn module_resolution_decl_inside_inline_module_with_path_attribute() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo {
|
||||
|
@ -378,9 +372,6 @@ fn module_resolution_decl_inside_inline_module() {
|
|||
//- /foo/bar.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -397,7 +388,7 @@ fn module_resolution_decl_inside_inline_module() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = "models/db"]
|
||||
|
@ -408,9 +399,6 @@ fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
|
|||
//- /models/db/bar.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -427,7 +415,7 @@ fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_3() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = "models/db"]
|
||||
|
@ -439,9 +427,6 @@ fn module_resolution_decl_inside_inline_module_3() {
|
|||
//- /models/db/users.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -458,7 +443,7 @@ fn module_resolution_decl_inside_inline_module_3() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_empty_path() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = ""]
|
||||
|
@ -467,12 +452,9 @@ fn module_resolution_decl_inside_inline_module_empty_path() {
|
|||
mod bar;
|
||||
}
|
||||
|
||||
//- /foo/users.rs
|
||||
//- /users.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -489,32 +471,25 @@ fn module_resolution_decl_inside_inline_module_empty_path() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_empty_path() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = ""]
|
||||
#[path = ""] // Should try to read `/` (a directory)
|
||||
mod foo;
|
||||
|
||||
//- /foo.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
⋮crate
|
||||
⋮foo: t
|
||||
⋮
|
||||
⋮crate::foo
|
||||
⋮Baz: t v
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_relative_path() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path = "./models"]
|
||||
|
@ -525,9 +500,6 @@ fn module_resolution_decl_inside_inline_module_relative_path() {
|
|||
//- /models/bar.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -544,7 +516,7 @@ fn module_resolution_decl_inside_inline_module_relative_path() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_in_crate_root() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo {
|
||||
|
@ -556,9 +528,6 @@ fn module_resolution_decl_inside_inline_module_in_crate_root() {
|
|||
//- /foo/baz.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -576,7 +545,7 @@ fn module_resolution_decl_inside_inline_module_in_crate_root() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_in_mod_rs() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
@ -591,9 +560,6 @@ fn module_resolution_decl_inside_inline_module_in_mod_rs() {
|
|||
//- /foo/bar/qwe.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -614,7 +580,7 @@ fn module_resolution_decl_inside_inline_module_in_mod_rs() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
@ -626,12 +592,9 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
|
|||
}
|
||||
use self::bar::baz::Baz;
|
||||
|
||||
//- /bar/qwe.rs
|
||||
//- /foo/bar/qwe.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -652,7 +615,7 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
@ -667,9 +630,6 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
|
|||
//- /bar/baz.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -709,7 +669,7 @@ fn unresolved_module_diagnostics() {
|
|||
|
||||
#[test]
|
||||
fn module_resolution_decl_inside_module_in_non_crate_root_2() {
|
||||
let map = def_map_with_crate_graph(
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /main.rs
|
||||
#[path="module/m2.rs"]
|
||||
|
@ -721,9 +681,6 @@ fn module_resolution_decl_inside_module_in_non_crate_root_2() {
|
|||
//- /module/submod.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
|
@ -737,3 +694,66 @@ fn module_resolution_decl_inside_module_in_non_crate_root_2() {
|
|||
⋮Baz: t v
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_out_of_line_module() {
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /lib.rs
|
||||
mod a {
|
||||
mod b {
|
||||
mod c;
|
||||
}
|
||||
}
|
||||
|
||||
//- /a/b/c.rs
|
||||
struct X;
|
||||
"###,
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
crate
|
||||
a: t
|
||||
|
||||
crate::a
|
||||
b: t
|
||||
|
||||
crate::a::b
|
||||
c: t
|
||||
|
||||
crate::a::b::c
|
||||
X: t v
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_out_of_line_module_with_path() {
|
||||
let map = def_map(
|
||||
r###"
|
||||
//- /lib.rs
|
||||
mod a {
|
||||
#[path = "d/e"]
|
||||
mod b {
|
||||
mod c;
|
||||
}
|
||||
}
|
||||
|
||||
//- /a/d/e/c.rs
|
||||
struct X;
|
||||
"###,
|
||||
);
|
||||
|
||||
assert_snapshot!(map, @r###"
|
||||
crate
|
||||
a: t
|
||||
|
||||
crate::a
|
||||
b: t
|
||||
|
||||
crate::a::b
|
||||
c: t
|
||||
|
||||
crate::a::b::c
|
||||
X: t v
|
||||
"###);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue