@@ -2852,19 +2852,23 @@ impl<'a> LoweringContext<'a> {
28522852 let mut rest = None ;
28532853
28542854 let mut iter = pats. iter ( ) . enumerate ( ) ;
2855- while let Some ( ( idx, pat) ) = iter. next ( ) {
2856- // Interpret the first `..` pattern as a subtuple pattern.
2855+ for ( idx, pat) in iter. by_ref ( ) {
2856+ // Interpret the first `..` pattern as a sub-tuple pattern.
2857+ // Note that unlike for slice patterns,
2858+ // where `xs @ ..` is a legal sub-slice pattern,
2859+ // it is not a legal sub-tuple pattern.
28572860 if pat. is_rest ( ) {
28582861 rest = Some ( ( idx, pat. span ) ) ;
28592862 break ;
28602863 }
2861- // It was not a subslice pattern so lower it normally.
2864+ // It was not a sub-tuple pattern so lower it normally.
28622865 elems. push ( self . lower_pat ( pat) ) ;
28632866 }
28642867
2865- while let Some ( ( _, pat) ) = iter. next ( ) {
2866- // There was a previous subtuple pattern; make sure we don't allow more.
2868+ for ( _, pat) in iter {
2869+ // There was a previous sub-tuple pattern; make sure we don't allow more.. .
28672870 if pat. is_rest ( ) {
2871+ // ...but there was one again, so error.
28682872 self . ban_extra_rest_pat ( pat. span , rest. unwrap ( ) . 1 , ctx) ;
28692873 } else {
28702874 elems. push ( self . lower_pat ( pat) ) ;
@@ -2874,36 +2878,44 @@ impl<'a> LoweringContext<'a> {
28742878 ( elems. into ( ) , rest. map ( |( ddpos, _) | ddpos) )
28752879 }
28762880
2881+ /// Lower a slice pattern of form `[pat_0, ..., pat_n]` into
2882+ /// `hir::PatKind::Slice(before, slice, after)`.
2883+ ///
2884+ /// When encountering `($binding_mode $ident @)? ..` (`slice`),
2885+ /// this is interpreted as a sub-slice pattern semantically.
2886+ /// Patterns that follow, which are not like `slice` -- or an error occurs, are in `after`.
28772887 fn lower_pat_slice ( & mut self , pats : & [ AstP < Pat > ] ) -> hir:: PatKind {
28782888 let mut before = Vec :: new ( ) ;
28792889 let mut after = Vec :: new ( ) ;
28802890 let mut slice = None ;
28812891 let mut prev_rest_span = None ;
28822892
28832893 let mut iter = pats. iter ( ) ;
2884- while let Some ( pat ) = iter . next ( ) {
2885- // Interpret the first `((ref mut?)? x @)? ..` pattern as a subslice pattern.
2894+ // Lower all the patterns until the first occurence of a sub-slice pattern.
2895+ for pat in iter . by_ref ( ) {
28862896 match pat. kind {
2897+ // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here.
28872898 PatKind :: Rest => {
28882899 prev_rest_span = Some ( pat. span ) ;
28892900 slice = Some ( self . pat_wild_with_node_id_of ( pat) ) ;
28902901 break ;
28912902 } ,
2903+ // Found a sub-slice pattern `$binding_mode $ident @ ..`.
2904+ // Record, lower it to `$binding_mode $ident @ _`, and stop here.
28922905 PatKind :: Ident ( ref bm, ident, Some ( ref sub) ) if sub. is_rest ( ) => {
28932906 prev_rest_span = Some ( sub. span ) ;
28942907 let lower_sub = |this : & mut Self | Some ( this. pat_wild_with_node_id_of ( sub) ) ;
28952908 let node = self . lower_pat_ident ( pat, bm, ident, lower_sub) ;
28962909 slice = Some ( self . pat_with_node_id_of ( pat, node) ) ;
28972910 break ;
28982911 } ,
2899- _ => { }
2912+ // It was not a subslice pattern so lower it normally.
2913+ _ => before. push ( self . lower_pat ( pat) ) ,
29002914 }
2901-
2902- // It was not a subslice pattern so lower it normally.
2903- before. push ( self . lower_pat ( pat) ) ;
29042915 }
29052916
2906- while let Some ( pat) = iter. next ( ) {
2917+ // Lower all the patterns after the first sub-slice pattern.
2918+ for pat in iter {
29072919 // There was a previous subslice pattern; make sure we don't allow more.
29082920 let rest_span = match pat. kind {
29092921 PatKind :: Rest => Some ( pat. span ) ,
@@ -2915,8 +2927,10 @@ impl<'a> LoweringContext<'a> {
29152927 _ => None ,
29162928 } ;
29172929 if let Some ( rest_span) = rest_span {
2930+ // We have e.g., `[a, .., b, ..]`. That's no good, error!
29182931 self . ban_extra_rest_pat ( rest_span, prev_rest_span. unwrap ( ) , "slice" ) ;
29192932 } else {
2933+ // Lower the pattern normally.
29202934 after. push ( self . lower_pat ( pat) ) ;
29212935 }
29222936 }
0 commit comments