1
1
use super :: { ForceCollect , Parser , PathStyle , TrailingToken } ;
2
2
use crate :: errors:: {
3
- AmbiguousRangePattern , BoxNotPat , DotDotDotForRemainingFields ,
4
- DotDotDotRangeToPatternNotAllowed , DotDotDotRestPattern , EnumPatternInsteadOfIdentifier ,
5
- ExpectedBindingLeftOfAt , ExpectedCommaAfterPatternField ,
6
- GenericArgsInPatRequireTurbofishSyntax , InclusiveRangeExtraEquals , InclusiveRangeMatchArrow ,
7
- InclusiveRangeNoEnd , InvalidMutInPattern , PatternOnWrongSideOfAt , RefMutOrderIncorrect ,
8
- RemoveLet , RepeatedMutInPattern , SwitchRefBoxOrder , TopLevelOrPatternNotAllowed ,
9
- TopLevelOrPatternNotAllowedSugg , TrailingVertNotAllowed , UnexpectedLifetimeInPattern ,
10
- UnexpectedParenInRangePat , UnexpectedParenInRangePatSugg ,
11
- UnexpectedVertVertBeforeFunctionParam , UnexpectedVertVertInPattern ,
3
+ self , AmbiguousRangePattern , DotDotDotForRemainingFields , DotDotDotRangeToPatternNotAllowed ,
4
+ DotDotDotRestPattern , EnumPatternInsteadOfIdentifier , ExpectedBindingLeftOfAt ,
5
+ ExpectedCommaAfterPatternField , GenericArgsInPatRequireTurbofishSyntax ,
6
+ InclusiveRangeExtraEquals , InclusiveRangeMatchArrow , InclusiveRangeNoEnd , InvalidMutInPattern ,
7
+ PatternOnWrongSideOfAt , RefMutOrderIncorrect , RemoveLet , RepeatedMutInPattern ,
8
+ SwitchRefBoxOrder , TopLevelOrPatternNotAllowed , TopLevelOrPatternNotAllowedSugg ,
9
+ TrailingVertNotAllowed , UnexpectedLifetimeInPattern , UnexpectedParenInRangePat ,
10
+ UnexpectedParenInRangePatSugg , UnexpectedVertVertBeforeFunctionParam ,
11
+ UnexpectedVertVertInPattern ,
12
12
} ;
13
13
use crate :: { maybe_recover_from_interpolated_ty_qpath, maybe_whole} ;
14
14
use rustc_ast:: mut_visit:: { noop_visit_pat, MutVisitor } ;
@@ -19,7 +19,7 @@ use rustc_ast::{
19
19
PatField , PatFieldsRest , PatKind , Path , QSelf , RangeEnd , RangeSyntax ,
20
20
} ;
21
21
use rustc_ast_pretty:: pprust;
22
- use rustc_errors:: { Applicability , DiagnosticBuilder , MultiSpan , PResult } ;
22
+ use rustc_errors:: { Applicability , DiagnosticBuilder , PResult } ;
23
23
use rustc_session:: errors:: ExprParenthesesNeeded ;
24
24
use rustc_span:: source_map:: { respan, Spanned } ;
25
25
use rustc_span:: symbol:: { kw, sym, Ident } ;
@@ -604,7 +604,7 @@ impl<'a> Parser<'a> {
604
604
&& let Some ( form) = self . parse_range_end ( ) =>
605
605
{
606
606
self . dcx ( ) . emit_err ( UnexpectedParenInRangePat {
607
- span : MultiSpan :: from_spans ( vec ! [ open_paren, close_paren] ) ,
607
+ span : vec ! [ open_paren, close_paren] ,
608
608
sugg : UnexpectedParenInRangePatSugg {
609
609
start_span : open_paren,
610
610
end_span : close_paren,
@@ -752,14 +752,6 @@ impl<'a> Parser<'a> {
752
752
begin : P < Expr > ,
753
753
re : Spanned < RangeEnd > ,
754
754
) -> PResult < ' a , PatKind > {
755
- // recover from `(`
756
- let open_paren = ( self . may_recover ( )
757
- && self . token . kind == token:: OpenDelim ( Delimiter :: Parenthesis ) )
758
- . then ( || {
759
- self . bump ( ) ;
760
- self . prev_token . span
761
- } ) ;
762
-
763
755
let end = if self . is_pat_range_end_start ( 0 ) {
764
756
// Parsing e.g. `X..=Y`.
765
757
Some ( self . parse_pat_range_end ( ) ?)
@@ -771,19 +763,6 @@ impl<'a> Parser<'a> {
771
763
}
772
764
None
773
765
} ;
774
-
775
- if let Some ( span) = open_paren {
776
- self . expect ( & token:: CloseDelim ( Delimiter :: Parenthesis ) ) ?;
777
-
778
- self . dcx ( ) . emit_err ( UnexpectedParenInRangePat {
779
- span : MultiSpan :: from_spans ( vec ! [ span, self . prev_token. span] ) ,
780
- sugg : UnexpectedParenInRangePatSugg {
781
- start_span : span,
782
- end_span : self . prev_token . span ,
783
- } ,
784
- } ) ;
785
- }
786
-
787
766
Ok ( PatKind :: Range ( Some ( begin) , end, re) )
788
767
}
789
768
@@ -823,32 +802,11 @@ impl<'a> Parser<'a> {
823
802
/// The form `...X` is prohibited to reduce confusion with the potential
824
803
/// expression syntax `...expr` for splatting in expressions.
825
804
fn parse_pat_range_to ( & mut self , mut re : Spanned < RangeEnd > ) -> PResult < ' a , PatKind > {
826
- // recover from `(`
827
- let open_paren = ( self . may_recover ( )
828
- && self . token . kind == token:: OpenDelim ( Delimiter :: Parenthesis ) )
829
- . then ( || {
830
- self . bump ( ) ;
831
- self . prev_token . span
832
- } ) ;
833
-
834
805
let end = self . parse_pat_range_end ( ) ?;
835
806
if let RangeEnd :: Included ( syn @ RangeSyntax :: DotDotDot ) = & mut re. node {
836
807
* syn = RangeSyntax :: DotDotEq ;
837
808
self . dcx ( ) . emit_err ( DotDotDotRangeToPatternNotAllowed { span : re. span } ) ;
838
809
}
839
-
840
- if let Some ( span) = open_paren {
841
- self . expect ( & token:: CloseDelim ( Delimiter :: Parenthesis ) ) ?;
842
-
843
- self . dcx ( ) . emit_err ( UnexpectedParenInRangePat {
844
- span : MultiSpan :: from_spans ( vec ! [ span, self . prev_token. span] ) ,
845
- sugg : UnexpectedParenInRangePatSugg {
846
- start_span : span,
847
- end_span : self . prev_token . span ,
848
- } ,
849
- } ) ;
850
- }
851
-
852
810
Ok ( PatKind :: Range ( None , Some ( end) , re) )
853
811
}
854
812
@@ -868,8 +826,14 @@ impl<'a> Parser<'a> {
868
826
} )
869
827
}
870
828
829
+ /// Parse a range pattern end bound
871
830
fn parse_pat_range_end ( & mut self ) -> PResult < ' a , P < Expr > > {
872
- if self . check_inline_const ( 0 ) {
831
+ // recover leading `(`
832
+ let open_paren = ( self . may_recover ( )
833
+ && self . eat_noexpect ( & token:: OpenDelim ( Delimiter :: Parenthesis ) ) )
834
+ . then_some ( self . prev_token . span ) ;
835
+
836
+ let bound = if self . check_inline_const ( 0 ) {
873
837
self . parse_const_block ( self . token . span , true )
874
838
} else if self . check_path ( ) {
875
839
let lo = self . token . span ;
@@ -885,6 +849,32 @@ impl<'a> Parser<'a> {
885
849
Ok ( self . mk_expr ( lo. to ( hi) , ExprKind :: Path ( qself, path) ) )
886
850
} else {
887
851
self . parse_literal_maybe_minus ( )
852
+ } ;
853
+
854
+ // recover trailing `)`
855
+ if let Some ( open_paren) = open_paren {
856
+ let bound = bound. map_err ( |err| {
857
+ // we couldn't parse a bound after the `(`, so cancel the recovery
858
+ err. cancel ( ) ;
859
+ self . dcx ( ) . struct_span_err ( open_paren, "unexpected token: `(`" )
860
+ } ) ?;
861
+
862
+ if self . eat_noexpect ( & token:: CloseDelim ( Delimiter :: Parenthesis ) ) {
863
+ self . dcx ( ) . emit_err ( UnexpectedParenInRangePat {
864
+ span : vec ! [ open_paren, self . prev_token. span] ,
865
+ sugg : UnexpectedParenInRangePatSugg {
866
+ start_span : open_paren,
867
+ end_span : self . prev_token . span ,
868
+ } ,
869
+ } ) ;
870
+
871
+ Ok ( bound)
872
+ } else {
873
+ // the `(bound` is missing its closing `)`, so cancel the recovery
874
+ Err ( self . dcx ( ) . struct_span_err ( open_paren, "unexpected token: `(`" ) )
875
+ }
876
+ } else {
877
+ bound
888
878
}
889
879
}
890
880
@@ -1013,7 +1003,7 @@ impl<'a> Parser<'a> {
1013
1003
1014
1004
if self . isnt_pattern_start ( ) {
1015
1005
let descr = super :: token_descr ( & self . token ) ;
1016
- self . dcx ( ) . emit_err ( BoxNotPat {
1006
+ self . dcx ( ) . emit_err ( errors :: BoxNotPat {
1017
1007
span : self . token . span ,
1018
1008
kw : box_span,
1019
1009
lo : box_span. shrink_to_lo ( ) ,
0 commit comments