Skip to content

Commit 947eec7

Browse files
committed
Use super, don't use private imports
1 parent df9d3bd commit 947eec7

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed

crates/ra_hir_def/src/find_path.rs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ use crate::{
88
};
99
use hir_expand::name::Name;
1010

11-
// TODO don't import from super imports? or at least deprioritize
12-
// TODO use super?
1311
// TODO performance / memoize
1412

1513
pub fn find_path(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Option<ModPath> {
@@ -27,6 +25,13 @@ pub fn find_path(db: &impl DefDatabase, item: ItemInNs, from: ModuleId) -> Optio
2725
return Some(ModPath::from_simple_segments(PathKind::Crate, Vec::new()));
2826
}
2927

28+
// - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly)
29+
if let Some(parent_id) = def_map.modules[from.local_id].parent {
30+
if item == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId { krate: from.krate, local_id: parent_id })) {
31+
return Some(ModPath::from_simple_segments(PathKind::Super(1), Vec::new()));
32+
}
33+
}
34+
3035
// - if the item is the crate root of a dependency crate, return the name from the extern prelude
3136
for (name, def_id) in &def_map.extern_prelude {
3237
if item == ItemInNs::Types(*def_id) {
@@ -80,6 +85,19 @@ fn find_importable_locations(db: &impl DefDatabase, item: ItemInNs, from: Module
8085
let def_map = db.crate_def_map(krate);
8186
for (local_id, data) in def_map.modules.iter() {
8287
if let Some((name, vis)) = data.scope.reverse_get(item) {
88+
let is_private = if let crate::visibility::Visibility::Module(private_to) = vis {
89+
private_to.local_id == local_id
90+
} else { false };
91+
let is_original_def = if let Some(module_def_id) = item.as_module_def_id() {
92+
data.scope.declarations().any(|it| it == module_def_id)
93+
} else { false };
94+
if is_private && !is_original_def {
95+
// Ignore private imports. these could be used if we are
96+
// in a submodule of this module, but that's usually not
97+
// what the user wants; and if this module can import
98+
// the item and we're a submodule of it, so can we.
99+
continue;
100+
}
83101
if vis.is_visible_from(db, from) {
84102
result.push((ModuleId { krate, local_id }, name.clone()));
85103
}
@@ -160,6 +178,20 @@ mod tests {
160178
check_found_path(code, "foo::S");
161179
}
162180

181+
#[test]
182+
fn super_module() {
183+
let code = r#"
184+
//- /main.rs
185+
mod foo;
186+
//- /foo.rs
187+
mod bar;
188+
struct S;
189+
//- /foo/bar.rs
190+
<|>
191+
"#;
192+
check_found_path(code, "super::S");
193+
}
194+
163195
#[test]
164196
fn crate_root() {
165197
let code = r#"
@@ -290,4 +322,18 @@ mod tests {
290322
"#;
291323
check_found_path(code, "baz::S");
292324
}
325+
326+
#[test]
327+
fn discount_private_imports() {
328+
let code = r#"
329+
//- /main.rs
330+
mod foo;
331+
pub mod bar { pub struct S; }
332+
use bar::S;
333+
//- /foo.rs
334+
<|>
335+
"#;
336+
// crate::S would be shorter, but using private imports seems wrong
337+
check_found_path(code, "crate::bar::S");
338+
}
293339
}

0 commit comments

Comments
 (0)