@@ -17,6 +17,7 @@ use rustc_session::lint::builtin::{
1717 BINDINGS_WITH_VARIANT_NAME , IRREFUTABLE_LET_PATTERNS , UNREACHABLE_PATTERNS ,
1818} ;
1919use rustc_session:: Session ;
20+ use rustc_span:: source_map:: Spanned ;
2021use rustc_span:: { DesugaringKind , ExpnKind , Span } ;
2122
2223crate fn check_match ( tcx : TyCtxt < ' _ > , def_id : DefId ) {
@@ -445,6 +446,10 @@ fn check_let_reachability<'p, 'tcx>(
445446 pat : & ' p DeconstructedPat < ' p , ' tcx > ,
446447 span : Span ,
447448) {
449+ if is_let_chain ( cx. tcx , pat_id) {
450+ return ;
451+ }
452+
448453 let arms = [ MatchArm { pat, hir_id : pat_id, has_guard : false } ] ;
449454 let report = compute_match_usefulness ( & cx, & arms, pat_id, pat. ty ( ) ) ;
450455
@@ -764,8 +769,11 @@ pub enum LetSource {
764769
765770fn let_source ( tcx : TyCtxt < ' _ > , pat_id : HirId ) -> LetSource {
766771 let hir = tcx. hir ( ) ;
772+
767773 let parent = hir. get_parent_node ( pat_id) ;
768- match hir. get ( parent) {
774+ let parent_node = hir. get ( parent) ;
775+
776+ match parent_node {
769777 hir:: Node :: Arm ( hir:: Arm {
770778 guard : Some ( hir:: Guard :: IfLet ( & hir:: Pat { hir_id, .. } , _) ) ,
771779 ..
@@ -780,6 +788,7 @@ fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
780788 }
781789 _ => { }
782790 }
791+
783792 let parent_parent = hir. get_parent_node ( parent) ;
784793 let parent_parent_node = hir. get ( parent_parent) ;
785794
@@ -792,12 +801,30 @@ fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
792801 ..
793802 } ) = parent_parent_parent_parent_node
794803 {
795- LetSource :: WhileLet
796- } else if let hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: If { .. } , .. } ) =
797- parent_parent_node
798- {
799- LetSource :: IfLet
800- } else {
801- LetSource :: GenericLet
804+ return LetSource :: WhileLet ;
805+ }
806+
807+ if let hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: If ( ..) , .. } ) = parent_parent_node {
808+ return LetSource :: IfLet ;
802809 }
810+
811+ LetSource :: GenericLet
812+ }
813+
814+ // Since this function is called within a let context, it is reasonable to assume that any parent
815+ // `&&` infers a let chain
816+ fn is_let_chain ( tcx : TyCtxt < ' _ > , pat_id : HirId ) -> bool {
817+ let hir = tcx. hir ( ) ;
818+ let parent = hir. get_parent_node ( pat_id) ;
819+ let parent_parent = hir. get_parent_node ( parent) ;
820+ matches ! (
821+ hir. get( parent_parent) ,
822+ hir:: Node :: Expr (
823+ hir:: Expr {
824+ kind: hir:: ExprKind :: Binary ( Spanned { node: hir:: BinOpKind :: And , .. } , ..) ,
825+ ..
826+ } ,
827+ ..
828+ )
829+ )
803830}
0 commit comments