diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 1 | ||||
| -rw-r--r-- | src/libsyntax/feature_gate.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 3 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 12 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/util/parser.rs | 16 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 2 |
7 files changed, 36 insertions, 12 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 4b0ec8578c1..abc44407eff 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -942,6 +942,7 @@ pub enum Expr_ { ExprLit(P<Lit>), /// A cast (`foo as f64`) ExprCast(P<Expr>, P<Ty>), + ExprType(P<Expr>, P<Ty>), /// An `if` block, with an optional else block /// /// `if expr { block } else { expr }` diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 0d38411ac93..b2989c42a9e 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -233,6 +233,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status // Allows `#[deprecated]` attribute ("deprecated", "1.6.0", Some(29935), Active), + + // allow using type ascription in expressions + ("type_ascription", "1.6.0", Some(23416), Active), ]; // (changing above list without updating src/doc/reference.md makes @cmr sad) @@ -958,6 +961,10 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> { "box expression syntax is experimental; \ you can call `Box::new` instead."); } + ast::ExprType(..) => { + self.gate_feature("type_ascription", e.span, + "type ascription is experimental"); + } _ => {} } visit::walk_expr(self, e); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index cd2210c71b8..cb467f9016b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1203,6 +1203,9 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu ExprCast(expr, ty) => { ExprCast(folder.fold_expr(expr), folder.fold_ty(ty)) } + ExprType(expr, ty) => { + ExprType(folder.fold_expr(expr), folder.fold_ty(ty)) + } ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)), ExprIf(cond, tr, fl) => { ExprIf(folder.fold_expr(cond), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index ebfcf8c5180..b625277f2a7 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -26,7 +26,7 @@ use ast::{ExprBreak, ExprCall, ExprCast, ExprInPlace}; use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex}; use ast::{ExprLit, ExprLoop, ExprMac, ExprRange}; use ast::{ExprMethodCall, ExprParen, ExprPath}; -use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary}; +use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprType, ExprUnary}; use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl}; use ast::{ForeignItem, ForeignItemStatic, ForeignItemFn, FunctionRetTy}; use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic}; @@ -2787,6 +2787,11 @@ impl<'a> Parser<'a> { lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, ExprCast(lhs, rhs), None); continue + } else if op == AssocOp::Colon { + let rhs = try!(self.parse_ty()); + lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, + ExprType(lhs, rhs), None); + continue } else if op == AssocOp::DotDot { // If we didn’t have to handle `x..`, it would be pretty easy to generalise // it to the Fixity::None code. @@ -2809,7 +2814,6 @@ impl<'a> Parser<'a> { break } - let rhs = try!(match op.fixity() { Fixity::Right => self.with_res(restrictions, |this|{ this.parse_assoc_expr_with(op.precedence(), LhsExpr::NotYetParsed) @@ -2856,7 +2860,9 @@ impl<'a> Parser<'a> { let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs); self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None) } - AssocOp::As | AssocOp::DotDot => self.bug("As or DotDot branch reached") + AssocOp::As | AssocOp::Colon | AssocOp::DotDot => { + self.bug("As, Colon or DotDot branch reached") + } }; if op.fixity() == Fixity::None { break } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1f296dc5d59..ff01f0ac67e 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -444,7 +444,7 @@ fn needs_parentheses(expr: &ast::Expr) -> bool { ast::ExprAssign(..) | ast::ExprBinary(..) | ast::ExprClosure(..) | ast::ExprAssignOp(..) | ast::ExprCast(..) | - ast::ExprInPlace(..) => true, + ast::ExprInPlace(..) | ast::ExprType(..) => true, _ => false, } } @@ -2035,6 +2035,11 @@ impl<'a> State<'a> { try!(self.word_space("as")); try!(self.print_type(&**ty)); } + ast::ExprType(ref expr, ref ty) => { + try!(self.print_expr(&**expr)); + try!(self.word_space(":")); + try!(self.print_type(&**ty)); + } ast::ExprIf(ref test, ref blk, ref elseopt) => { try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e))); } diff --git a/src/libsyntax/util/parser.rs b/src/libsyntax/util/parser.rs index bf3a8def390..87ef96d87ff 100644 --- a/src/libsyntax/util/parser.rs +++ b/src/libsyntax/util/parser.rs @@ -60,7 +60,9 @@ pub enum AssocOp { /// `as` As, /// `..` range - DotDot + DotDot, + /// `:` + Colon, } #[derive(Debug, PartialEq, Eq)] @@ -100,6 +102,7 @@ impl AssocOp { Token::AndAnd => Some(LAnd), Token::OrOr => Some(LOr), Token::DotDot => Some(DotDot), + Token::Colon => Some(Colon), _ if t.is_keyword(keywords::As) => Some(As), _ => None } @@ -134,7 +137,7 @@ impl AssocOp { pub fn precedence(&self) -> usize { use self::AssocOp::*; match *self { - As => 14, + As | Colon => 14, Multiply | Divide | Modulus => 13, Add | Subtract => 12, ShiftLeft | ShiftRight => 11, @@ -158,7 +161,7 @@ impl AssocOp { Inplace | Assign | AssignOp(_) => Fixity::Right, As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | - LAnd | LOr => Fixity::Left, + LAnd | LOr | Colon => Fixity::Left, DotDot => Fixity::None } } @@ -168,7 +171,7 @@ impl AssocOp { match *self { Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true, Inplace | Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract | - ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot => false + ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | Colon => false } } @@ -178,7 +181,7 @@ impl AssocOp { Assign | AssignOp(_) | Inplace => true, Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | - LOr | DotDot => false + LOr | DotDot | Colon => false } } @@ -203,8 +206,7 @@ impl AssocOp { BitOr => Some(ast::BiBitOr), LAnd => Some(ast::BiAnd), LOr => Some(ast::BiOr), - Inplace | Assign | AssignOp(_) | As | DotDot => None + Inplace | Assign | AssignOp(_) | As | DotDot | Colon => None } } - } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 22bf135f4f9..b8dd54790ce 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -693,7 +693,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(subexpression) } ExprLit(_) => {} - ExprCast(ref subexpression, ref typ) => { + ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => { visitor.visit_expr(subexpression); visitor.visit_ty(typ) } |
