@@ -388,73 +388,77 @@ impl<'a> Parser<'a> {
388
388
/// possibly including trailing comma.
389
389
fn parse_angle_args ( & mut self ) -> PResult < ' a , Vec < AngleBracketedArg > > {
390
390
let mut args = Vec :: new ( ) ;
391
- loop {
392
- if self . check_lifetime ( ) && self . look_ahead ( 1 , |t| !t. is_like_plus ( ) ) {
393
- // Parse lifetime argument.
394
- args. push ( AngleBracketedArg :: Arg ( GenericArg :: Lifetime ( self . expect_lifetime ( ) ) ) ) ;
395
- } else if self . check_ident ( )
396
- && self . look_ahead ( 1 , |t| matches ! ( t. kind, token:: Eq | token:: Colon ) )
397
- {
398
- // Parse associated type constraint.
399
- let lo = self . token . span ;
400
- let ident = self . parse_ident ( ) ?;
401
- let kind = if self . eat ( & token:: Eq ) {
402
- AssocTyConstraintKind :: Equality { ty : self . parse_ty ( ) ? }
403
- } else if self . eat ( & token:: Colon ) {
404
- let bounds = self . parse_generic_bounds ( Some ( self . prev_token . span ) ) ?;
405
- AssocTyConstraintKind :: Bound { bounds }
406
- } else {
407
- unreachable ! ( ) ;
408
- } ;
409
-
410
- let span = lo. to ( self . prev_token . span ) ;
411
-
412
- // Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
413
- if let AssocTyConstraintKind :: Bound { .. } = kind {
414
- self . sess . gated_spans . gate ( sym:: associated_type_bounds, span) ;
415
- }
416
-
417
- let constraint = AssocTyConstraint { id : ast:: DUMMY_NODE_ID , ident, kind, span } ;
418
- args. push ( AngleBracketedArg :: Constraint ( constraint) ) ;
419
- } else if self . check_const_arg ( ) {
420
- // Parse const argument.
421
- let expr = if let token:: OpenDelim ( token:: Brace ) = self . token . kind {
422
- self . parse_block_expr (
423
- None ,
424
- self . token . span ,
425
- BlockCheckMode :: Default ,
426
- ast:: AttrVec :: new ( ) ,
427
- ) ?
428
- } else if self . token . is_ident ( ) {
429
- // FIXME(const_generics): to distinguish between idents for types and consts,
430
- // we should introduce a GenericArg::Ident in the AST and distinguish when
431
- // lowering to the HIR. For now, idents for const args are not permitted.
432
- if self . token . is_bool_lit ( ) {
433
- self . parse_literal_maybe_minus ( ) ?
434
- } else {
435
- let span = self . token . span ;
436
- let msg = "identifiers may currently not be used for const generics" ;
437
- self . struct_span_err ( span, msg) . emit ( ) ;
438
- let block = self . mk_block_err ( span) ;
439
- self . mk_expr ( span, ast:: ExprKind :: Block ( block, None ) , ast:: AttrVec :: new ( ) )
440
- }
441
- } else {
442
- self . parse_literal_maybe_minus ( ) ?
443
- } ;
444
- let value = AnonConst { id : ast:: DUMMY_NODE_ID , value : expr } ;
445
- args. push ( AngleBracketedArg :: Arg ( GenericArg :: Const ( value) ) ) ;
446
- } else if self . check_type ( ) {
447
- // Parse type argument.
448
- args. push ( AngleBracketedArg :: Arg ( GenericArg :: Type ( self . parse_ty ( ) ?) ) ) ;
449
- } else {
450
- break ;
451
- }
452
-
391
+ while let Some ( arg) = self . parse_angle_arg ( ) ? {
392
+ args. push ( arg) ;
453
393
if !self . eat ( & token:: Comma ) {
454
394
break ;
455
395
}
456
396
}
457
-
458
397
Ok ( args)
459
398
}
399
+
400
+ /// Parses a single argument in the angle arguments `<...>` of a path segment.
401
+ fn parse_angle_arg ( & mut self ) -> PResult < ' a , Option < AngleBracketedArg > > {
402
+ let arg = if self . check_lifetime ( ) && self . look_ahead ( 1 , |t| !t. is_like_plus ( ) ) {
403
+ // Parse lifetime argument.
404
+ AngleBracketedArg :: Arg ( GenericArg :: Lifetime ( self . expect_lifetime ( ) ) )
405
+ } else if self . check_ident ( )
406
+ && self . look_ahead ( 1 , |t| matches ! ( t. kind, token:: Eq | token:: Colon ) )
407
+ {
408
+ // Parse associated type constraint.
409
+ let lo = self . token . span ;
410
+ let ident = self . parse_ident ( ) ?;
411
+ let kind = if self . eat ( & token:: Eq ) {
412
+ AssocTyConstraintKind :: Equality { ty : self . parse_ty ( ) ? }
413
+ } else if self . eat ( & token:: Colon ) {
414
+ let bounds = self . parse_generic_bounds ( Some ( self . prev_token . span ) ) ?;
415
+ AssocTyConstraintKind :: Bound { bounds }
416
+ } else {
417
+ unreachable ! ( ) ;
418
+ } ;
419
+
420
+ let span = lo. to ( self . prev_token . span ) ;
421
+
422
+ // Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
423
+ if let AssocTyConstraintKind :: Bound { .. } = kind {
424
+ self . sess . gated_spans . gate ( sym:: associated_type_bounds, span) ;
425
+ }
426
+
427
+ let constraint = AssocTyConstraint { id : ast:: DUMMY_NODE_ID , ident, kind, span } ;
428
+ AngleBracketedArg :: Constraint ( constraint)
429
+ } else if self . check_const_arg ( ) {
430
+ // Parse const argument.
431
+ let expr = if let token:: OpenDelim ( token:: Brace ) = self . token . kind {
432
+ self . parse_block_expr (
433
+ None ,
434
+ self . token . span ,
435
+ BlockCheckMode :: Default ,
436
+ ast:: AttrVec :: new ( ) ,
437
+ ) ?
438
+ } else if self . token . is_ident ( ) {
439
+ // FIXME(const_generics): to distinguish between idents for types and consts,
440
+ // we should introduce a GenericArg::Ident in the AST and distinguish when
441
+ // lowering to the HIR. For now, idents for const args are not permitted.
442
+ if self . token . is_bool_lit ( ) {
443
+ self . parse_literal_maybe_minus ( ) ?
444
+ } else {
445
+ let span = self . token . span ;
446
+ let msg = "identifiers may currently not be used for const generics" ;
447
+ self . struct_span_err ( span, msg) . emit ( ) ;
448
+ let block = self . mk_block_err ( span) ;
449
+ self . mk_expr ( span, ast:: ExprKind :: Block ( block, None ) , ast:: AttrVec :: new ( ) )
450
+ }
451
+ } else {
452
+ self . parse_literal_maybe_minus ( ) ?
453
+ } ;
454
+ let value = AnonConst { id : ast:: DUMMY_NODE_ID , value : expr } ;
455
+ AngleBracketedArg :: Arg ( GenericArg :: Const ( value) )
456
+ } else if self . check_type ( ) {
457
+ // Parse type argument.
458
+ AngleBracketedArg :: Arg ( GenericArg :: Type ( self . parse_ty ( ) ?) )
459
+ } else {
460
+ return Ok ( None ) ;
461
+ } ;
462
+ Ok ( Some ( arg) )
463
+ }
460
464
}
0 commit comments