Fill missing fields of enum variants

This commit is contained in:
Aleksey Kladov 2020-02-19 17:53:32 +01:00
parent 7db7c86881
commit 9549aad525
2 changed files with 40 additions and 7 deletions

View file

@ -15,6 +15,7 @@ use rustc_hash::FxHashSet;
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
diagnostics::{MissingFields, MissingOkInTailExpr}, diagnostics::{MissingFields, MissingOkInTailExpr},
utils::variant_data,
ApplicationTy, InferenceResult, Ty, TypeCtor, ApplicationTy, InferenceResult, Ty, TypeCtor,
}; };
@ -27,6 +28,7 @@ pub use hir_def::{
ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp,
MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp,
}, },
VariantId,
}; };
pub struct ExprValidator<'a, 'b: 'a> { pub struct ExprValidator<'a, 'b: 'a> {
@ -69,17 +71,19 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
) { ) {
if spread.is_some() { if spread.is_some() {
return; return;
};
let variant_def: VariantId = match self.infer.variant_resolution_for_expr(id) {
Some(VariantId::UnionId(_)) | None => return,
Some(it) => it,
};
if let VariantId::UnionId(_) = variant_def {
return;
} }
let struct_def = match self.infer[id].as_adt() { let variant_data = variant_data(db, variant_def);
Some((AdtId::StructId(s), _)) => s,
_ => return,
};
let struct_data = db.struct_data(struct_def);
let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
let missed_fields: Vec<Name> = struct_data let missed_fields: Vec<Name> = variant_data
.variant_data
.fields() .fields()
.iter() .iter()
.filter_map(|(_f, d)| { .filter_map(|(_f, d)| {

View file

@ -469,6 +469,35 @@ mod tests {
check_apply_diagnostic_fix(before, after); check_apply_diagnostic_fix(before, after);
} }
#[test]
fn test_fill_struct_fields_enum() {
let before = r"
enum Expr {
Bin { lhs: Box<Expr>, rhs: Box<Expr> }
}
impl Expr {
fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr {
Expr::Bin { <|> }
}
}
";
let after = r"
enum Expr {
Bin { lhs: Box<Expr>, rhs: Box<Expr> }
}
impl Expr {
fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr {
Expr::Bin { lhs: (), rhs: () <|> }
}
}
";
check_apply_diagnostic_fix(before, after);
}
#[test] #[test]
fn test_fill_struct_fields_partial() { fn test_fill_struct_fields_partial() {
let before = r" let before = r"