@@ -388,73 +388,77 @@ impl<'a> Parser<'a> {
388388 /// possibly including trailing comma.
389389 fn parse_angle_args ( & mut self ) -> PResult < ' a , Vec < AngleBracketedArg > > {
390390 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) ;
453393 if !self . eat ( & token:: Comma ) {
454394 break ;
455395 }
456396 }
457-
458397 Ok ( args)
459398 }
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+ }
460464}
0 commit comments