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
bors 2022-06-16
parent 7ade4d4 · parent 6df969f · commit 7322a98
-rw-r--r--crates/hir/src/source_analyzer.rs20
-rw-r--r--crates/ide-completion/src/tests/type_pos.rs31
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#"