55use  std:: fmt; 
66
77use  either:: Either ; 
8+ use  hir_def:: hir:: Statement ; 
89use  hir_def:: lang_item:: LangItem ; 
910use  hir_def:: { resolver:: HasResolver ,  AdtId ,  AssocItemId ,  DefWithBodyId ,  HasModule } ; 
1011use  hir_def:: { ItemContainerId ,  Lookup } ; 
@@ -44,6 +45,10 @@ pub enum BodyValidationDiagnostic {
4445        match_expr :  ExprId , 
4546        uncovered_patterns :  String , 
4647    } , 
48+     NonExhaustiveLet  { 
49+         pat :  PatId , 
50+         uncovered_patterns :  String , 
51+     } , 
4752} 
4853
4954impl  BodyValidationDiagnostic  { 
@@ -61,7 +66,7 @@ struct ExprValidator {
6166    owner :  DefWithBodyId , 
6267    body :  Arc < Body > , 
6368    infer :  Arc < InferenceResult > , 
64-     pub ( super )   diagnostics :  Vec < BodyValidationDiagnostic > , 
69+     diagnostics :  Vec < BodyValidationDiagnostic > , 
6570} 
6671
6772impl  ExprValidator  { 
@@ -88,6 +93,9 @@ impl ExprValidator {
8893                Expr :: Call  {  .. }  | Expr :: MethodCall  {  .. }  => { 
8994                    self . validate_call ( db,  id,  expr,  & mut  filter_map_next_checker) ; 
9095                } 
96+                 Expr :: Block  {  .. }  => { 
97+                     self . validate_block ( db,  expr) ; 
98+                 } 
9199                _ => { } 
92100            } 
93101        } 
@@ -211,7 +219,7 @@ impl ExprValidator {
211219        if  !witnesses. is_empty ( )  { 
212220            self . diagnostics . push ( BodyValidationDiagnostic :: MissingMatchArms  { 
213221                match_expr, 
214-                 uncovered_patterns :  missing_match_arms ( & cx,  scrut_ty,  witnesses,  arms ) , 
222+                 uncovered_patterns :  missing_match_arms ( & cx,  scrut_ty,  witnesses,  & m_arms ) , 
215223            } ) ; 
216224        } 
217225    } 
@@ -231,6 +239,35 @@ impl ExprValidator {
231239        } 
232240        pattern
233241    } 
242+ 
243+     fn  validate_block ( & mut  self ,  db :  & dyn  HirDatabase ,  expr :  & Expr )  { 
244+         let  Expr :: Block  {  statements,  .. }  = expr else  {  return  } ; 
245+         let  pattern_arena = Arena :: new ( ) ; 
246+         let  cx = MatchCheckCtx :: new ( self . owner . module ( db. upcast ( ) ) ,  self . owner ,  db,  & pattern_arena) ; 
247+         for  stmt in  & * * statements { 
248+             let  Statement :: Let  {  pat,  initializer,  else_branch :  None ,  .. }  = stmt else  {  continue  } ; 
249+             let  Some ( initializer)  = initializer else  {  continue  } ; 
250+             let  init_ty = & self . infer [ * initializer] ; 
251+ 
252+             let  mut  have_errors = false ; 
253+             let  match_arm = match_check:: MatchArm  { 
254+                 pat :  self . lower_pattern ( & cx,  * pat,  db,  & mut  have_errors) , 
255+                 has_guard :  false , 
256+             } ; 
257+             if  have_errors { 
258+                 continue ; 
259+             } 
260+ 
261+             let  report = compute_match_usefulness ( & cx,  & [ match_arm] ,  init_ty) ; 
262+             let  witnesses = report. non_exhaustiveness_witnesses ; 
263+             if  !witnesses. is_empty ( )  { 
264+                 self . diagnostics . push ( BodyValidationDiagnostic :: NonExhaustiveLet  { 
265+                     pat :  * pat, 
266+                     uncovered_patterns :  missing_match_arms ( & cx,  init_ty,  witnesses,  & [ match_arm] ) , 
267+                 } ) ; 
268+             } 
269+         } 
270+     } 
234271} 
235272
236273struct  FilterMapNextChecker  { 
@@ -371,7 +408,7 @@ fn missing_match_arms<'p>(
371408    cx :  & MatchCheckCtx < ' _ ,  ' p > , 
372409    scrut_ty :  & Ty , 
373410    witnesses :  Vec < DeconstructedPat < ' p > > , 
374-     arms :  & [ MatchArm ] , 
411+     arms :  & [ match_check :: MatchArm < ' _ > ] , 
375412)  -> String  { 
376413    struct  DisplayWitness < ' a ,  ' p > ( & ' a  DeconstructedPat < ' p > ,  & ' a  MatchCheckCtx < ' a ,  ' p > ) ; 
377414    impl  fmt:: Display  for  DisplayWitness < ' _ ,  ' _ >  { 
0 commit comments