Skip to content

Commit 6c31f5b

Browse files
bors[bot]ava57r
andcommitted
Merge #1499
1499: processing attribute #[path] of module r=matklad a=andreevlex support two cases - simple name file `foo.rs` - declaration in mod.rs #1211 Co-authored-by: Alexander Andreev <andreevlex.as@gmail.com>
2 parents 89bfc59 + 1c582be commit 6c31f5b

File tree

7 files changed

+241
-109
lines changed

7 files changed

+241
-109
lines changed

crates/ra_hir/src/nameres.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// This module implements import-resolution/macro expansion algorithm.
22
///
3-
/// The result of this module is `CrateDefMap`: a datastructure which contains:
3+
/// The result of this module is `CrateDefMap`: a data structure which contains:
44
///
55
/// * a tree of modules for the crate
66
/// * for each module, a set of items visible in the module (directly declared
@@ -76,7 +76,7 @@ pub use self::{
7676
raw::ImportId,
7777
};
7878

79-
/// Contans all top-level defs from a macro-expanded crate
79+
/// Contains all top-level defs from a macro-expanded crate
8080
#[derive(Debug, PartialEq, Eq)]
8181
pub struct CrateDefMap {
8282
krate: Crate,

crates/ra_hir/src/nameres/collector.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use arrayvec::ArrayVec;
22
use ra_db::FileId;
3-
use ra_syntax::ast;
3+
use ra_syntax::{ast, SmolStr};
44
use relative_path::RelativePathBuf;
55
use rustc_hash::FxHashMap;
66
use test_utils::tested_by;
@@ -508,11 +508,17 @@ where
508508
}
509509
.collect(&*items);
510510
}
511-
// out of line module, resovle, parse and recurse
512-
raw::ModuleData::Declaration { name, ast_id } => {
511+
// out of line module, resolve, parse and recurse
512+
raw::ModuleData::Declaration { name, ast_id, attr_path } => {
513513
let ast_id = ast_id.with_file_id(self.file_id);
514514
let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none();
515-
match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) {
515+
match resolve_submodule(
516+
self.def_collector.db,
517+
self.file_id,
518+
name,
519+
is_root,
520+
attr_path.as_ref(),
521+
) {
516522
Ok(file_id) => {
517523
let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
518524
let raw_items = self.def_collector.db.raw_items(file_id.into());
@@ -626,6 +632,7 @@ fn resolve_submodule(
626632
file_id: HirFileId,
627633
name: &Name,
628634
is_root: bool,
635+
attr_path: Option<&SmolStr>,
629636
) -> Result<FileId, RelativePathBuf> {
630637
// FIXME: handle submodules of inline modules properly
631638
let file_id = file_id.original_file(db);
@@ -639,7 +646,13 @@ fn resolve_submodule(
639646
let file_mod = dir_path.join(format!("{}.rs", name));
640647
let dir_mod = dir_path.join(format!("{}/mod.rs", name));
641648
let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
642-
let mut candidates = ArrayVec::<[_; 2]>::new();
649+
let mut candidates = ArrayVec::<[_; 3]>::new();
650+
let file_attr_mod = attr_path.map(|file_path| {
651+
let file_attr_mod = dir_path.join(file_path.to_string());
652+
candidates.push(file_attr_mod.clone());
653+
654+
file_attr_mod
655+
});
643656
if is_dir_owner {
644657
candidates.push(file_mod.clone());
645658
candidates.push(dir_mod);
@@ -651,7 +664,13 @@ fn resolve_submodule(
651664
// FIXME: handle ambiguity
652665
match points_to.next() {
653666
Some(file_id) => Ok(file_id),
654-
None => Err(if is_dir_owner { file_mod } else { file_dir_mod }),
667+
None => {
668+
if let Some(file_attr_mod) = file_attr_mod {
669+
Err(file_attr_mod)
670+
} else {
671+
Err(if is_dir_owner { file_mod } else { file_dir_mod })
672+
}
673+
}
655674
}
656675
}
657676

crates/ra_hir/src/nameres/raw.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{ops::Index, sync::Arc};
33
use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
44
use ra_syntax::{
55
ast::{self, AttrsOwner, NameOwner},
6-
AstNode, AstPtr, SourceFile, TreeArc,
6+
AstNode, AstPtr, SmolStr, SourceFile, TreeArc,
77
};
88
use test_utils::tested_by;
99

@@ -130,7 +130,7 @@ impl_arena_id!(Module);
130130

131131
#[derive(Debug, PartialEq, Eq)]
132132
pub(super) enum ModuleData {
133-
Declaration { name: Name, ast_id: FileAstId<ast::Module> },
133+
Declaration { name: Name, ast_id: FileAstId<ast::Module>, attr_path: Option<SmolStr> },
134134
Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> },
135135
}
136136

@@ -255,9 +255,12 @@ impl RawItemsCollector {
255255
Some(it) => it.as_name(),
256256
None => return,
257257
};
258+
259+
let attr_path = extract_mod_path_attribute(module);
258260
let ast_id = self.source_ast_id_map.ast_id(module);
259261
if module.has_semi() {
260-
let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id });
262+
let item =
263+
self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id, attr_path });
261264
self.push_item(current_module, RawItem::Module(item));
262265
return;
263266
}
@@ -339,3 +342,16 @@ impl RawItemsCollector {
339342
.push(item)
340343
}
341344
}
345+
346+
fn extract_mod_path_attribute(module: &ast::Module) -> Option<SmolStr> {
347+
module.attrs().into_iter().find_map(|attr| {
348+
attr.as_key_value().and_then(|(name, value)| {
349+
let is_path = name == "path";
350+
if is_path {
351+
Some(value)
352+
} else {
353+
None
354+
}
355+
})
356+
})
357+
}

crates/ra_hir/src/nameres/tests.rs

Lines changed: 1 addition & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ mod macros;
22
mod globs;
33
mod incremental;
44
mod primitives;
5+
mod mods;
56

67
use std::sync::Arc;
78

@@ -312,83 +313,6 @@ fn edition_2015_imports() {
312313
"###);
313314
}
314315

315-
#[test]
316-
fn module_resolution_works_for_non_standard_filenames() {
317-
let map = def_map_with_crate_graph(
318-
"
319-
//- /my_library.rs
320-
mod foo;
321-
use self::foo::Bar;
322-
323-
//- /foo/mod.rs
324-
pub struct Bar;
325-
",
326-
crate_graph! {
327-
"my_library": ("/my_library.rs", []),
328-
},
329-
);
330-
331-
assert_snapshot_matches!(map, @r###"
332-
⋮crate
333-
⋮Bar: t v
334-
⋮foo: t
335-
336-
⋮crate::foo
337-
⋮Bar: t v
338-
"###);
339-
}
340-
341-
#[test]
342-
fn module_resolution_works_for_raw_modules() {
343-
let map = def_map_with_crate_graph(
344-
"
345-
//- /library.rs
346-
mod r#async;
347-
use self::r#async::Bar;
348-
349-
//- /async.rs
350-
pub struct Bar;
351-
",
352-
crate_graph! {
353-
"library": ("/library.rs", []),
354-
},
355-
);
356-
357-
assert_snapshot_matches!(map, @r###"
358-
⋮crate
359-
⋮Bar: t v
360-
⋮async: t
361-
362-
⋮crate::async
363-
⋮Bar: t v
364-
"###);
365-
}
366-
367-
#[test]
368-
fn name_res_works_for_broken_modules() {
369-
covers!(name_res_works_for_broken_modules);
370-
let map = def_map(
371-
"
372-
//- /lib.rs
373-
mod foo // no `;`, no body
374-
375-
use self::foo::Baz;
376-
377-
//- /foo/mod.rs
378-
pub mod bar;
379-
380-
pub use self::bar::Baz;
381-
382-
//- /foo/bar.rs
383-
pub struct Baz;
384-
",
385-
);
386-
assert_snapshot_matches!(map, @r###"
387-
⋮crate
388-
⋮Baz: _
389-
"###);
390-
}
391-
392316
#[test]
393317
fn item_map_using_self() {
394318
let map = def_map(
@@ -581,22 +505,3 @@ fn values_dont_shadow_extern_crates() {
581505
⋮foo: v
582506
"###);
583507
}
584-
585-
#[test]
586-
fn unresolved_module_diagnostics() {
587-
let diagnostics = MockDatabase::with_files(
588-
r"
589-
//- /lib.rs
590-
mod foo;
591-
mod bar;
592-
mod baz {}
593-
//- /foo.rs
594-
",
595-
)
596-
.diagnostics();
597-
598-
assert_snapshot_matches!(diagnostics, @r###"
599-
"mod bar;": unresolved module
600-
"###
601-
);
602-
}

0 commit comments

Comments
 (0)