self.parse_expr_res(Restrictions::empty(), None)
}
+ pub(super) fn parse_anon_const_expr(&mut self) -> PResult<'a, AnonConst> {
+ self.parse_expr().map(|value| AnonConst { id: DUMMY_NODE_ID, value })
+ }
+
fn parse_expr_catch_underscore(&mut self) -> PResult<'a, P<Expr>> {
match self.parse_expr() {
Ok(expr) => Ok(expr),
}
}
- /// Parses a sequence of expressions bounded by parentheses.
+ /// Parses a sequence of expressions delimited by parentheses.
fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec<P<Expr>>> {
self.parse_paren_comma_seq(|p| {
p.parse_expr_catch_underscore()
let first_expr = self.parse_expr()?;
if self.eat(&token::Semi) {
// Repeating array syntax: `[ 0; 512 ]`
- let count = AnonConst {
- id: DUMMY_NODE_ID,
- value: self.parse_expr()?,
- };
+ let count = self.parse_anon_const_expr()?;
self.expect(close)?;
ExprKind::Repeat(first_expr, count)
} else if self.eat(&token::Comma) {
use rustc_errors::{PResult, Applicability, DiagnosticBuilder, StashKey};
use rustc_error_codes::*;
-use syntax::ast::{self, DUMMY_NODE_ID, Ident, AttrVec, Attribute, AttrKind, AttrStyle, AnonConst};
+use syntax::ast::{self, DUMMY_NODE_ID, Ident, AttrVec, Attribute, AttrKind, AttrStyle};
use syntax::ast::{AssocItem, AssocItemKind, Item, ItemKind, UseTree, UseTreeKind};
use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
};
let disr_expr = if self.eat(&token::Eq) {
- Some(AnonConst {
- id: DUMMY_NODE_ID,
- value: self.parse_expr()?,
- })
+ Some(self.parse_anon_const_expr()?)
} else {
None
};
use syntax::ptr::P;
use syntax::ast::{self, Ty, TyKind, MutTy, BareFnTy, FunctionRetTy, GenericParam, Lifetime, Ident};
use syntax::ast::{TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef};
-use syntax::ast::{Mutability, AnonConst, Mac};
+use syntax::ast::{Mutability, Mac};
use syntax::token::{self, Token};
use syntax::struct_span_err;
use syntax_pos::source_map::Span;
} else if self.eat(&token::BinOp(token::Star)) {
self.parse_ty_ptr()?
} else if self.eat(&token::OpenDelim(token::Bracket)) {
- // Array or slice
- let t = self.parse_ty()?;
- // Parse optional `; EXPR` in `[TYPE; EXPR]`
- let t = match self.maybe_parse_fixed_length_of_vec()? {
- None => TyKind::Slice(t),
- Some(length) => TyKind::Array(t, AnonConst {
- id: ast::DUMMY_NODE_ID,
- value: length,
- }),
- };
- self.expect(&token::CloseDelim(token::Bracket))?;
- t
+ self.parse_array_or_slice_ty()?
} else if self.check(&token::BinOp(token::And)) || self.check(&token::AndAnd) {
// Reference
self.expect_and()?;
// `typeof(EXPR)`
// In order to not be ambiguous, the type must be surrounded by parens.
self.expect(&token::OpenDelim(token::Paren))?;
- let e = AnonConst {
- id: ast::DUMMY_NODE_ID,
- value: self.parse_expr()?,
- };
+ let expr = self.parse_anon_const_expr()?;
self.expect(&token::CloseDelim(token::Paren))?;
- TyKind::Typeof(e)
+ TyKind::Typeof(expr)
} else if self.eat_keyword(kw::Underscore) {
// A type to be inferred `_`
TyKind::Infer
Ok(TyKind::Ptr(MutTy { ty, mutbl }))
}
- fn maybe_parse_fixed_length_of_vec(&mut self) -> PResult<'a, Option<P<ast::Expr>>> {
- if self.eat(&token::Semi) {
- Ok(Some(self.parse_expr()?))
+ /// Parses an array (`[TYPE; EXPR]`) or slice (`[TYPE]`) type.
+ /// The opening `[` bracket is already eaten.
+ fn parse_array_or_slice_ty(&mut self) -> PResult<'a, TyKind> {
+ let elt_ty = self.parse_ty()?;
+ let ty = if self.eat(&token::Semi) {
+ TyKind::Array(elt_ty, self.parse_anon_const_expr()?)
} else {
- Ok(None)
- }
+ TyKind::Slice(elt_ty)
+ };
+ self.expect(&token::CloseDelim(token::Bracket))?;
+ Ok(ty)
}
fn parse_borrowed_pointee(&mut self) -> PResult<'a, TyKind> {