feat(diagnostics): use Default::default() expression instead of todo! when missing fields

Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com>
This commit is contained in:
Benjamin Coenen 2021-12-30 15:49:31 +01:00
parent 3d63abf1d8
commit 0435463439
2 changed files with 20 additions and 4 deletions

View file

@ -1,6 +1,6 @@
use either::Either; use either::Either;
use hir::{db::AstDatabase, InFile}; use hir::{db::AstDatabase, InFile, Type};
use ide_db::{assists::Assist, source_change::SourceChange}; use ide_db::{assists::Assist, helpers::FamousDefs, source_change::SourceChange};
use rustc_hash::FxHashMap; use rustc_hash::FxHashMap;
use stdx::format_to; use stdx::format_to;
use syntax::{algo, ast::make, AstNode, SyntaxNodePtr}; use syntax::{algo, ast::make, AstNode, SyntaxNodePtr};
@ -63,6 +63,19 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
} }
}); });
let missing_fields = ctx.sema.record_literal_missing_fields(&field_list_parent); let missing_fields = ctx.sema.record_literal_missing_fields(&field_list_parent);
let generate_default_expr = |ty: &Type| {
let krate = ctx.sema.to_module_def(d.file.original_file(ctx.sema.db))?.krate();
let default_trait = FamousDefs(&ctx.sema, Some(krate)).core_default_Default();
match default_trait {
Some(default_trait) if ty.impls_trait(ctx.sema.db, default_trait, &[]) => {
Some(make::ext::expr_default())
}
_ => Some(make::ext::expr_todo()),
}
};
for (f, ty) in missing_fields.iter() { for (f, ty) in missing_fields.iter() {
let field_expr = if let Some(local_candidate) = locals.get(&f.name(ctx.sema.db)) { let field_expr = if let Some(local_candidate) = locals.get(&f.name(ctx.sema.db)) {
cov_mark::hit!(field_shorthand); cov_mark::hit!(field_shorthand);
@ -70,10 +83,10 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &hir::MissingFields) -> Option<Vec<Ass
if ty.could_unify_with(ctx.sema.db, &candidate_ty) { if ty.could_unify_with(ctx.sema.db, &candidate_ty) {
None None
} else { } else {
Some(make::ext::expr_todo()) generate_default_expr(ty)
} }
} else { } else {
Some(make::ext::expr_todo()) generate_default_expr(ty)
}; };
let field = let field =
make::record_expr_field(make::name_ref(&f.name(ctx.sema.db).to_smol_str()), field_expr) make::record_expr_field(make::name_ref(&f.name(ctx.sema.db).to_smol_str()), field_expr)

View file

@ -59,6 +59,9 @@ pub mod ext {
pub fn expr_todo() -> ast::Expr { pub fn expr_todo() -> ast::Expr {
expr_from_text("todo!()") expr_from_text("todo!()")
} }
pub fn expr_default() -> ast::Expr {
expr_from_text("Default::default()")
}
pub fn empty_block_expr() -> ast::BlockExpr { pub fn empty_block_expr() -> ast::BlockExpr {
block_expr(None, None) block_expr(None, None)
} }