Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #12554 - XFFXFF:fix_11959, r=Veykril
fix: local items should not be completed in parent signature
fixes #11959
> We get a Bar completion for the following snippet which is wrong as the item is not visible in that position.
> ``` rust
> fn foo() -> $0 {
> struct Bar;
> }
> ```
I investigated the problem and found that the scope of the cursor offset, also `CompletionContext.scope` is the body of the function
| -rw-r--r-- | crates/hir/src/source_analyzer.rs | 20 | ||||
| -rw-r--r-- | crates/ide-completion/src/tests/type_pos.rs | 31 |
2 files changed, 43 insertions, 8 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs index b5e6d99093..d624d37577 100644 --- a/crates/hir/src/source_analyzer.rs +++ b/crates/hir/src/source_analyzer.rs @@ -67,7 +67,10 @@ impl SourceAnalyzer { let scopes = db.expr_scopes(def); let scope = match offset { None => scope_for(&scopes, &source_map, node), - Some(offset) => scope_for_offset(db, &scopes, &source_map, node.with_value(offset)), + Some(offset) => { + let file_id = node.file_id.original_file(db.upcast()); + scope_for_offset(db, &scopes, &source_map, InFile::new(file_id.into(), offset)) + } }; let resolver = resolver_for_scope(db.upcast(), def, scope); SourceAnalyzer { @@ -88,7 +91,10 @@ impl SourceAnalyzer { let scopes = db.expr_scopes(def); let scope = match offset { None => scope_for(&scopes, &source_map, node), - Some(offset) => scope_for_offset(db, &scopes, &source_map, node.with_value(offset)), + Some(offset) => { + let file_id = node.file_id.original_file(db.upcast()); + scope_for_offset(db, &scopes, &source_map, InFile::new(file_id.into(), offset)) + } }; let resolver = resolver_for_scope(db.upcast(), def, scope); SourceAnalyzer { resolver, def: Some((def, body, source_map)), infer: None, file_id } @@ -600,13 +606,11 @@ fn scope_for_offset( .filter(|it| it.value.kind() == SyntaxKind::MACRO_CALL)?; Some((source.value.text_range(), scope)) }) - // find containing scope - .min_by_key(|(expr_range, _scope)| { - ( - !(expr_range.start() <= offset.value && offset.value <= expr_range.end()), - expr_range.len(), - ) + .filter(|(expr_range, _scope)| { + expr_range.start() <= offset.value && offset.value <= expr_range.end() }) + // find containing scope + .min_by_key(|(expr_range, _scope)| expr_range.len()) .map(|(expr_range, scope)| { adjust(db, scopes, source_map, expr_range, offset).unwrap_or(*scope) }) diff --git a/crates/ide-completion/src/tests/type_pos.rs b/crates/ide-completion/src/tests/type_pos.rs index 1e5e86eef5..8943d303b6 100644 --- a/crates/ide-completion/src/tests/type_pos.rs +++ b/crates/ide-completion/src/tests/type_pos.rs @@ -90,6 +90,37 @@ fn x<'lt, T, const C: usize>() -> $0 } #[test] +fn fn_return_type_no_local_items() { + check( + r#" +fn foo() -> B$0 { + struct Bar; + enum Baz {} + union Bax { + i: i32, + f: f32 + } +} +"#, + expect![[r#" + en Enum + ma makro!(…) macro_rules! makro + md module + st Record + st Tuple + st Unit + tt Trait + un Union + bt u32 + it () + kw crate:: + kw self:: + kw super:: + "#]], + ) +} + +#[test] fn inferred_type_const() { check( r#" |