diff options
Diffstat (limited to 'crates/ra_hir/src/expr')
-rw-r--r-- | crates/ra_hir/src/expr/validation.rs | 77 |
1 files changed, 39 insertions, 38 deletions
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs index aebed6788..3f758f283 100644 --- a/crates/ra_hir/src/expr/validation.rs +++ b/crates/ra_hir/src/expr/validation.rs | |||
@@ -5,13 +5,11 @@ use ra_syntax::ast::{AstNode, StructLit}; | |||
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | expr::AstPtr, | 7 | expr::AstPtr, |
8 | HirDatabase, | 8 | HirDatabase, Function, Name, |
9 | Function, | ||
10 | Name, | ||
11 | diagnostics::{DiagnosticSink, MissingFields}, | 9 | diagnostics::{DiagnosticSink, MissingFields}, |
12 | adt::AdtDef, | 10 | adt::AdtDef, |
13 | Path, | 11 | Path, |
14 | ty::InferenceResult | 12 | ty::InferenceResult, |
15 | }; | 13 | }; |
16 | use super::{Expr, StructLitField, ExprId}; | 14 | use super::{Expr, StructLitField, ExprId}; |
17 | 15 | ||
@@ -50,43 +48,46 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
50 | spread: &Option<ExprId>, | 48 | spread: &Option<ExprId>, |
51 | db: &impl HirDatabase, | 49 | db: &impl HirDatabase, |
52 | ) { | 50 | ) { |
53 | if let Some(_) = spread { | 51 | if spread.is_some() { |
54 | return; | 52 | return; |
55 | } | 53 | } |
54 | |||
55 | let struct_def = match self.infer[id].as_adt() { | ||
56 | Some((AdtDef::Struct(s), _)) => s, | ||
57 | _ => return, | ||
58 | }; | ||
59 | |||
56 | let lit_fields: FxHashSet<_> = fields.into_iter().map(|f| &f.name).collect(); | 60 | let lit_fields: FxHashSet<_> = fields.into_iter().map(|f| &f.name).collect(); |
57 | let struct_ty = &self.infer[id]; | 61 | let missed_fields: Vec<Name> = struct_def |
58 | if let Some((AdtDef::Struct(s), _)) = struct_ty.as_adt() { | 62 | .fields(db) |
59 | let missed_fields: Vec<Name> = s | 63 | .iter() |
60 | .fields(db) | 64 | .filter_map(|f| { |
61 | .iter() | 65 | let name = f.name(db); |
62 | .filter_map(|f| { | 66 | if lit_fields.contains(&name) { |
63 | let name = f.name(db); | 67 | None |
64 | if lit_fields.contains(&name) { | 68 | } else { |
65 | None | 69 | Some(name) |
66 | } else { | 70 | } |
67 | Some(name) | 71 | }) |
68 | } | 72 | .collect(); |
69 | }) | 73 | if missed_fields.is_empty() { |
70 | .collect(); | 74 | return; |
71 | if missed_fields.is_empty() { | 75 | } |
72 | return; | 76 | let source_map = self.func.body_source_map(db); |
73 | } | 77 | let file_id = self.func.source(db).0; |
74 | let source_map = self.func.body_source_map(db); | 78 | let source_file = db.parse(file_id.original_file(db)); |
75 | let file_id = self.func.source(db).0; | 79 | if let Some(field_list_node) = source_map |
76 | let source_file = db.parse(file_id.original_file(db)); | 80 | .expr_syntax(id) |
77 | if let Some(field_list_node) = source_map | 81 | .map(|ptr| ptr.to_node(source_file.syntax())) |
78 | .expr_syntax(id) | 82 | .and_then(StructLit::cast) |
79 | .map(|ptr| ptr.to_node(source_file.syntax())) | 83 | .and_then(|lit| lit.named_field_list()) |
80 | .and_then(StructLit::cast) | 84 | { |
81 | .and_then(|lit| lit.named_field_list()) | 85 | let field_list_ptr = AstPtr::new(field_list_node); |
82 | { | 86 | self.sink.push(MissingFields { |
83 | let field_list_ptr = AstPtr::new(field_list_node); | 87 | file: file_id, |
84 | self.sink.push(MissingFields { | 88 | field_list: field_list_ptr, |
85 | file: file_id, | 89 | missed_fields, |
86 | field_list: field_list_ptr, | 90 | }) |
87 | missed_fields, | ||
88 | }) | ||
89 | } | ||
90 | } | 91 | } |
91 | } | 92 | } |
92 | } | 93 | } |