fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<AssocTyConstraint>)> {
        let mut args = Vec::new();
        let mut constraints = Vec::new();
        let mut misplaced_assoc_ty_constraints: Vec<Span> = Vec::new();
        let mut assoc_ty_constraints: Vec<Span> = Vec::new();

        let args_lo = self.token.span;

        loop {
            if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
                // Parse lifetime argument.
                args.push(GenericArg::Lifetime(self.expect_lifetime()));
                misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
            } else if self.check_ident()
                && self.look_ahead(1, |t| t == &token::Eq || t == &token::Colon)
            {
                // Parse associated type constraint.
                let lo = self.token.span;
                let ident = self.parse_ident()?;
                let kind = if self.eat(&token::Eq) {
                    AssocTyConstraintKind::Equality {
                        ty: self.parse_ty()?,
                    }
                } else if self.eat(&token::Colon) {
                    AssocTyConstraintKind::Bound {
                        bounds: self.parse_generic_bounds(Some(self.prev_span))?,
                    }
                } else {
                    unreachable!();
                };

                let span = lo.to(self.prev_span);

                // Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
                if let AssocTyConstraintKind::Bound { .. } = kind {
                    self.sess.gated_spans.gate(sym::associated_type_bounds, span);
                }

                constraints.push(AssocTyConstraint {
                    id: ast::DUMMY_NODE_ID,
                    ident,
                    kind,
                    span,
                });
                assoc_ty_constraints.push(span);
            } else if self.check_const_arg() {
                // Parse const argument.
                let expr = if let token::OpenDelim(token::Brace) = self.token.kind {
                    self.parse_block_expr(
                        None, self.token.span, BlockCheckMode::Default, ast::AttrVec::new()
                    )?
                } else if self.token.is_ident() {
                    // FIXME(const_generics): to distinguish between idents for types and consts,
                    // we should introduce a GenericArg::Ident in the AST and distinguish when
                    // lowering to the HIR. For now, idents for const args are not permitted.
                    if self.token.is_bool_lit() {
                        self.parse_literal_maybe_minus()?
                    } else {
                        return Err(
                            self.fatal("identifiers may currently not be used for const generics")
                        );
                    }
                } else {
                    self.parse_literal_maybe_minus()?
                };
                let value = AnonConst {
                    id: ast::DUMMY_NODE_ID,
                    value: expr,
                };
                args.push(GenericArg::Const(value));
                misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
            } else if self.check_type() {
                // Parse type argument.
                args.push(GenericArg::Type(self.parse_ty()?));
                misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
            } else {
                break
            }

            if !self.eat(&token::Comma) {
                break
            }
        }

        // FIXME: we would like to report this in ast_validation instead, but we currently do not
        // preserve ordering of generic parameters with respect to associated type binding, so we
        // lose that information after parsing.
        if misplaced_assoc_ty_constraints.len() > 0 {
            let mut err = self.struct_span_err(
                args_lo.to(self.prev_span),
                "associated type bindings must be declared after generic parameters",
            );
            for span in misplaced_assoc_ty_constraints {
                err.span_label(
                    span,
                    "this associated type binding should be moved after the generic parameters",
                );
            }
            err.emit();
        }

        Ok((args, constraints))
    }
/// Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
/// possibly including trailing comma.
Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
possibly including trailing comma.
Parses ( possibly empty ) list of lifetime and type arguments and associated type bindings possibly including trailing comma .
fn parse_generic_args(&mut self) -> PResult<'a, (Vec<GenericArg>, Vec<AssocTyConstraint>)> {
        let mut args = Vec::new();
        let mut constraints = Vec::new();
        let mut misplaced_assoc_ty_constraints: Vec<Span> = Vec::new();
        let mut assoc_ty_constraints: Vec<Span> = Vec::new();
        let args_lo = self.token.span;
        loop {
            if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
                // Parse lifetime argument.
                args.push(GenericArg::Lifetime(self.expect_lifetime()));
                misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
            } else if self.check_ident()
                && self.look_ahead(1, |t| t == &token::Eq || t == &token::Colon)
            {
                // Parse associated type constraint.
                let lo = self.token.span;
                let ident = self.parse_ident()?;
                let kind = if self.eat(&token::Eq) {
                    AssocTyConstraintKind::Equality {
                        ty: self.parse_ty()?,
                    }
                } else if self.eat(&token::Colon) {
                    AssocTyConstraintKind::Bound {
                        bounds: self.parse_generic_bounds(Some(self.prev_span))?,
                    }
                } else {
                    unreachable!();
                };
                let span = lo.to(self.prev_span);
                // Gate associated type bounds, e.g., `Iterator<Item: Ord>`.
                if let AssocTyConstraintKind::Bound { .. } = kind {
                    self.sess.gated_spans.gate(sym::associated_type_bounds, span);
                }
                constraints.push(AssocTyConstraint {
                    id: ast::DUMMY_NODE_ID,
                    ident,
                    kind,
                    span,
                });
                assoc_ty_constraints.push(span);
            } else if self.check_const_arg() {
                // Parse const argument.
                let expr = if let token::OpenDelim(token::Brace) = self.token.kind {
                    self.parse_block_expr(
                        None, self.token.span, BlockCheckMode::Default, ast::AttrVec::new()
                    )?
                } else if self.token.is_ident() {
                    // FIXME(const_generics): to distinguish between idents for types and consts,
                    // we should introduce a GenericArg::Ident in the AST and distinguish when
                    // lowering to the HIR. For now, idents for const args are not permitted.
                    if self.token.is_bool_lit() {
                        self.parse_literal_maybe_minus()?
                    } else {
                        return Err(
                            self.fatal("identifiers may currently not be used for const generics")
                        );
                    }
                } else {
                    self.parse_literal_maybe_minus()?
                };
                let value = AnonConst {
                    id: ast::DUMMY_NODE_ID,
                    value: expr,
                };
                args.push(GenericArg::Const(value));
                misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
            } else if self.check_type() {
                // Parse type argument.
                args.push(GenericArg::Type(self.parse_ty()?));
                misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints);
            } else {
                break
            }
            if !self.eat(&token::Comma) {
                break
            }
        }
        // FIXME: we would like to report this in ast_validation instead, but we currently do not
        // preserve ordering of generic parameters with respect to associated type binding, so we
        // lose that information after parsing.
        if misplaced_assoc_ty_constraints.len() > 0 {
            let mut err = self.struct_span_err(
                args_lo.to(self.prev_span),
                "associated type bindings must be declared after generic parameters",
            );
            for span in misplaced_assoc_ty_constraints {
                err.span_label(
                    span,
                    "this associated type binding should be moved after the generic parameters",
                );
            }
            err.emit();
        }
        Ok((args, constraints))
    }
fn parse_generic_args ( & mut self ) -> PResult < ' a , ( Vec < GenericArg > , Vec < AssocTyConstraint > ) > { let mut args = Vec :: new ( ) ; let mut constraints = Vec :: new ( ) ; let mut misplaced_assoc_ty_constraints : Vec < Span > = Vec :: new ( ) ; let mut assoc_ty_constraints : Vec < Span > = Vec :: new ( ) ; let args_lo = self . token . span ; loop { if self . check_lifetime ( ) && self . look_ahead ( 1 , | t | ! t . is_like_plus ( ) ) { // Parse lifetime argument. args . push ( GenericArg :: Lifetime ( self . expect_lifetime ( ) ) ) ; misplaced_assoc_ty_constraints . append ( & mut assoc_ty_constraints ) ; } else if self . check_ident ( ) && self . look_ahead ( 1 , | t | t == & token :: Eq || t == & token :: Colon ) { // Parse associated type constraint. let lo = self . token . span ; let ident = self . parse_ident ( ) ? ; let kind = if self . eat ( & token :: Eq ) { AssocTyConstraintKind :: Equality { ty : self . parse_ty ( ) ? , } } else if self . eat ( & token :: Colon ) { AssocTyConstraintKind :: Bound { bounds : self . parse_generic_bounds ( Some ( self . prev_span ) ) ? , } } else { unreachable ! ( ) ; } ; let span = lo . to ( self . prev_span ) ; // Gate associated type bounds, e.g., `Iterator<Item: Ord>`. if let AssocTyConstraintKind :: Bound { .. } = kind { self . sess . gated_spans . gate ( sym :: associated_type_bounds , span ) ; } constraints . push ( AssocTyConstraint { id : ast :: DUMMY_NODE_ID , ident , kind , span , } ) ; assoc_ty_constraints . push ( span ) ; } else if self . check_const_arg ( ) { // Parse const argument. let expr = if let token :: OpenDelim ( token :: Brace ) = self . token . kind { self . parse_block_expr ( None , self . token . span , BlockCheckMode :: Default , ast :: AttrVec :: new ( ) ) ? } else if self . token . is_ident ( ) { // FIXME(const_generics): to distinguish between idents for types and consts, // we should introduce a GenericArg::Ident in the AST and distinguish when // lowering to the HIR. For now, idents for const args are not permitted. if self . token . is_bool_lit ( ) { self . parse_literal_maybe_minus ( ) ? } else { return Err ( self . fatal ( " " ) ) ; } } else { self . parse_literal_maybe_minus ( ) ? } ; let value = AnonConst { id : ast :: DUMMY_NODE_ID , value : expr , } ; args . push ( GenericArg :: Const ( value ) ) ; misplaced_assoc_ty_constraints . append ( & mut assoc_ty_constraints ) ; } else if self . check_type ( ) { // Parse type argument. args . push ( GenericArg :: Type ( self . parse_ty ( ) ? ) ) ; misplaced_assoc_ty_constraints . append ( & mut assoc_ty_constraints ) ; } else { break } if ! self . eat ( & token :: Comma ) { break } } // FIXME: we would like to report this in ast_validation instead, but we currently do not // preserve ordering of generic parameters with respect to associated type binding, so we // lose that information after parsing. if misplaced_assoc_ty_constraints . len ( ) > 0 { let mut err = self . struct_span_err ( args_lo . to ( self . prev_span ) , " " , ) ; for span in misplaced_assoc_ty_constraints { err . span_label ( span , " " , ) ; } err . emit ( ) ; } Ok ( ( args , constraints ) ) }
Parses (possibly empty) list of lifetime and type arguments and associated type bindings,
possibly including trailing comma.
Parses ( possibly empty ) list of lifetime and type arguments and associated type bindings possibly including trailing comma .
&mut self