@@ -168,9 +168,9 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> {
168168 {
169169 let mut chain_refutabilities = Vec :: new ( ) ;
170170 let Ok ( ( ) ) = self . visit_land ( ex, & mut chain_refutabilities) else { return } ;
171- // If at least one of the operands is a ` let ... = ...`.
172- if chain_refutabilities . iter ( ) . any ( |x| x . is_some ( ) ) {
173- self . check_let_chain ( chain_refutabilities , ex. span ) ;
171+ // Check only single let binding
172+ if let [ Some ( ( _ , refutability ) ) ] = chain_refutabilities [ .. ] {
173+ self . check_single_let ( refutability , ex. span ) ;
174174 }
175175 return ;
176176 }
@@ -562,73 +562,16 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
562562 }
563563
564564 #[ instrument( level = "trace" , skip( self ) ) ]
565- fn check_let_chain (
566- & mut self ,
567- chain_refutabilities : Vec < Option < ( Span , RefutableFlag ) > > ,
568- whole_chain_span : Span ,
569- ) {
565+ fn check_single_let ( & mut self , refutability : RefutableFlag , whole_chain_span : Span ) {
570566 assert ! ( self . let_source != LetSource :: None ) ;
571-
572- if chain_refutabilities. iter ( ) . all ( |r| matches ! ( * r, Some ( ( _, Irrefutable ) ) ) ) {
573- // The entire chain is made up of irrefutable `let` statements
567+ if matches ! ( refutability, Irrefutable ) {
574568 report_irrefutable_let_patterns (
575569 self . tcx ,
576570 self . lint_level ,
577571 self . let_source ,
578- chain_refutabilities . len ( ) ,
572+ 1 ,
579573 whole_chain_span,
580574 ) ;
581- return ;
582- }
583-
584- if let Some ( until) =
585- chain_refutabilities. iter ( ) . position ( |r| !matches ! ( * r, Some ( ( _, Irrefutable ) ) ) )
586- && until > 0
587- {
588- // The chain has a non-zero prefix of irrefutable `let` statements.
589-
590- // Check if the let source is while, for there is no alternative place to put a prefix,
591- // and we shouldn't lint.
592- // For let guards inside a match, prefixes might use bindings of the match pattern,
593- // so can't always be moved out.
594- // For `else if let`, an extra indentation level would be required to move the bindings.
595- // FIXME: Add checking whether the bindings are actually used in the prefix,
596- // and lint if they are not.
597- if !matches ! (
598- self . let_source,
599- LetSource :: WhileLet | LetSource :: IfLetGuard | LetSource :: ElseIfLet
600- ) {
601- // Emit the lint
602- let prefix = & chain_refutabilities[ ..until] ;
603- let span_start = prefix[ 0 ] . unwrap ( ) . 0 ;
604- let span_end = prefix. last ( ) . unwrap ( ) . unwrap ( ) . 0 ;
605- let span = span_start. to ( span_end) ;
606- let count = prefix. len ( ) ;
607- self . tcx . emit_node_span_lint (
608- IRREFUTABLE_LET_PATTERNS ,
609- self . lint_level ,
610- span,
611- LeadingIrrefutableLetPatterns { count } ,
612- ) ;
613- }
614- }
615-
616- if let Some ( from) =
617- chain_refutabilities. iter ( ) . rposition ( |r| !matches ! ( * r, Some ( ( _, Irrefutable ) ) ) )
618- && from != ( chain_refutabilities. len ( ) - 1 )
619- {
620- // The chain has a non-empty suffix of irrefutable `let` statements
621- let suffix = & chain_refutabilities[ from + 1 ..] ;
622- let span_start = suffix[ 0 ] . unwrap ( ) . 0 ;
623- let span_end = suffix. last ( ) . unwrap ( ) . unwrap ( ) . 0 ;
624- let span = span_start. to ( span_end) ;
625- let count = suffix. len ( ) ;
626- self . tcx . emit_node_span_lint (
627- IRREFUTABLE_LET_PATTERNS ,
628- self . lint_level ,
629- span,
630- TrailingIrrefutableLetPatterns { count } ,
631- ) ;
632575 }
633576 }
634577
0 commit comments