Skip to content

Commit fc0354b

Browse files
bors[bot]Veykril
andauthored
Merge #6635
6635: Complete struct in irrefutable let r=Veykril a=Veykril Fixes #6210 Co-authored-by: Lukas Wirth <[email protected]>
2 parents 38d595c + ee06c07 commit fc0354b

File tree

2 files changed

+46
-14
lines changed

2 files changed

+46
-14
lines changed

crates/completion/src/completions/pattern.rs

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{CompletionContext, Completions};
44

55
/// Completes constats and paths in patterns.
66
pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
7-
if !ctx.is_pat_binding_or_const {
7+
if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_let_pat_binding) {
88
return;
99
}
1010
if ctx.record_pat_syntax.is_some() {
@@ -14,20 +14,27 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
1414
// FIXME: ideally, we should look at the type we are matching against and
1515
// suggest variants + auto-imports
1616
ctx.scope.process_all_names(&mut |name, res| {
17-
match &res {
18-
hir::ScopeDef::ModuleDef(def) => match def {
19-
hir::ModuleDef::Adt(hir::Adt::Enum(..))
20-
| hir::ModuleDef::Adt(hir::Adt::Struct(..))
21-
| hir::ModuleDef::EnumVariant(..)
22-
| hir::ModuleDef::Const(..)
23-
| hir::ModuleDef::Module(..) => (),
24-
_ => return,
25-
},
26-
hir::ScopeDef::MacroDef(_) => (),
27-
_ => return,
17+
let add_resolution = match &res {
18+
hir::ScopeDef::ModuleDef(def) => {
19+
if ctx.is_irrefutable_let_pat_binding {
20+
matches!(def, hir::ModuleDef::Adt(hir::Adt::Struct(_)))
21+
} else {
22+
matches!(
23+
def,
24+
hir::ModuleDef::Adt(hir::Adt::Enum(..))
25+
| hir::ModuleDef::Adt(hir::Adt::Struct(..))
26+
| hir::ModuleDef::EnumVariant(..)
27+
| hir::ModuleDef::Const(..)
28+
| hir::ModuleDef::Module(..)
29+
)
30+
}
31+
}
32+
hir::ScopeDef::MacroDef(_) => true,
33+
_ => false,
2834
};
29-
30-
acc.add_resolution(ctx, name.to_string(), &res)
35+
if add_resolution {
36+
acc.add_resolution(ctx, name.to_string(), &res);
37+
}
3138
});
3239
}
3340

@@ -85,4 +92,26 @@ fn foo() {
8592
"#]],
8693
);
8794
}
95+
96+
#[test]
97+
fn completes_in_irrefutable_let() {
98+
check(
99+
r#"
100+
enum E { X }
101+
use self::E::X;
102+
const Z: E = E::X;
103+
mod m {}
104+
105+
static FOO: E = E::X;
106+
struct Bar { f: u32 }
107+
108+
fn foo() {
109+
let <|>
110+
}
111+
"#,
112+
expect![[r#"
113+
st Bar
114+
"#]],
115+
);
116+
}
88117
}

crates/completion/src/context.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub(crate) struct CompletionContext<'a> {
5151
/// If a name-binding or reference to a const in a pattern.
5252
/// Irrefutable patterns (like let) are excluded.
5353
pub(super) is_pat_binding_or_const: bool,
54+
pub(super) is_irrefutable_let_pat_binding: bool,
5455
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
5556
pub(super) is_trivial_path: bool,
5657
/// If not a trivial path, the prefix (qualifier).
@@ -146,6 +147,7 @@ impl<'a> CompletionContext<'a> {
146147
active_parameter: ActiveParameter::at(db, position),
147148
is_param: false,
148149
is_pat_binding_or_const: false,
150+
is_irrefutable_let_pat_binding: false,
149151
is_trivial_path: false,
150152
path_qual: None,
151153
after_if: false,
@@ -330,6 +332,7 @@ impl<'a> CompletionContext<'a> {
330332
if pat.syntax().text_range().contains_range(bind_pat.syntax().text_range())
331333
{
332334
self.is_pat_binding_or_const = false;
335+
self.is_irrefutable_let_pat_binding = true;
333336
}
334337
}
335338
}

0 commit comments

Comments
 (0)