6635: Complete struct in irrefutable let r=Veykril a=Veykril

Fixes #6210

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2020-11-26 20:30:16 +00:00 committed by GitHub
commit fc0354b280
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 14 deletions

View file

@ -4,7 +4,7 @@ use crate::{CompletionContext, Completions};
/// Completes constats and paths in patterns. /// Completes constats and paths in patterns.
pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
if !ctx.is_pat_binding_or_const { if !(ctx.is_pat_binding_or_const || ctx.is_irrefutable_let_pat_binding) {
return; return;
} }
if ctx.record_pat_syntax.is_some() { if ctx.record_pat_syntax.is_some() {
@ -14,20 +14,27 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
// FIXME: ideally, we should look at the type we are matching against and // FIXME: ideally, we should look at the type we are matching against and
// suggest variants + auto-imports // suggest variants + auto-imports
ctx.scope.process_all_names(&mut |name, res| { ctx.scope.process_all_names(&mut |name, res| {
match &res { let add_resolution = match &res {
hir::ScopeDef::ModuleDef(def) => match def { hir::ScopeDef::ModuleDef(def) => {
hir::ModuleDef::Adt(hir::Adt::Enum(..)) if ctx.is_irrefutable_let_pat_binding {
| hir::ModuleDef::Adt(hir::Adt::Struct(..)) matches!(def, hir::ModuleDef::Adt(hir::Adt::Struct(_)))
| hir::ModuleDef::EnumVariant(..) } else {
| hir::ModuleDef::Const(..) matches!(
| hir::ModuleDef::Module(..) => (), def,
_ => return, hir::ModuleDef::Adt(hir::Adt::Enum(..))
}, | hir::ModuleDef::Adt(hir::Adt::Struct(..))
hir::ScopeDef::MacroDef(_) => (), | hir::ModuleDef::EnumVariant(..)
_ => return, | hir::ModuleDef::Const(..)
| hir::ModuleDef::Module(..)
)
}
}
hir::ScopeDef::MacroDef(_) => true,
_ => false,
}; };
if add_resolution {
acc.add_resolution(ctx, name.to_string(), &res) acc.add_resolution(ctx, name.to_string(), &res);
}
}); });
} }
@ -85,4 +92,26 @@ fn foo() {
"#]], "#]],
); );
} }
#[test]
fn completes_in_irrefutable_let() {
check(
r#"
enum E { X }
use self::E::X;
const Z: E = E::X;
mod m {}
static FOO: E = E::X;
struct Bar { f: u32 }
fn foo() {
let <|>
}
"#,
expect![[r#"
st Bar
"#]],
);
}
} }

View file

@ -51,6 +51,7 @@ pub(crate) struct CompletionContext<'a> {
/// If a name-binding or reference to a const in a pattern. /// If a name-binding or reference to a const in a pattern.
/// Irrefutable patterns (like let) are excluded. /// Irrefutable patterns (like let) are excluded.
pub(super) is_pat_binding_or_const: bool, pub(super) is_pat_binding_or_const: bool,
pub(super) is_irrefutable_let_pat_binding: bool,
/// A single-indent path, like `foo`. `::foo` should not be considered a trivial path. /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
pub(super) is_trivial_path: bool, pub(super) is_trivial_path: bool,
/// If not a trivial path, the prefix (qualifier). /// If not a trivial path, the prefix (qualifier).
@ -146,6 +147,7 @@ impl<'a> CompletionContext<'a> {
active_parameter: ActiveParameter::at(db, position), active_parameter: ActiveParameter::at(db, position),
is_param: false, is_param: false,
is_pat_binding_or_const: false, is_pat_binding_or_const: false,
is_irrefutable_let_pat_binding: false,
is_trivial_path: false, is_trivial_path: false,
path_qual: None, path_qual: None,
after_if: false, after_if: false,
@ -330,6 +332,7 @@ impl<'a> CompletionContext<'a> {
if pat.syntax().text_range().contains_range(bind_pat.syntax().text_range()) if pat.syntax().text_range().contains_range(bind_pat.syntax().text_range())
{ {
self.is_pat_binding_or_const = false; self.is_pat_binding_or_const = false;
self.is_irrefutable_let_pat_binding = true;
} }
} }
} }