9849: internal: Refine functional update completion some more r=Veykril a=Veykril

cc https://github.com/rust-analyzer/rust-analyzer/issues/9839
bors r+

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
bors[bot] 2021-08-10 15:05:04 +00:00 committed by GitHub
commit c943057038
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 7 deletions

View File

@ -1,15 +1,18 @@
//! Complete fields in record literals and patterns.
use ide_db::{helpers::FamousDefs, SymbolKind};
use syntax::ast::Expr;
use syntax::{ast::Expr, T};
use crate::{
item::CompletionKind, patterns::ImmediateLocation, CompletionContext, CompletionItem,
Completions,
CompletionItemKind, Completions,
};
pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
let missing_fields = match &ctx.completion_location {
Some(ImmediateLocation::RecordExpr(record_expr)) => {
Some(
ImmediateLocation::RecordExpr(record_expr)
| ImmediateLocation::RecordExprUpdate(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)| {
@ -29,7 +32,13 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
item.insert_text(completion_text).kind(SymbolKind::Field);
item.add_to(acc);
}
if ctx.previous_token_is(T![.]) {
let mut item =
CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), "..");
item.insert_text(".").kind(CompletionItemKind::Snippet);
item.add_to(acc);
return None;
}
missing_fields
}
Some(ImmediateLocation::RecordPat(record_pat)) => {

View File

@ -63,6 +63,9 @@ pub(crate) enum ImmediateLocation {
/// The record expr of the field name we are completing
RecordExpr(ast::RecordExpr),
// Original file ast node
/// The record expr of the functional update syntax we are completing
RecordExprUpdate(ast::RecordExpr),
// Original file ast node
/// The record pat of the field name we are completing
RecordPat(ast::RecordPat),
}
@ -209,7 +212,7 @@ pub(crate) fn determine_location(
},
ast::RecordExprFieldList(_it) => sema
.find_node_at_offset_with_macros(original_file, offset)
.map(ImmediateLocation::RecordExpr)?,
.map(ImmediateLocation::RecordExprUpdate)?,
ast::TupleField(_it) => ImmediateLocation::TupleField,
ast::TupleFieldList(_it) => ImmediateLocation::TupleField,
ast::TypeBound(_it) => ImmediateLocation::TypeBound,

View File

@ -136,8 +136,7 @@ fn main() {
"#,
expect![[r#"
fd ..Default::default()
fd foo1 u32
fd foo2 u32
sn ..
"#]],
);
check(
@ -155,6 +154,28 @@ fn main() {
}
"#,
expect![[r#"
kw unsafe
kw match
kw while
kw while let
kw loop
kw if
kw if let
kw for
kw true
kw false
kw return
kw self
kw super
kw crate
lc foo Foo
lc thing i32
st Foo
fn main() fn()
md core
bt u32
tt Sized
tt Default
fd ..Default::default()
fd foo1 u32
fd foo2 u32