Skip to content

Commit 9e8feeb

Browse files
Fix TestDB::module_at_position with submodules
1 parent 52585df commit 9e8feeb

File tree

2 files changed

+72
-2
lines changed

2 files changed

+72
-2
lines changed

crates/hir_def/src/find_path.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,29 @@ fn main() {
954954
)
955955
}
956956

957+
#[test]
958+
fn from_inside_module() {
959+
// This worked correctly, but the test suite logic was broken.
960+
cov_mark::check!(submodule_in_testdb);
961+
check_found_path(
962+
r#"
963+
mod baz {
964+
pub struct Foo {}
965+
}
966+
967+
mod bar {
968+
fn bar() {
969+
$0
970+
}
971+
}
972+
"#,
973+
"crate::baz::Foo",
974+
"crate::baz::Foo",
975+
"crate::baz::Foo",
976+
"crate::baz::Foo",
977+
)
978+
}
979+
957980
#[test]
958981
fn recursive_pub_mod_reexport() {
959982
cov_mark::check!(recursive_imports);

crates/hir_def/src/test_db.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ use rustc_hash::FxHashSet;
1515
use syntax::{algo, ast, AstNode, TextRange, TextSize};
1616
use test_utils::extract_annotations;
1717

18-
use crate::{db::DefDatabase, nameres::DefMap, src::HasSource, Lookup, ModuleDefId, ModuleId};
18+
use crate::{
19+
db::DefDatabase,
20+
nameres::{DefMap, ModuleSource},
21+
src::HasSource,
22+
LocalModuleId, Lookup, ModuleDefId, ModuleId,
23+
};
1924

2025
#[salsa::database(
2126
base_db::SourceDatabaseExtStorage,
@@ -87,10 +92,11 @@ impl TestDB {
8792
pub(crate) fn module_at_position(&self, position: FilePosition) -> ModuleId {
8893
let file_module = self.module_for_file(position.file_id);
8994
let mut def_map = file_module.def_map(self);
95+
let module = self.mod_at_position(&def_map, position);
9096

9197
def_map = match self.block_at_position(&def_map, position) {
9298
Some(it) => it,
93-
None => return file_module,
99+
None => return def_map.module_id(module),
94100
};
95101
loop {
96102
let new_map = self.block_at_position(&def_map, position);
@@ -106,6 +112,47 @@ impl TestDB {
106112
}
107113
}
108114

115+
/// Finds the smallest/innermost module in `def_map` containing `position`.
116+
fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId {
117+
let mut size = None;
118+
let mut res = def_map.root();
119+
for (module, data) in def_map.modules() {
120+
let src = data.definition_source(self);
121+
if src.file_id != position.file_id.into() {
122+
continue;
123+
}
124+
125+
let range = match src.value {
126+
ModuleSource::SourceFile(it) => it.syntax().text_range(),
127+
ModuleSource::Module(it) => it.syntax().text_range(),
128+
ModuleSource::BlockExpr(it) => it.syntax().text_range(),
129+
};
130+
131+
if !range.contains(position.offset) {
132+
continue;
133+
}
134+
135+
let new_size = match size {
136+
None => range.len(),
137+
Some(size) => {
138+
if range.len() < size {
139+
range.len()
140+
} else {
141+
size
142+
}
143+
}
144+
};
145+
146+
if size != Some(new_size) {
147+
cov_mark::hit!(submodule_in_testdb);
148+
size = Some(new_size);
149+
res = module;
150+
}
151+
}
152+
153+
res
154+
}
155+
109156
fn block_at_position(&self, def_map: &DefMap, position: FilePosition) -> Option<Arc<DefMap>> {
110157
// Find the smallest (innermost) function in `def_map` containing the cursor.
111158
let mut size = None;

0 commit comments

Comments
 (0)