Implement cast_expr
diff --git a/src/expr.rs b/src/expr.rs
index c327a47..3844710 100644
--- a/src/expr.rs
+++ b/src/expr.rs
@@ -1354,62 +1354,50 @@
// <unary> as <ty>
// <unary> : <ty>
#[cfg(feature = "full")]
- named2!(cast_expr(allow_struct: AllowStruct, allow_block: AllowBlock) -> Expr, do_parse!(
- mut e: shim!(unary_expr, allow_struct, allow_block) >>
- many0!(alt!(
- do_parse!(
- as_: keyword!(as) >>
- // We can't accept `A + B` in cast expressions, as it's
- // ambiguous with the + expression.
- ty: shim!(Type::without_plus) >>
- ({
- e = ExprCast {
- attrs: Vec::new(),
- expr: Box::new(e),
- as_token: as_,
- ty: Box::new(ty),
- }.into();
- })
- )
- |
- do_parse!(
- colon: punct!(:) >>
- // We can't accept `A + B` in cast expressions, as it's
- // ambiguous with the + expression.
- ty: shim!(Type::without_plus) >>
- ({
- e = ExprType {
- attrs: Vec::new(),
- expr: Box::new(e),
- colon_token: colon,
- ty: Box::new(ty),
- }.into();
- })
- )
- )) >>
- (e)
- ));
+ fn cast_expr(input: ParseStream, allow_struct: AllowStruct, allow_block: AllowBlock) -> Result<Expr> {
+ let mut e = unary_expr(input, allow_struct, allow_block)?;
+ loop {
+ if input.peek(Token![as]) {
+ e = Expr::Cast(ExprCast {
+ attrs: Vec::new(),
+ expr: Box::new(e),
+ as_token: input.parse()?,
+ // We can't accept `A + B` in cast expressions, as it's
+ // ambiguous with the + expression.
+ ty: Box::new(input.call(Type::without_plus)?),
+ });
+ } else if input.peek(Token![:]) {
+ e = Expr::Type(ExprType {
+ attrs: Vec::new(),
+ expr: Box::new(e),
+ colon_token: input.parse()?,
+ // We can't accept `A + B` in cast expressions, as it's
+ // ambiguous with the + expression.
+ ty: Box::new(input.call(Type::without_plus)?),
+ });
+ } else {
+ break;
+ }
+ }
+ Ok(e)
+ }
// <unary> as <ty>
#[cfg(not(feature = "full"))]
- named2!(cast_expr(allow_struct: AllowStruct, allow_block: AllowBlock) -> Expr, do_parse!(
- mut e: shim!(unary_expr, allow_struct, allow_block) >>
- many0!(do_parse!(
- as_: keyword!(as) >>
- // We can't accept `A + B` in cast expressions, as it's
- // ambiguous with the + expression.
- ty: shim!(Type::without_plus) >>
- ({
- e = ExprCast {
- attrs: Vec::new(),
- expr: Box::new(e),
- as_token: as_,
- ty: Box::new(ty),
- }.into();
- })
- )) >>
- (e)
- ));
+ fn cast_expr(input: ParseStream, allow_struct: AllowStruct, allow_block: AllowBlock) -> Result<Expr> {
+ let mut e = unary_expr(input, allow_struct, allow_block)?;
+ while input.peek(Token![as]) {
+ e = Expr::Cast(ExprCast {
+ attrs: Vec::new(),
+ expr: Box::new(e),
+ as_token: input.parse()?,
+ // We can't accept `A + B` in cast expressions, as it's
+ // ambiguous with the + expression.
+ ty: Box::new(input.call(Type::without_plus)?),
+ });
+ }
+ Ok(e)
+ }
// <UnOp> <trailer>
// & <trailer>