diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-12-10 16:18:49 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-10 16:18:49 +0000 |
commit | 44978acf51e25513ef8420e228221273f42abf8c (patch) | |
tree | cc798690135a0adc9ee43bdb6d2b99686ce9e6f1 /crates/hir_ty/src/diagnostics | |
parent | 5a6065e3b05e2624c4c340f928b20c04ce579928 (diff) | |
parent | bbb0bc7b041278480edbfaa7c3cdadc5a704fc03 (diff) |
Merge #6769
6769: Add native "remove this semicolon" diagnostics r=matklad a=ivan770
Closes #6739
![demo2](https://user-images.githubusercontent.com/14003886/101530533-b76c3180-399a-11eb-9d18-5c8457721655.gif)
Co-authored-by: ivan770 <[email protected]>
Diffstat (limited to 'crates/hir_ty/src/diagnostics')
-rw-r--r-- | crates/hir_ty/src/diagnostics/expr.rs | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index 434b19354..849415706 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::{expr::Statement, path::path, resolver::HasResolver, AdtId, DefWithBodyId}; |
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}; |
@@ -12,6 +12,7 @@ use crate::{ | |||
12 | diagnostics::{ | 12 | diagnostics::{ |
13 | match_check::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, | 13 | match_check::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, |
14 | MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, | 14 | MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, |
15 | RemoveThisSemicolon, | ||
15 | }, | 16 | }, |
16 | utils::variant_data, | 17 | utils::variant_data, |
17 | ApplicationTy, InferenceResult, Ty, TypeCtor, | 18 | ApplicationTy, InferenceResult, Ty, TypeCtor, |
@@ -76,8 +77,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
76 | } | 77 | } |
77 | } | 78 | } |
78 | let body_expr = &body[body.body_expr]; | 79 | let body_expr = &body[body.body_expr]; |
79 | if let Expr::Block { tail: Some(t), .. } = body_expr { | 80 | if let Expr::Block { statements, tail, .. } = body_expr { |
80 | self.validate_results_in_tail_expr(body.body_expr, *t, db); | 81 | if let Some(t) = tail { |
82 | self.validate_results_in_tail_expr(body.body_expr, *t, db); | ||
83 | } else if let Some(Statement::Expr(id)) = statements.last() { | ||
84 | self.validate_missing_tail_expr(body.body_expr, *id, db); | ||
85 | } | ||
81 | } | 86 | } |
82 | } | 87 | } |
83 | 88 | ||
@@ -317,6 +322,34 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
317 | } | 322 | } |
318 | } | 323 | } |
319 | } | 324 | } |
325 | |||
326 | fn validate_missing_tail_expr( | ||
327 | &mut self, | ||
328 | body_id: ExprId, | ||
329 | possible_tail_id: ExprId, | ||
330 | db: &dyn HirDatabase, | ||
331 | ) { | ||
332 | let mismatch = match self.infer.type_mismatch_for_expr(body_id) { | ||
333 | Some(m) => m, | ||
334 | None => return, | ||
335 | }; | ||
336 | |||
337 | let possible_tail_ty = match self.infer.type_of_expr.get(possible_tail_id) { | ||
338 | Some(ty) => ty, | ||
339 | None => return, | ||
340 | }; | ||
341 | |||
342 | if mismatch.actual != Ty::unit() || mismatch.expected != *possible_tail_ty { | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | let (_, source_map) = db.body_with_source_map(self.owner.into()); | ||
347 | |||
348 | if let Ok(source_ptr) = source_map.expr_syntax(possible_tail_id) { | ||
349 | self.sink | ||
350 | .push(RemoveThisSemicolon { file: source_ptr.file_id, expr: source_ptr.value }); | ||
351 | } | ||
352 | } | ||
320 | } | 353 | } |
321 | 354 | ||
322 | pub fn record_literal_missing_fields( | 355 | pub fn record_literal_missing_fields( |