diff options
Diffstat (limited to 'crates/hir_ty/src/diagnostics')
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 434b19354..313422968 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::{path::path, resolver::HasResolver, AdtId, DefWithBodyId}; | 5 | use hir_def::{AdtId, DefWithBodyId, expr::Statement, path::path, resolver::HasResolver}; |
6 | use hir_expand::diagnostics::DiagnosticSink; | 6 | use hir_expand::diagnostics::DiagnosticSink; |
7 | use rustc_hash::FxHashSet; | 7 | use rustc_hash::FxHashSet; |
8 | use syntax::{ast, AstPtr}; | 8 | use syntax::{ast, AstPtr}; |
@@ -23,6 +23,8 @@ pub(crate) use hir_def::{ | |||
23 | LocalFieldId, VariantId, | 23 | LocalFieldId, VariantId, |
24 | }; | 24 | }; |
25 | 25 | ||
26 | use super::RemoveThisSemicolon; | ||
27 | |||
26 | pub(super) struct ExprValidator<'a, 'b: 'a> { | 28 | pub(super) struct ExprValidator<'a, 'b: 'a> { |
27 | owner: DefWithBodyId, | 29 | owner: DefWithBodyId, |
28 | infer: Arc<InferenceResult>, | 30 | infer: Arc<InferenceResult>, |
@@ -78,6 +80,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
78 | let body_expr = &body[body.body_expr]; | 80 | let body_expr = &body[body.body_expr]; |
79 | if let Expr::Block { tail: Some(t), .. } = body_expr { | 81 | if let Expr::Block { tail: Some(t), .. } = body_expr { |
80 | self.validate_results_in_tail_expr(body.body_expr, *t, db); | 82 | self.validate_results_in_tail_expr(body.body_expr, *t, db); |
83 | } else { | ||
84 | if let Expr::Block { statements, .. } = body_expr { | ||
85 | if let Some(Statement::Expr(id)) = statements.last() { | ||
86 | self.validate_missing_tail_expr(body.body_expr, *id, db); | ||
87 | } | ||
88 | } | ||
81 | } | 89 | } |
82 | } | 90 | } |
83 | 91 | ||
@@ -317,6 +325,23 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
317 | } | 325 | } |
318 | } | 326 | } |
319 | } | 327 | } |
328 | |||
329 | fn validate_missing_tail_expr(&mut self, body_id: ExprId, possible_tail_id: ExprId, db: &dyn HirDatabase) { | ||
330 | let mismatch = match self.infer.type_mismatch_for_expr(body_id) { | ||
331 | Some(m) => m, | ||
332 | None => return, | ||
333 | }; | ||
334 | |||
335 | if let Some(possible_tail_ty) = self.infer.type_of_expr.get(possible_tail_id) { | ||
336 | if mismatch.actual == Ty::unit() && mismatch.expected == *possible_tail_ty { | ||
337 | let (_, source_map) = db.body_with_source_map(self.owner.into()); | ||
338 | |||
339 | if let Ok(source_ptr) = source_map.expr_syntax(possible_tail_id) { | ||
340 | self.sink.push(RemoveThisSemicolon { file: source_ptr.file_id, expr: source_ptr.value }); | ||
341 | } | ||
342 | } | ||
343 | } | ||
344 | } | ||
320 | } | 345 | } |
321 | 346 | ||
322 | pub fn record_literal_missing_fields( | 347 | pub fn record_literal_missing_fields( |