@@ -1179,7 +1179,7 @@ impl<'a> Parser<'a> {
11791179 let lo = self . span . lo ;
11801180
11811181 let ( name, node) = if self . eat_keyword ( keywords:: Type ) {
1182- let TyParam { ident, bounds, default, ..} = self . parse_ty_param ( ) ?;
1182+ let TyParam { ident, bounds, default, ..} = self . parse_ty_param ( vec ! [ ] ) ?;
11831183 self . expect ( & token:: Semi ) ?;
11841184 ( ident, TraitItemKind :: Type ( bounds, default) )
11851185 } else if self . is_const_item ( ) {
@@ -1910,10 +1910,22 @@ impl<'a> Parser<'a> {
19101910
19111911 /// Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]` where `lifetime_def =
19121912 /// lifetime [':' lifetimes]`
1913- pub fn parse_lifetime_defs ( & mut self ) -> PResult < ' a , Vec < ast:: LifetimeDef > > {
1914-
1913+ ///
1914+ /// If `followed_by_ty_params` is None, then we are in a context
1915+ /// where only lifetime parameters are allowed, and thus we should
1916+ /// error if we encounter attributes after the bound lifetimes.
1917+ ///
1918+ /// If `followed_by_ty_params` is Some(r), then there may be type
1919+ /// parameter bindings after the lifetimes, so we should pass
1920+ /// along the parsed attributes to be attached to the first such
1921+ /// type parmeter.
1922+ pub fn parse_lifetime_defs ( & mut self ,
1923+ followed_by_ty_params : Option < & mut Vec < ast:: Attribute > > )
1924+ -> PResult < ' a , Vec < ast:: LifetimeDef > >
1925+ {
19151926 let mut res = Vec :: new ( ) ;
19161927 loop {
1928+ let attrs = self . parse_outer_attributes ( ) ?;
19171929 match self . token {
19181930 token:: Lifetime ( _) => {
19191931 let lifetime = self . parse_lifetime ( ) ?;
@@ -1923,11 +1935,20 @@ impl<'a> Parser<'a> {
19231935 } else {
19241936 Vec :: new ( )
19251937 } ;
1926- res. push ( ast:: LifetimeDef { lifetime : lifetime,
1938+ res. push ( ast:: LifetimeDef { attrs : attrs. into ( ) ,
1939+ lifetime : lifetime,
19271940 bounds : bounds } ) ;
19281941 }
19291942
19301943 _ => {
1944+ if let Some ( recv) = followed_by_ty_params {
1945+ assert ! ( recv. is_empty( ) ) ;
1946+ * recv = attrs;
1947+ } else {
1948+ let msg = "trailing attribute after lifetime parameters" ;
1949+ return Err ( self . fatal ( msg) ) ;
1950+ }
1951+ debug ! ( "parse_lifetime_defs ret {:?}" , res) ;
19311952 return Ok ( res) ;
19321953 }
19331954 }
@@ -4228,7 +4249,7 @@ impl<'a> Parser<'a> {
42284249 }
42294250
42304251 /// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
4231- fn parse_ty_param ( & mut self ) -> PResult < ' a , TyParam > {
4252+ fn parse_ty_param ( & mut self , preceding_attrs : Vec < ast :: Attribute > ) -> PResult < ' a , TyParam > {
42324253 let span = self . span ;
42334254 let ident = self . parse_ident ( ) ?;
42344255
@@ -4242,6 +4263,7 @@ impl<'a> Parser<'a> {
42424263 } ;
42434264
42444265 Ok ( TyParam {
4266+ attrs : preceding_attrs. into ( ) ,
42454267 ident : ident,
42464268 id : ast:: DUMMY_NODE_ID ,
42474269 bounds : bounds,
@@ -4262,11 +4284,27 @@ impl<'a> Parser<'a> {
42624284 let span_lo = self . span . lo ;
42634285
42644286 if self . eat ( & token:: Lt ) {
4265- let lifetime_defs = self . parse_lifetime_defs ( ) ?;
4287+ // Upon encountering attribute in generics list, we do not
4288+ // know if it is attached to lifetime or to type param.
4289+ //
4290+ // Solution: 1. eagerly parse attributes in tandem with
4291+ // lifetime defs, 2. store last set of parsed (and unused)
4292+ // attributes in `attrs`, and 3. pass in those attributes
4293+ // when parsing formal type param after lifetime defs.
4294+ let mut attrs = vec ! [ ] ;
4295+ let lifetime_defs = self . parse_lifetime_defs ( Some ( & mut attrs) ) ?;
42664296 let mut seen_default = false ;
4297+ let mut post_lifetime_attrs = Some ( attrs) ;
42674298 let ty_params = self . parse_seq_to_gt ( Some ( token:: Comma ) , |p| {
42684299 p. forbid_lifetime ( ) ?;
4269- let ty_param = p. parse_ty_param ( ) ?;
4300+ // Move out of `post_lifetime_attrs` if present. O/w
4301+ // not first type param: parse attributes anew.
4302+ let attrs = match post_lifetime_attrs. as_mut ( ) {
4303+ None => p. parse_outer_attributes ( ) ?,
4304+ Some ( attrs) => mem:: replace ( attrs, vec ! [ ] ) ,
4305+ } ;
4306+ post_lifetime_attrs = None ;
4307+ let ty_param = p. parse_ty_param ( attrs) ?;
42704308 if ty_param. default . is_some ( ) {
42714309 seen_default = true ;
42724310 } else if seen_default {
@@ -4276,6 +4314,12 @@ impl<'a> Parser<'a> {
42764314 }
42774315 Ok ( ty_param)
42784316 } ) ?;
4317+ if let Some ( attrs) = post_lifetime_attrs {
4318+ if !attrs. is_empty ( ) {
4319+ self . span_err ( attrs[ 0 ] . span ,
4320+ "trailing attribute after lifetime parameters" ) ;
4321+ }
4322+ }
42794323 Ok ( ast:: Generics {
42804324 lifetimes : lifetime_defs,
42814325 ty_params : ty_params,
@@ -4423,7 +4467,7 @@ impl<'a> Parser<'a> {
44234467 let bound_lifetimes = if self . eat_keyword ( keywords:: For ) {
44244468 // Higher ranked constraint.
44254469 self . expect ( & token:: Lt ) ?;
4426- let lifetime_defs = self . parse_lifetime_defs ( ) ?;
4470+ let lifetime_defs = self . parse_lifetime_defs ( None ) ?;
44274471 self . expect_gt ( ) ?;
44284472 lifetime_defs
44294473 } else {
@@ -4991,7 +5035,7 @@ impl<'a> Parser<'a> {
49915035 fn parse_late_bound_lifetime_defs ( & mut self ) -> PResult < ' a , Vec < ast:: LifetimeDef > > {
49925036 if self . eat_keyword ( keywords:: For ) {
49935037 self . expect ( & token:: Lt ) ?;
4994- let lifetime_defs = self . parse_lifetime_defs ( ) ?;
5038+ let lifetime_defs = self . parse_lifetime_defs ( None ) ?;
49955039 self . expect_gt ( ) ?;
49965040 Ok ( lifetime_defs)
49975041 } else {
0 commit comments