@@ -118,31 +118,6 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
118118 check_for_bindings_named_same_as_variants ( self , pat) ;
119119 }
120120
121- fn let_source ( & mut self , pat : & ' tcx hir:: Pat < ' tcx > , _expr : & hir:: Expr < ' _ > ) -> LetSource {
122- let hir = self . tcx . hir ( ) ;
123- let parent = hir. get_parent_node ( pat. hir_id ) ;
124- let parent_parent = hir. get_parent_node ( parent) ;
125- let parent_parent_node = hir. get ( parent_parent) ;
126-
127- let parent_parent_parent = hir. get_parent_node ( parent_parent) ;
128- let parent_parent_parent_parent = hir. get_parent_node ( parent_parent_parent) ;
129- let parent_parent_parent_parent_node = hir. get ( parent_parent_parent_parent) ;
130-
131- if let hir:: Node :: Expr ( hir:: Expr {
132- kind : hir:: ExprKind :: Loop ( _, _, hir:: LoopSource :: While , _) ,
133- ..
134- } ) = parent_parent_parent_parent_node
135- {
136- LetSource :: WhileLet
137- } else if let hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: If { .. } , .. } ) =
138- parent_parent_node
139- {
140- LetSource :: IfLet
141- } else {
142- LetSource :: GenericLet
143- }
144- }
145-
146121 fn lower_pattern < ' p > (
147122 & self ,
148123 cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
@@ -172,10 +147,9 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
172147
173148 fn check_let ( & mut self , pat : & ' tcx hir:: Pat < ' tcx > , expr : & hir:: Expr < ' _ > , span : Span ) {
174149 self . check_patterns ( pat) ;
175- let ls = self . let_source ( pat, expr) ;
176150 let mut cx = self . new_cx ( expr. hir_id ) ;
177151 let tpat = self . lower_pattern ( & mut cx, pat, & mut false ) . 0 ;
178- check_let_reachability ( & mut cx, ls , pat. hir_id , & tpat, span) ;
152+ check_let_reachability ( & mut cx, pat. hir_id , & tpat, span) ;
179153 }
180154
181155 fn check_match (
@@ -192,13 +166,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
192166 if let Some ( hir:: Guard :: IfLet ( ref pat, _) ) = arm. guard {
193167 self . check_patterns ( pat) ;
194168 let tpat = self . lower_pattern ( & mut cx, pat, & mut false ) . 0 ;
195- check_let_reachability (
196- & mut cx,
197- LetSource :: IfLetGuard ,
198- pat. hir_id ,
199- & tpat,
200- tpat. span ,
201- ) ;
169+ check_let_reachability ( & mut cx, pat. hir_id , & tpat, tpat. span ) ;
202170 }
203171 }
204172
@@ -397,7 +365,7 @@ fn unreachable_pattern(tcx: TyCtxt<'_>, span: Span, id: HirId, catchall: Option<
397365 } ) ;
398366}
399367
400- fn irrefutable_let_pattern ( id : HirId , ls : LetSource , span : Span , tcx : TyCtxt < ' _ > ) {
368+ fn irrefutable_let_pattern ( tcx : TyCtxt < ' _ > , id : HirId , span : Span ) {
401369 macro_rules! emit_diag {
402370 (
403371 $lint: expr,
@@ -412,7 +380,8 @@ fn irrefutable_let_pattern(id: HirId, ls: LetSource, span: Span, tcx: TyCtxt<'_>
412380 } } ;
413381 }
414382
415- tcx. struct_span_lint_hir ( IRREFUTABLE_LET_PATTERNS , id, span, |lint| match ls {
383+ let source = let_source ( tcx, id) ;
384+ tcx. struct_span_lint_hir ( IRREFUTABLE_LET_PATTERNS , id, span, |lint| match source {
416385 LetSource :: GenericLet => {
417386 emit_diag ! ( lint, "`let`" , "`let` is useless" , "removing `let`" ) ;
418387 }
@@ -445,7 +414,6 @@ fn irrefutable_let_pattern(id: HirId, ls: LetSource, span: Span, tcx: TyCtxt<'_>
445414
446415fn check_let_reachability < ' p , ' tcx > (
447416 cx : & mut MatchCheckCtxt < ' p , ' tcx > ,
448- ls : LetSource ,
449417 pat_id : HirId ,
450418 pat : & ' p super :: Pat < ' tcx > ,
451419 span : Span ,
@@ -454,13 +422,13 @@ fn check_let_reachability<'p, 'tcx>(
454422 let report = compute_match_usefulness ( & cx, & arms, pat_id, pat. ty ) ;
455423
456424 report_arm_reachability ( & cx, & report, |arm_index, arm_span, arm_hir_id, _| {
457- match ls {
425+ match let_source ( cx . tcx , pat_id ) {
458426 LetSource :: IfLet | LetSource :: WhileLet => {
459427 match arm_index {
460428 // The arm with the user-specified pattern.
461429 0 => unreachable_pattern ( cx. tcx , arm_span, arm_hir_id, None ) ,
462430 // The arm with the wildcard pattern.
463- 1 => irrefutable_let_pattern ( pat_id , ls , arm_span, cx . tcx ) ,
431+ 1 => irrefutable_let_pattern ( cx . tcx , pat_id , arm_span) ,
464432 _ => bug ! ( ) ,
465433 }
466434 }
@@ -473,7 +441,7 @@ fn check_let_reachability<'p, 'tcx>(
473441
474442 if report. non_exhaustiveness_witnesses . is_empty ( ) {
475443 // The match is exhaustive, i.e. the `if let` pattern is irrefutable.
476- irrefutable_let_pattern ( pat_id , ls , span, cx . tcx ) ;
444+ irrefutable_let_pattern ( cx . tcx , pat_id , span) ;
477445 }
478446}
479447
@@ -789,3 +757,37 @@ pub enum LetSource {
789757 IfLetGuard ,
790758 WhileLet ,
791759}
760+
761+ fn let_source ( tcx : TyCtxt < ' _ > , pat_id : HirId ) -> LetSource {
762+ let hir = tcx. hir ( ) ;
763+ let parent = hir. get_parent_node ( pat_id) ;
764+ match hir. get ( parent) {
765+ hir:: Node :: Arm ( hir:: Arm {
766+ guard : Some ( hir:: Guard :: IfLet ( & hir:: Pat { hir_id, .. } , _) ) ,
767+ ..
768+ } ) if hir_id == pat_id => {
769+ return LetSource :: IfLetGuard ;
770+ }
771+ _ => { }
772+ }
773+ let parent_parent = hir. get_parent_node ( parent) ;
774+ let parent_parent_node = hir. get ( parent_parent) ;
775+
776+ let parent_parent_parent = hir. get_parent_node ( parent_parent) ;
777+ let parent_parent_parent_parent = hir. get_parent_node ( parent_parent_parent) ;
778+ let parent_parent_parent_parent_node = hir. get ( parent_parent_parent_parent) ;
779+
780+ if let hir:: Node :: Expr ( hir:: Expr {
781+ kind : hir:: ExprKind :: Loop ( _, _, hir:: LoopSource :: While , _) ,
782+ ..
783+ } ) = parent_parent_parent_parent_node
784+ {
785+ LetSource :: WhileLet
786+ } else if let hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: If { .. } , .. } ) =
787+ parent_parent_node
788+ {
789+ LetSource :: IfLet
790+ } else {
791+ LetSource :: GenericLet
792+ }
793+ }
0 commit comments