@@ -1179,7 +1179,7 @@ impl<'a> Parser<'a> {
1179
1179
let lo = self . span . lo ;
1180
1180
1181
1181
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 ! [ ] ) ?;
1183
1183
self . expect ( & token:: Semi ) ?;
1184
1184
( ident, TraitItemKind :: Type ( bounds, default) )
1185
1185
} else if self . is_const_item ( ) {
@@ -1910,10 +1910,22 @@ impl<'a> Parser<'a> {
1910
1910
1911
1911
/// Parses `lifetime_defs = [ lifetime_defs { ',' lifetime_defs } ]` where `lifetime_def =
1912
1912
/// 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
+ {
1915
1926
let mut res = Vec :: new ( ) ;
1916
1927
loop {
1928
+ let attrs = self . parse_outer_attributes ( ) ?;
1917
1929
match self . token {
1918
1930
token:: Lifetime ( _) => {
1919
1931
let lifetime = self . parse_lifetime ( ) ?;
@@ -1923,11 +1935,20 @@ impl<'a> Parser<'a> {
1923
1935
} else {
1924
1936
Vec :: new ( )
1925
1937
} ;
1926
- res. push ( ast:: LifetimeDef { lifetime : lifetime,
1938
+ res. push ( ast:: LifetimeDef { attrs : attrs. into ( ) ,
1939
+ lifetime : lifetime,
1927
1940
bounds : bounds } ) ;
1928
1941
}
1929
1942
1930
1943
_ => {
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) ;
1931
1952
return Ok ( res) ;
1932
1953
}
1933
1954
}
@@ -4228,7 +4249,7 @@ impl<'a> Parser<'a> {
4228
4249
}
4229
4250
4230
4251
/// 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 > {
4232
4253
let span = self . span ;
4233
4254
let ident = self . parse_ident ( ) ?;
4234
4255
@@ -4242,6 +4263,7 @@ impl<'a> Parser<'a> {
4242
4263
} ;
4243
4264
4244
4265
Ok ( TyParam {
4266
+ attrs : preceding_attrs. into ( ) ,
4245
4267
ident : ident,
4246
4268
id : ast:: DUMMY_NODE_ID ,
4247
4269
bounds : bounds,
@@ -4262,11 +4284,27 @@ impl<'a> Parser<'a> {
4262
4284
let span_lo = self . span . lo ;
4263
4285
4264
4286
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) ) ?;
4266
4296
let mut seen_default = false ;
4297
+ let mut post_lifetime_attrs = Some ( attrs) ;
4267
4298
let ty_params = self . parse_seq_to_gt ( Some ( token:: Comma ) , |p| {
4268
4299
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) ?;
4270
4308
if ty_param. default . is_some ( ) {
4271
4309
seen_default = true ;
4272
4310
} else if seen_default {
@@ -4276,6 +4314,12 @@ impl<'a> Parser<'a> {
4276
4314
}
4277
4315
Ok ( ty_param)
4278
4316
} ) ?;
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
+ }
4279
4323
Ok ( ast:: Generics {
4280
4324
lifetimes : lifetime_defs,
4281
4325
ty_params : ty_params,
@@ -4423,7 +4467,7 @@ impl<'a> Parser<'a> {
4423
4467
let bound_lifetimes = if self . eat_keyword ( keywords:: For ) {
4424
4468
// Higher ranked constraint.
4425
4469
self . expect ( & token:: Lt ) ?;
4426
- let lifetime_defs = self . parse_lifetime_defs ( ) ?;
4470
+ let lifetime_defs = self . parse_lifetime_defs ( None ) ?;
4427
4471
self . expect_gt ( ) ?;
4428
4472
lifetime_defs
4429
4473
} else {
@@ -4991,7 +5035,7 @@ impl<'a> Parser<'a> {
4991
5035
fn parse_late_bound_lifetime_defs ( & mut self ) -> PResult < ' a , Vec < ast:: LifetimeDef > > {
4992
5036
if self . eat_keyword ( keywords:: For ) {
4993
5037
self . expect ( & token:: Lt ) ?;
4994
- let lifetime_defs = self . parse_lifetime_defs ( ) ?;
5038
+ let lifetime_defs = self . parse_lifetime_defs ( None ) ?;
4995
5039
self . expect_gt ( ) ?;
4996
5040
Ok ( lifetime_defs)
4997
5041
} else {
0 commit comments