From 5660408f0a5b62bcc31258678e65078378109c94 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 30 May 2021 21:23:42 +0200 Subject: Move more fields to `ImmediateLocation` --- crates/ide_completion/src/completions/fn_param.rs | 15 +++++++++++++++ crates/ide_completion/src/completions/keyword.rs | 18 +++++++++++------- crates/ide_completion/src/completions/mod_.rs | 6 +++--- crates/ide_completion/src/completions/record.rs | 20 ++++++++++++-------- 4 files changed, 41 insertions(+), 18 deletions(-) (limited to 'crates/ide_completion/src/completions') diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs index 0ea558489..cb90e8a3e 100644 --- a/crates/ide_completion/src/completions/fn_param.rs +++ b/crates/ide_completion/src/completions/fn_param.rs @@ -128,4 +128,19 @@ fn outer(text: String) { "#]], ) } + + #[test] + fn completes_non_ident_pat_param() { + check( + r#" +struct Bar { bar: u32 } + +fn foo(Bar { bar }: Bar) {} +fn foo2($0) {} +"#, + expect![[r#" + bn Bar { bar }: Bar + "#]], + ) + } } diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs index e71a04b6e..0d035c611 100644 --- a/crates/ide_completion/src/completions/keyword.rs +++ b/crates/ide_completion/src/completions/keyword.rs @@ -4,7 +4,10 @@ use std::iter; use syntax::{SyntaxKind, T}; -use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions}; +use crate::{ + patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind, + CompletionKind, Completions, +}; pub(crate) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) { // complete keyword "crate" in use stmt @@ -44,7 +47,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte cov_mark::hit!(no_keyword_completion_in_comments); return; } - if ctx.record_lit_syntax.is_some() { + if matches!(ctx.completion_location, Some(ImmediateLocation::RecordExpr(_))) { cov_mark::hit!(no_keyword_completion_in_record_lit); return; } @@ -55,7 +58,6 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte let expects_item = ctx.expects_item(); if ctx.has_impl_or_trait_prev_sibling() { - // FIXME this also incorrectly shows up after a complete trait/impl add_keyword("where", "where "); return; } @@ -77,11 +79,8 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte add_keyword("pub", "pub "); } - if expects_item || expects_assoc_item || has_block_expr_parent || ctx.is_match_arm { - add_keyword("unsafe", "unsafe "); - } - if expects_item || expects_assoc_item || has_block_expr_parent { + add_keyword("unsafe", "unsafe "); add_keyword("fn", "fn $1($2) {\n $0\n}"); add_keyword("const", "const $0"); add_keyword("type", "type $0"); @@ -103,6 +102,9 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte } if ctx.expects_expression() { + if !has_block_expr_parent { + add_keyword("unsafe", "unsafe {\n $0\n}"); + } add_keyword("match", "match $1 {\n $0\n}"); add_keyword("while", "while $1 {\n $0\n}"); add_keyword("while let", "while let $1 = $2 {\n $0\n}"); @@ -574,6 +576,7 @@ pub mod future { check( r#"fn main() { let _ = $0 }"#, expect![[r#" + kw unsafe kw match kw while kw while let @@ -634,6 +637,7 @@ fn foo() { } "#, expect![[r#" + kw unsafe kw match kw while kw while let diff --git a/crates/ide_completion/src/completions/mod_.rs b/crates/ide_completion/src/completions/mod_.rs index 4f9415736..6a5746fb9 100644 --- a/crates/ide_completion/src/completions/mod_.rs +++ b/crates/ide_completion/src/completions/mod_.rs @@ -9,14 +9,14 @@ use ide_db::{ }; use rustc_hash::FxHashSet; -use crate::CompletionItem; +use crate::{patterns::ImmediateLocation, CompletionItem}; use crate::{context::CompletionContext, item::CompletionKind, Completions}; /// Complete mod declaration, i.e. `mod $0 ;` pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { - let mod_under_caret = match &ctx.mod_declaration_under_caret { - Some(mod_under_caret) if mod_under_caret.item_list().is_none() => mod_under_caret, + let mod_under_caret = match &ctx.completion_location { + Some(ImmediateLocation::ModDeclaration(mod_under_caret)) => mod_under_caret, _ => return None, }; diff --git a/crates/ide_completion/src/completions/record.rs b/crates/ide_completion/src/completions/record.rs index e1526b70b..227c08d01 100644 --- a/crates/ide_completion/src/completions/record.rs +++ b/crates/ide_completion/src/completions/record.rs @@ -2,21 +2,21 @@ use ide_db::{helpers::FamousDefs, SymbolKind}; use syntax::ast::Expr; -use crate::{item::CompletionKind, CompletionContext, CompletionItem, Completions}; +use crate::{ + item::CompletionKind, patterns::ImmediateLocation, CompletionContext, CompletionItem, + Completions, +}; pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { - let missing_fields = match (ctx.record_pat_syntax.as_ref(), ctx.record_lit_syntax.as_ref()) { - (None, None) => return None, - (Some(_), Some(_)) => unreachable!("A record cannot be both a literal and a pattern"), - (Some(record_pat), _) => ctx.sema.record_pattern_missing_fields(record_pat), - (_, Some(record_lit)) => { - let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_lit.clone())); + let missing_fields = match &ctx.completion_location { + Some(ImmediateLocation::RecordExpr(record_expr)) => { + let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone())); let default_trait = FamousDefs(&ctx.sema, ctx.krate).core_default_Default(); let impl_default_trait = default_trait .zip(ty) .map_or(false, |(default_trait, ty)| ty.impls_trait(ctx.db, default_trait, &[])); - let missing_fields = ctx.sema.record_literal_missing_fields(record_lit); + let missing_fields = ctx.sema.record_literal_missing_fields(record_expr); if impl_default_trait && !missing_fields.is_empty() { let completion_text = "..Default::default()"; let mut item = CompletionItem::new( @@ -32,6 +32,10 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> missing_fields } + Some(ImmediateLocation::RecordPat(record_pat)) => { + ctx.sema.record_pattern_missing_fields(record_pat) + } + _ => return None, }; for (field, ty) in missing_fields { -- cgit v1.2.3