aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/expr.rs')
-rw-r--r--crates/ra_hir_ty/src/expr.rs68
1 files changed, 32 insertions, 36 deletions
diff --git a/crates/ra_hir_ty/src/expr.rs b/crates/ra_hir_ty/src/expr.rs
index 827b687de..21abbcf1e 100644
--- a/crates/ra_hir_ty/src/expr.rs
+++ b/crates/ra_hir_ty/src/expr.rs
@@ -89,21 +89,19 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
89 let (_, source_map) = db.body_with_source_map(self.func.into()); 89 let (_, source_map) = db.body_with_source_map(self.func.into());
90 90
91 if let Ok(source_ptr) = source_map.expr_syntax(id) { 91 if let Ok(source_ptr) = source_map.expr_syntax(id) {
92 if let Some(expr) = source_ptr.value.as_ref().left() { 92 let root = source_ptr.file_syntax(db.upcast());
93 let root = source_ptr.file_syntax(db.upcast()); 93 if let ast::Expr::RecordLit(record_lit) = &source_ptr.value.to_node(&root) {
94 if let ast::Expr::RecordLit(record_lit) = expr.to_node(&root) { 94 if let Some(field_list) = record_lit.record_field_list() {
95 if let Some(field_list) = record_lit.record_field_list() { 95 let variant_data = variant_data(db.upcast(), variant_def);
96 let variant_data = variant_data(db.upcast(), variant_def); 96 let missed_fields = missed_fields
97 let missed_fields = missed_fields 97 .into_iter()
98 .into_iter() 98 .map(|idx| variant_data.fields()[idx].name.clone())
99 .map(|idx| variant_data.fields()[idx].name.clone()) 99 .collect();
100 .collect(); 100 self.sink.push(MissingFields {
101 self.sink.push(MissingFields { 101 file: source_ptr.file_id,
102 file: source_ptr.file_id, 102 field_list: AstPtr::new(&field_list),
103 field_list: AstPtr::new(&field_list), 103 missed_fields,
104 missed_fields, 104 })
105 })
106 }
107 } 105 }
108 } 106 }
109 } 107 }
@@ -163,12 +161,6 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
163 161
164 let mut seen = Matrix::empty(); 162 let mut seen = Matrix::empty();
165 for pat in pats { 163 for pat in pats {
166 // We skip any patterns whose type we cannot resolve.
167 //
168 // This could lead to false positives in this diagnostic, so
169 // it might be better to skip the entire diagnostic if we either
170 // cannot resolve a match arm or determine that the match arm has
171 // the wrong type.
172 if let Some(pat_ty) = infer.type_of_pat.get(pat) { 164 if let Some(pat_ty) = infer.type_of_pat.get(pat) {
173 // We only include patterns whose type matches the type 165 // We only include patterns whose type matches the type
174 // of the match expression. If we had a InvalidMatchArmPattern 166 // of the match expression. If we had a InvalidMatchArmPattern
@@ -191,8 +183,15 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
191 // to the matrix here. 183 // to the matrix here.
192 let v = PatStack::from_pattern(pat); 184 let v = PatStack::from_pattern(pat);
193 seen.push(&cx, v); 185 seen.push(&cx, v);
186 continue;
194 } 187 }
195 } 188 }
189
190 // If we can't resolve the type of a pattern, or the pattern type doesn't
191 // fit the match expression, we skip this diagnostic. Skipping the entire
192 // diagnostic rather than just not including this match arm is preferred
193 // to avoid the chance of false positives.
194 return;
196 } 195 }
197 196
198 match is_useful(&cx, &seen, &PatStack::from_wild()) { 197 match is_useful(&cx, &seen, &PatStack::from_wild()) {
@@ -205,18 +204,16 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
205 } 204 }
206 205
207 if let Ok(source_ptr) = source_map.expr_syntax(id) { 206 if let Ok(source_ptr) = source_map.expr_syntax(id) {
208 if let Some(expr) = source_ptr.value.as_ref().left() { 207 let root = source_ptr.file_syntax(db.upcast());
209 let root = source_ptr.file_syntax(db.upcast()); 208 if let ast::Expr::MatchExpr(match_expr) = &source_ptr.value.to_node(&root) {
210 if let ast::Expr::MatchExpr(match_expr) = expr.to_node(&root) { 209 if let (Some(match_expr), Some(arms)) =
211 if let (Some(match_expr), Some(arms)) = 210 (match_expr.expr(), match_expr.match_arm_list())
212 (match_expr.expr(), match_expr.match_arm_list()) 211 {
213 { 212 self.sink.push(MissingMatchArms {
214 self.sink.push(MissingMatchArms { 213 file: source_ptr.file_id,
215 file: source_ptr.file_id, 214 match_expr: AstPtr::new(&match_expr),
216 match_expr: AstPtr::new(&match_expr), 215 arms: AstPtr::new(&arms),
217 arms: AstPtr::new(&arms), 216 })
218 })
219 }
220 } 217 }
221 } 218 }
222 } 219 }
@@ -247,9 +244,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
247 let (_, source_map) = db.body_with_source_map(self.func.into()); 244 let (_, source_map) = db.body_with_source_map(self.func.into());
248 245
249 if let Ok(source_ptr) = source_map.expr_syntax(id) { 246 if let Ok(source_ptr) = source_map.expr_syntax(id) {
250 if let Some(expr) = source_ptr.value.left() { 247 self.sink
251 self.sink.push(MissingOkInTailExpr { file: source_ptr.file_id, expr }); 248 .push(MissingOkInTailExpr { file: source_ptr.file_id, expr: source_ptr.value });
252 }
253 } 249 }
254 } 250 }
255 } 251 }