22
33use std:: sync:: Arc ;
44
5- use hir_def:: { path:: path, resolver:: HasResolver , AdtId , DefWithBodyId } ;
5+ use hir_def:: { AdtId , DefWithBodyId , expr :: Statement , path:: path, resolver:: HasResolver } ;
66use hir_expand:: diagnostics:: DiagnosticSink ;
77use rustc_hash:: FxHashSet ;
88use syntax:: { ast, AstPtr } ;
@@ -23,6 +23,8 @@ pub(crate) use hir_def::{
2323 LocalFieldId , VariantId ,
2424} ;
2525
26+ use super :: RemoveThisSemicolon ;
27+
2628pub ( super ) struct ExprValidator < ' a , ' b : ' a > {
2729 owner : DefWithBodyId ,
2830 infer : Arc < InferenceResult > ,
@@ -78,6 +80,12 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
7880 let body_expr = & body[ body. body_expr ] ;
7981 if let Expr :: Block { tail : Some ( t) , .. } = body_expr {
8082 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+ }
8189 }
8290 }
8391
@@ -317,6 +325,23 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
317325 }
318326 }
319327 }
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+ }
320345}
321346
322347pub fn record_literal_missing_fields (
0 commit comments