aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-02-19 16:53:32 +0000
committerAleksey Kladov <[email protected]>2020-02-19 17:17:09 +0000
commit9549aad525845d5e401a71254d25ca92920de462 (patch)
treebf1cc13ddb0fd6b45e6a19789d5e3cd79caaf904
parent7db7c868812c7289626825988fb6e610ea747eeb (diff)
Fill missing fields of enum variants
-rw-r--r--crates/ra_hir_ty/src/expr.rs18
-rw-r--r--crates/ra_ide/src/diagnostics.rs29
2 files changed, 40 insertions, 7 deletions
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index 0d11b537c..22f24890d 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -15,6 +15,7 @@ use rustc_hash::FxHashSet;
15use crate::{ 15use crate::{
16 db::HirDatabase, 16 db::HirDatabase,
17 diagnostics::{MissingFields, MissingOkInTailExpr}, 17 diagnostics::{MissingFields, MissingOkInTailExpr},
18 utils::variant_data,
18 ApplicationTy, InferenceResult, Ty, TypeCtor, 19 ApplicationTy, InferenceResult, Ty, TypeCtor,
19}; 20};
20 21
@@ -27,6 +28,7 @@ pub use hir_def::{
27 ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp, 28 ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal, LogicOp,
28 MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp, 29 MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, UnaryOp,
29 }, 30 },
31 VariantId,
30}; 32};
31 33
32pub struct ExprValidator<'a, 'b: 'a> { 34pub struct ExprValidator<'a, 'b: 'a> {
@@ -69,17 +71,19 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
69 ) { 71 ) {
70 if spread.is_some() { 72 if spread.is_some() {
71 return; 73 return;
74 };
75 let variant_def: VariantId = match self.infer.variant_resolution_for_expr(id) {
76 Some(VariantId::UnionId(_)) | None => return,
77 Some(it) => it,
78 };
79 if let VariantId::UnionId(_) = variant_def {
80 return;
72 } 81 }
73 82
74 let struct_def = match self.infer[id].as_adt() { 83 let variant_data = variant_data(db, variant_def);
75 Some((AdtId::StructId(s), _)) => s,
76 _ => return,
77 };
78 let struct_data = db.struct_data(struct_def);
79 84
80 let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); 85 let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect();
81 let missed_fields: Vec<Name> = struct_data 86 let missed_fields: Vec<Name> = variant_data
82 .variant_data
83 .fields() 87 .fields()
84 .iter() 88 .iter()
85 .filter_map(|(_f, d)| { 89 .filter_map(|(_f, d)| {
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index 82596c665..9cf86b26d 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -470,6 +470,35 @@ mod tests {
470 } 470 }
471 471
472 #[test] 472 #[test]
473 fn test_fill_struct_fields_enum() {
474 let before = r"
475 enum Expr {
476 Bin { lhs: Box<Expr>, rhs: Box<Expr> }
477 }
478
479 impl Expr {
480 fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr {
481 Expr::Bin { <|> }
482 }
483 }
484
485 ";
486 let after = r"
487 enum Expr {
488 Bin { lhs: Box<Expr>, rhs: Box<Expr> }
489 }
490
491 impl Expr {
492 fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr {
493 Expr::Bin { lhs: (), rhs: () <|> }
494 }
495 }
496
497 ";
498 check_apply_diagnostic_fix(before, after);
499 }
500
501 #[test]
473 fn test_fill_struct_fields_partial() { 502 fn test_fill_struct_fields_partial() {
474 let before = r" 503 let before = r"
475 struct TestStruct { 504 struct TestStruct {