@@ -2852,19 +2852,23 @@ impl<'a> LoweringContext<'a> {
2852
2852
let mut rest = None ;
2853
2853
2854
2854
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.
2857
2860
if pat. is_rest ( ) {
2858
2861
rest = Some ( ( idx, pat. span ) ) ;
2859
2862
break ;
2860
2863
}
2861
- // It was not a subslice pattern so lower it normally.
2864
+ // It was not a sub-tuple pattern so lower it normally.
2862
2865
elems. push ( self . lower_pat ( pat) ) ;
2863
2866
}
2864
2867
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.. .
2867
2870
if pat. is_rest ( ) {
2871
+ // ...but there was one again, so error.
2868
2872
self . ban_extra_rest_pat ( pat. span , rest. unwrap ( ) . 1 , ctx) ;
2869
2873
} else {
2870
2874
elems. push ( self . lower_pat ( pat) ) ;
@@ -2874,36 +2878,44 @@ impl<'a> LoweringContext<'a> {
2874
2878
( elems. into ( ) , rest. map ( |( ddpos, _) | ddpos) )
2875
2879
}
2876
2880
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`.
2877
2887
fn lower_pat_slice ( & mut self , pats : & [ AstP < Pat > ] ) -> hir:: PatKind {
2878
2888
let mut before = Vec :: new ( ) ;
2879
2889
let mut after = Vec :: new ( ) ;
2880
2890
let mut slice = None ;
2881
2891
let mut prev_rest_span = None ;
2882
2892
2883
2893
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 ( ) {
2886
2896
match pat. kind {
2897
+ // Found a sub-slice pattern `..`. Record, lower it to `_`, and stop here.
2887
2898
PatKind :: Rest => {
2888
2899
prev_rest_span = Some ( pat. span ) ;
2889
2900
slice = Some ( self . pat_wild_with_node_id_of ( pat) ) ;
2890
2901
break ;
2891
2902
} ,
2903
+ // Found a sub-slice pattern `$binding_mode $ident @ ..`.
2904
+ // Record, lower it to `$binding_mode $ident @ _`, and stop here.
2892
2905
PatKind :: Ident ( ref bm, ident, Some ( ref sub) ) if sub. is_rest ( ) => {
2893
2906
prev_rest_span = Some ( sub. span ) ;
2894
2907
let lower_sub = |this : & mut Self | Some ( this. pat_wild_with_node_id_of ( sub) ) ;
2895
2908
let node = self . lower_pat_ident ( pat, bm, ident, lower_sub) ;
2896
2909
slice = Some ( self . pat_with_node_id_of ( pat, node) ) ;
2897
2910
break ;
2898
2911
} ,
2899
- _ => { }
2912
+ // It was not a subslice pattern so lower it normally.
2913
+ _ => before. push ( self . lower_pat ( pat) ) ,
2900
2914
}
2901
-
2902
- // It was not a subslice pattern so lower it normally.
2903
- before. push ( self . lower_pat ( pat) ) ;
2904
2915
}
2905
2916
2906
- while let Some ( pat) = iter. next ( ) {
2917
+ // Lower all the patterns after the first sub-slice pattern.
2918
+ for pat in iter {
2907
2919
// There was a previous subslice pattern; make sure we don't allow more.
2908
2920
let rest_span = match pat. kind {
2909
2921
PatKind :: Rest => Some ( pat. span ) ,
@@ -2915,8 +2927,10 @@ impl<'a> LoweringContext<'a> {
2915
2927
_ => None ,
2916
2928
} ;
2917
2929
if let Some ( rest_span) = rest_span {
2930
+ // We have e.g., `[a, .., b, ..]`. That's no good, error!
2918
2931
self . ban_extra_rest_pat ( rest_span, prev_rest_span. unwrap ( ) , "slice" ) ;
2919
2932
} else {
2933
+ // Lower the pattern normally.
2920
2934
after. push ( self . lower_pat ( pat) ) ;
2921
2935
}
2922
2936
}
0 commit comments