@@ -8,6 +8,7 @@ use ide_db::{
8
8
base_db::{SourceDatabaseExt, VfsPath},
9
9
RootDatabase, SymbolKind,
10
10
};
11
+ use syntax::{ast, AstNode, SyntaxKind};
11
12
12
13
use crate::{context::NameContext, CompletionItem};
13
14
@@ -24,7 +25,21 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op
24
25
25
26
let _p = profile::span("completion::complete_mod");
26
27
27
- let current_module = ctx.module;
28
+ let mut current_module = ctx.module;
29
+ // For `mod $0`, `ctx.module` is its parent, but for `mod f$0`, it's `mod f` itself, but we're
30
+ // interested in its parent.
31
+ if ctx.original_token.kind() == SyntaxKind::IDENT {
32
+ if let Some(module) = ctx.original_token.ancestors().nth(1).and_then(ast::Module::cast) {
33
+ match current_module.definition_source(ctx.db).value {
34
+ ModuleSource::Module(src) if src == module => {
35
+ if let Some(parent) = current_module.parent(ctx.db) {
36
+ current_module = parent;
37
+ }
38
+ }
39
+ _ => {}
40
+ }
41
+ }
42
+ }
28
43
29
44
let module_definition_file =
30
45
current_module.definition_source(ctx.db).file_id.original_file(ctx.db);
@@ -314,4 +329,26 @@ fn bar_ignored() {}
314
329
expect![[r#""#]],
315
330
);
316
331
}
332
+
333
+ #[test]
334
+ fn name_partially_typed() {
335
+ check(
336
+ r#"
337
+ //- /lib.rs
338
+ mod f$0
339
+ //- /foo.rs
340
+ fn foo() {}
341
+ //- /foo/ignored_foo.rs
342
+ fn ignored_foo() {}
343
+ //- /bar/mod.rs
344
+ fn bar() {}
345
+ //- /bar/ignored_bar.rs
346
+ fn ignored_bar() {}
347
+ "#,
348
+ expect![[r#"
349
+ md foo;
350
+ md bar;
351
+ "#]],
352
+ );
353
+ }
317
354
}
0 commit comments