@@ -17,6 +17,7 @@ use rustc_session::lint::builtin::{
17
17
BINDINGS_WITH_VARIANT_NAME , IRREFUTABLE_LET_PATTERNS , UNREACHABLE_PATTERNS ,
18
18
} ;
19
19
use rustc_session:: Session ;
20
+ use rustc_span:: source_map:: Spanned ;
20
21
use rustc_span:: { DesugaringKind , ExpnKind , Span } ;
21
22
22
23
crate fn check_match ( tcx : TyCtxt < ' _ > , def_id : DefId ) {
@@ -445,6 +446,10 @@ fn check_let_reachability<'p, 'tcx>(
445
446
pat : & ' p DeconstructedPat < ' p , ' tcx > ,
446
447
span : Span ,
447
448
) {
449
+ if is_let_chain ( cx. tcx , pat_id) {
450
+ return ;
451
+ }
452
+
448
453
let arms = [ MatchArm { pat, hir_id : pat_id, has_guard : false } ] ;
449
454
let report = compute_match_usefulness ( & cx, & arms, pat_id, pat. ty ( ) ) ;
450
455
@@ -764,8 +769,11 @@ pub enum LetSource {
764
769
765
770
fn let_source ( tcx : TyCtxt < ' _ > , pat_id : HirId ) -> LetSource {
766
771
let hir = tcx. hir ( ) ;
772
+
767
773
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 {
769
777
hir:: Node :: Arm ( hir:: Arm {
770
778
guard : Some ( hir:: Guard :: IfLet ( & hir:: Pat { hir_id, .. } , _) ) ,
771
779
..
@@ -780,6 +788,7 @@ fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
780
788
}
781
789
_ => { }
782
790
}
791
+
783
792
let parent_parent = hir. get_parent_node ( parent) ;
784
793
let parent_parent_node = hir. get ( parent_parent) ;
785
794
@@ -792,12 +801,30 @@ fn let_source(tcx: TyCtxt<'_>, pat_id: HirId) -> LetSource {
792
801
..
793
802
} ) = parent_parent_parent_parent_node
794
803
{
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 ;
802
809
}
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
+ )
803
830
}
0 commit comments