diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-17 01:35:22 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-17 01:35:22 +0000 |
| commit | df5b6f7d459a367b191d5d540c7363d9e526eadf (patch) | |
| tree | ffb5f57b1d989cbd94be19eae42ca091b060a4e3 | |
| parent | 52585df24aed2c02c17b89913f5a5365b2e76e75 (diff) | |
| parent | 9e8feeb94aaa9e215c07bf817b6481a0447aed18 (diff) | |
| download | rust-df5b6f7d459a367b191d5d540c7363d9e526eadf.tar.gz rust-df5b6f7d459a367b191d5d540c7363d9e526eadf.zip | |
Merge #8549
8549: Fix `TestDB::module_at_position` with submodules r=jonas-schievink a=jonas-schievink Found while looking into https://github.com/rust-analyzer/rust-analyzer/issues/8519 bors r+ Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
| -rw-r--r-- | crates/hir_def/src/find_path.rs | 23 | ||||
| -rw-r--r-- | crates/hir_def/src/test_db.rs | 51 |
2 files changed, 72 insertions, 2 deletions
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index 41da3bc2d42..2c4bbe585ea 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs @@ -955,6 +955,29 @@ fn main() { } #[test] + fn from_inside_module() { + // This worked correctly, but the test suite logic was broken. + cov_mark::check!(submodule_in_testdb); + check_found_path( + r#" +mod baz { + pub struct Foo {} +} + +mod bar { + fn bar() { + $0 + } +} + "#, + "crate::baz::Foo", + "crate::baz::Foo", + "crate::baz::Foo", + "crate::baz::Foo", + ) + } + + #[test] fn recursive_pub_mod_reexport() { cov_mark::check!(recursive_imports); check_found_path( diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs index dd36106f8d2..8fa703a574e 100644 --- a/crates/hir_def/src/test_db.rs +++ b/crates/hir_def/src/test_db.rs @@ -15,7 +15,12 @@ use rustc_hash::FxHashSet; use syntax::{algo, ast, AstNode, TextRange, TextSize}; use test_utils::extract_annotations; -use crate::{db::DefDatabase, nameres::DefMap, src::HasSource, Lookup, ModuleDefId, ModuleId}; +use crate::{ + db::DefDatabase, + nameres::{DefMap, ModuleSource}, + src::HasSource, + LocalModuleId, Lookup, ModuleDefId, ModuleId, +}; #[salsa::database( base_db::SourceDatabaseExtStorage, @@ -87,10 +92,11 @@ impl TestDB { pub(crate) fn module_at_position(&self, position: FilePosition) -> ModuleId { let file_module = self.module_for_file(position.file_id); let mut def_map = file_module.def_map(self); + let module = self.mod_at_position(&def_map, position); def_map = match self.block_at_position(&def_map, position) { Some(it) => it, - None => return file_module, + None => return def_map.module_id(module), }; loop { let new_map = self.block_at_position(&def_map, position); @@ -106,6 +112,47 @@ impl TestDB { } } + /// Finds the smallest/innermost module in `def_map` containing `position`. + fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId { + let mut size = None; + let mut res = def_map.root(); + for (module, data) in def_map.modules() { + let src = data.definition_source(self); + if src.file_id != position.file_id.into() { + continue; + } + + let range = match src.value { + ModuleSource::SourceFile(it) => it.syntax().text_range(), + ModuleSource::Module(it) => it.syntax().text_range(), + ModuleSource::BlockExpr(it) => it.syntax().text_range(), + }; + + if !range.contains(position.offset) { + continue; + } + + let new_size = match size { + None => range.len(), + Some(size) => { + if range.len() < size { + range.len() + } else { + size + } + } + }; + + if size != Some(new_size) { + cov_mark::hit!(submodule_in_testdb); + size = Some(new_size); + res = module; + } + } + + res + } + fn block_at_position(&self, def_map: &DefMap, position: FilePosition) -> Option<Arc<DefMap>> { // Find the smallest (innermost) function in `def_map` containing the cursor. let mut size = None; |
