@@ -18,7 +18,7 @@ use rustc_ast::{
1818} ;
1919use rustc_errors:: { Applicability , PResult } ;
2020use rustc_span:: symbol:: { kw, sym, Ident } ;
21- use rustc_span:: { Span , Symbol } ;
21+ use rustc_span:: { ErrorGuaranteed , Span , Symbol } ;
2222use thin_vec:: { thin_vec, ThinVec } ;
2323
2424#[ derive( Copy , Clone , PartialEq ) ]
@@ -280,7 +280,7 @@ impl<'a> Parser<'a> {
280280 // Function pointer type or bound list (trait object type) starting with a poly-trait.
281281 // `for<'lt> [unsafe] [extern "ABI"] fn (&'lt S) -> T`
282282 // `for<'lt> Trait1<'lt> + Trait2 + 'a`
283- let lifetime_defs = self . parse_late_bound_lifetime_defs ( ) ?;
283+ let ( lifetime_defs, _ ) = self . parse_late_bound_lifetime_defs ( ) ?;
284284 if self . check_fn_front_matter ( false , Case :: Sensitive ) {
285285 self . parse_ty_bare_fn (
286286 lo,
@@ -833,12 +833,9 @@ impl<'a> Parser<'a> {
833833 let lo = self . token . span ;
834834 let leading_token = self . prev_token . clone ( ) ;
835835 let has_parens = self . eat ( & token:: OpenDelim ( Delimiter :: Parenthesis ) ) ;
836- let inner_lo = self . token . span ;
837836
838- let modifiers = self . parse_trait_bound_modifiers ( ) ?;
839837 let bound = if self . token . is_lifetime ( ) {
840- self . error_lt_bound_with_modifiers ( modifiers) ;
841- self . parse_generic_lt_bound ( lo, inner_lo, has_parens) ?
838+ self . parse_generic_lt_bound ( lo, has_parens) ?
842839 } else if self . eat_keyword ( kw:: Use ) {
843840 // parse precise captures, if any. This is `use<'lt, 'lt, P, P>`; a list of
844841 // lifetimes and ident params (including SelfUpper). These are validated later
@@ -848,7 +845,7 @@ impl<'a> Parser<'a> {
848845 let ( args, args_span) = self . parse_precise_capturing_args ( ) ?;
849846 GenericBound :: Use ( args, use_span. to ( args_span) )
850847 } else {
851- self . parse_generic_ty_bound ( lo, has_parens, modifiers , & leading_token) ?
848+ self . parse_generic_ty_bound ( lo, has_parens, & leading_token) ?
852849 } ;
853850
854851 Ok ( bound)
@@ -858,50 +855,64 @@ impl<'a> Parser<'a> {
858855 /// ```ebnf
859856 /// LT_BOUND = LIFETIME
860857 /// ```
861- fn parse_generic_lt_bound (
862- & mut self ,
863- lo : Span ,
864- inner_lo : Span ,
865- has_parens : bool ,
866- ) -> PResult < ' a , GenericBound > {
867- let bound = GenericBound :: Outlives ( self . expect_lifetime ( ) ) ;
858+ fn parse_generic_lt_bound ( & mut self , lo : Span , has_parens : bool ) -> PResult < ' a , GenericBound > {
859+ let lt = self . expect_lifetime ( ) ;
860+ let bound = GenericBound :: Outlives ( lt) ;
868861 if has_parens {
869862 // FIXME(Centril): Consider not erroring here and accepting `('lt)` instead,
870863 // possibly introducing `GenericBound::Paren(P<GenericBound>)`?
871- self . recover_paren_lifetime ( lo, inner_lo ) ?;
864+ self . recover_paren_lifetime ( lo, lt . ident . span ) ?;
872865 }
873866 Ok ( bound)
874867 }
875868
876869 /// Emits an error if any trait bound modifiers were present.
877- fn error_lt_bound_with_modifiers ( & self , modifiers : TraitBoundModifiers ) {
878- match modifiers. constness {
870+ fn error_lt_bound_with_modifiers (
871+ & self ,
872+ modifiers : TraitBoundModifiers ,
873+ binder_span : Option < Span > ,
874+ ) -> ErrorGuaranteed {
875+ let TraitBoundModifiers { constness, asyncness, polarity } = modifiers;
876+
877+ match constness {
879878 BoundConstness :: Never => { }
880879 BoundConstness :: Always ( span) | BoundConstness :: Maybe ( span) => {
881- self . dcx ( ) . emit_err ( errors:: ModifierLifetime {
882- span,
883- modifier : modifiers. constness . as_str ( ) ,
884- } ) ;
880+ return self
881+ . dcx ( )
882+ . emit_err ( errors:: ModifierLifetime { span, modifier : constness. as_str ( ) } ) ;
885883 }
886884 }
887885
888- match modifiers . polarity {
886+ match polarity {
889887 BoundPolarity :: Positive => { }
890888 BoundPolarity :: Negative ( span) | BoundPolarity :: Maybe ( span) => {
891- self . dcx ( ) . emit_err ( errors:: ModifierLifetime {
892- span,
893- modifier : modifiers. polarity . as_str ( ) ,
894- } ) ;
889+ return self
890+ . dcx ( )
891+ . emit_err ( errors:: ModifierLifetime { span, modifier : polarity. as_str ( ) } ) ;
892+ }
893+ }
894+
895+ match asyncness {
896+ BoundAsyncness :: Normal => { }
897+ BoundAsyncness :: Async ( span) => {
898+ return self
899+ . dcx ( )
900+ . emit_err ( errors:: ModifierLifetime { span, modifier : asyncness. as_str ( ) } ) ;
895901 }
896902 }
903+
904+ if let Some ( span) = binder_span {
905+ return self . dcx ( ) . emit_err ( errors:: ModifierLifetime { span, modifier : "for<...>" } ) ;
906+ }
907+
908+ unreachable ! ( "lifetime bound intercepted in `parse_generic_ty_bound` but no modifiers?" )
897909 }
898910
899911 /// Recover on `('lifetime)` with `(` already eaten.
900- fn recover_paren_lifetime ( & mut self , lo : Span , inner_lo : Span ) -> PResult < ' a , ( ) > {
901- let inner_span = inner_lo. to ( self . prev_token . span ) ;
912+ fn recover_paren_lifetime ( & mut self , lo : Span , lt_span : Span ) -> PResult < ' a , ( ) > {
902913 self . expect ( & token:: CloseDelim ( Delimiter :: Parenthesis ) ) ?;
903914 let span = lo. to ( self . prev_token . span ) ;
904- let ( sugg, snippet) = if let Ok ( snippet) = self . span_to_snippet ( inner_span ) {
915+ let ( sugg, snippet) = if let Ok ( snippet) = self . span_to_snippet ( lt_span ) {
905916 ( Some ( span) , snippet)
906917 } else {
907918 ( None , String :: new ( ) )
@@ -970,15 +981,31 @@ impl<'a> Parser<'a> {
970981 /// TY_BOUND_NOPAREN = [TRAIT_BOUND_MODIFIERS] [for<LT_PARAM_DEFS>] SIMPLE_PATH
971982 /// ```
972983 ///
973- /// For example, this grammar accepts `~const ? for<'a: 'b> m::Trait<'a>`.
984+ /// For example, this grammar accepts `for<'a: 'b> ~const ? m::Trait<'a>`.
974985 fn parse_generic_ty_bound (
975986 & mut self ,
976987 lo : Span ,
977988 has_parens : bool ,
978- modifiers : TraitBoundModifiers ,
979989 leading_token : & Token ,
980990 ) -> PResult < ' a , GenericBound > {
981- let mut lifetime_defs = self . parse_late_bound_lifetime_defs ( ) ?;
991+ let ( mut lifetime_defs, binder_span) = self . parse_late_bound_lifetime_defs ( ) ?;
992+
993+ let modifiers_lo = self . token . span ;
994+ let modifiers = self . parse_trait_bound_modifiers ( ) ?;
995+ let modifiers_span = modifiers_lo. to ( self . prev_token . span ) ;
996+
997+ // Recover erroneous lifetime bound with modifiers or binder.
998+ // e.g. `T: for<'a> 'a` or `T: ~const 'a`.
999+ if self . token . is_lifetime ( ) {
1000+ let _: ErrorGuaranteed = self . error_lt_bound_with_modifiers ( modifiers, binder_span) ;
1001+ return self . parse_generic_lt_bound ( lo, has_parens) ;
1002+ }
1003+
1004+ if let ( more_lifetime_defs, Some ( binder_span) ) = self . parse_late_bound_lifetime_defs ( ) ? {
1005+ lifetime_defs. extend ( more_lifetime_defs) ;
1006+ self . dcx ( ) . emit_err ( errors:: BinderBeforeModifiers { binder_span, modifiers_span } ) ;
1007+ }
1008+
9821009 let mut path = if self . token . is_keyword ( kw:: Fn )
9831010 && self . look_ahead ( 1 , |tok| tok. kind == TokenKind :: OpenDelim ( Delimiter :: Parenthesis ) )
9841011 && let Some ( path) = self . recover_path_from_fn ( )
@@ -1094,16 +1121,19 @@ impl<'a> Parser<'a> {
10941121 }
10951122
10961123 /// Optionally parses `for<$generic_params>`.
1097- pub ( super ) fn parse_late_bound_lifetime_defs ( & mut self ) -> PResult < ' a , ThinVec < GenericParam > > {
1124+ pub ( super ) fn parse_late_bound_lifetime_defs (
1125+ & mut self ,
1126+ ) -> PResult < ' a , ( ThinVec < GenericParam > , Option < Span > ) > {
10981127 if self . eat_keyword ( kw:: For ) {
1128+ let lo = self . token . span ;
10991129 self . expect_lt ( ) ?;
11001130 let params = self . parse_generic_params ( ) ?;
11011131 self . expect_gt ( ) ?;
1102- // We rely on AST validation to rule out invalid cases: There must not be type
1103- // parameters, and the lifetime parameters must not have bounds.
1104- Ok ( params)
1132+ // We rely on AST validation to rule out invalid cases: There must not be
1133+ // type or const parameters, and parameters must not have bounds.
1134+ Ok ( ( params, Some ( lo . to ( self . prev_token . span ) ) ) )
11051135 } else {
1106- Ok ( ThinVec :: new ( ) )
1136+ Ok ( ( ThinVec :: new ( ) , None ) )
11071137 }
11081138 }
11091139
0 commit comments