about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2015-12-03 05:37:48 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2015-12-16 17:13:16 +0300
commite0ceef5a9e9224baf1f108ede1d1033e5e7fef08 (patch)
tree9b5a2df911400b1ff05bd8d12490dc6c6fccbb2b
parentb8157cc67fa25f2944b24f4306151d53d1b80b56 (diff)
Add ExprType to HIR and make everything compile
+ Apply parser changes manually
+ Add feature gate
-rw-r--r--src/librustc/middle/const_eval.rs2
-rw-r--r--src/librustc/middle/ty/mod.rs4
-rw-r--r--src/librustc_front/fold.rs3
-rw-r--r--src/librustc_front/hir.rs1
-rw-r--r--src/librustc_front/intravisit.rs2
-rw-r--r--src/librustc_front/lowering.rs4
-rw-r--r--src/librustc_front/print/pprust.rs8
-rw-r--r--src/librustc_lint/unused.rs1
-rw-r--r--src/librustc_mir/hair/cx/expr.rs2
-rw-r--r--src/librustc_trans/trans/consts.rs2
-rw-r--r--src/librustc_trans/trans/debuginfo/create_scope_map.rs1
-rw-r--r--src/librustc_trans/trans/expr.rs4
-rw-r--r--src/libsyntax/feature_gate.rs7
-rw-r--r--src/libsyntax/parse/parser.rs8
-rw-r--r--src/libsyntax/util/parser.rs16
-rw-r--r--src/libsyntax/visit.rs6
-rw-r--r--src/libsyntax_ext/asm.rs6
-rw-r--r--src/test/compile-fail/type-ascription-feature-gate.rs15
-rw-r--r--src/test/run-pass/coerce-expect-unsized-ascribed.rs22
19 files changed, 83 insertions, 31 deletions
diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs
index f5d5fe1a734..a56e8516d6c 100644
--- a/src/librustc/middle/const_eval.rs
+++ b/src/librustc/middle/const_eval.rs
@@ -1126,7 +1126,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
             None => unreachable!(),
         }
       }
-      hir::ExprType(ref e, _) => try!(eval_const_expr_partial(tcx, &**e, ety)),
+      hir::ExprType(ref e, _) => try!(eval_const_expr_partial(tcx, &**e, ty_hint, fn_args)),
       hir::ExprTup(_) => Tuple(e.id),
       hir::ExprStruct(..) => Struct(e.id),
       hir::ExprIndex(ref arr, ref idx) => {
diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs
index 7477c4dead0..e258321e64a 100644
--- a/src/librustc/middle/ty/mod.rs
+++ b/src/librustc/middle/ty/mod.rs
@@ -2108,6 +2108,10 @@ impl<'tcx> ctxt<'tcx> {
                 }
             }
 
+            hir::ExprType(ref e, _) => {
+                self.expr_is_lval(e)
+            }
+
             hir::ExprUnary(hir::UnDeref, _) |
             hir::ExprField(..) |
             hir::ExprTupField(..) |
diff --git a/src/librustc_front/fold.rs b/src/librustc_front/fold.rs
index 88a34b27c31..6ede584da05 100644
--- a/src/librustc_front/fold.rs
+++ b/src/librustc_front/fold.rs
@@ -1042,6 +1042,9 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
             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/librustc_front/hir.rs b/src/librustc_front/hir.rs
index d1cb82dbecc..7f738cbda1c 100644
--- a/src/librustc_front/hir.rs
+++ b/src/librustc_front/hir.rs
@@ -720,6 +720,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/librustc_front/intravisit.rs b/src/librustc_front/intravisit.rs
index 13d7e81cc6e..03b021cfa63 100644
--- a/src/librustc_front/intravisit.rs
+++ b/src/librustc_front/intravisit.rs
@@ -732,7 +732,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)
         }
diff --git a/src/librustc_front/lowering.rs b/src/librustc_front/lowering.rs
index c0b10fb8912..f4ea3d6a52e 100644
--- a/src/librustc_front/lowering.rs
+++ b/src/librustc_front/lowering.rs
@@ -1125,6 +1125,10 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
                 let expr = lower_expr(lctx, expr);
                 hir::ExprCast(expr, lower_ty(lctx, ty))
             }
+            ExprType(ref expr, ref ty) => {
+                let expr = lower_expr(lctx, expr);
+                hir::ExprType(expr, lower_ty(lctx, ty))
+            }
             ExprAddrOf(m, ref ohs) => {
                 let m = lower_mutability(lctx, m);
                 let ohs = lower_expr(lctx, ohs);
diff --git a/src/librustc_front/print/pprust.rs b/src/librustc_front/print/pprust.rs
index 81076b6e402..383ba9403c7 100644
--- a/src/librustc_front/print/pprust.rs
+++ b/src/librustc_front/print/pprust.rs
@@ -336,7 +336,8 @@ fn needs_parentheses(expr: &hir::Expr) -> bool {
         hir::ExprBinary(..) |
         hir::ExprClosure(..) |
         hir::ExprAssignOp(..) |
-        hir::ExprCast(..) => true,
+        hir::ExprCast(..) |
+        hir::ExprType(..) => true,
         _ => false,
     }
 }
@@ -1354,6 +1355,11 @@ impl<'a> State<'a> {
                 try!(self.word_space("as"));
                 try!(self.print_type(&**ty));
             }
+            hir::ExprType(ref expr, ref ty) => {
+                try!(self.print_expr(&**expr));
+                try!(self.word_space(":"));
+                try!(self.print_type(&**ty));
+            }
             hir::ExprIf(ref test, ref blk, ref elseopt) => {
                 try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e)));
             }
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index b8750cccb4b..18a3a96069e 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -319,6 +319,7 @@ impl UnusedParens {
                 }
                 ast::ExprUnary(_, ref x) |
                 ast::ExprCast(ref x, _) |
+                ast::ExprType(ref x, _) |
                 ast::ExprField(ref x, _) |
                 ast::ExprTupField(ref x, _) |
                 ast::ExprIndex(ref x, _) => {
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 08826013ebc..f74737af93c 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -320,6 +320,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
                                   name: Field::new(index.node as usize) },
             hir::ExprCast(ref source, _) =>
                 ExprKind::Cast { source: source.to_ref() },
+            hir::ExprType(ref source, _) =>
+                return source.make_mirror(cx),
             hir::ExprBox(ref value) =>
                 ExprKind::Box { value: value.to_ref() },
             hir::ExprVec(ref fields) =>
diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs
index dc5659ca465..175bae9f47f 100644
--- a/src/librustc_trans/trans/consts.rs
+++ b/src/librustc_trans/trans/consts.rs
@@ -1004,7 +1004,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             try!(const_fn_call(cx, MethodCallKey(method_call),
                                method_did, &arg_vals, param_substs, trueconst))
         },
-        hir::ExprType(ref e, _) => const_expr(cx, &**e, param_substs).0,
+        hir::ExprType(ref e, _) => try!(const_expr(cx, &**e, param_substs, fn_args, trueconst)).0,
         hir::ExprBlock(ref block) => {
             match block.expr {
                 Some(ref expr) => try!(const_expr(
diff --git a/src/librustc_trans/trans/debuginfo/create_scope_map.rs b/src/librustc_trans/trans/debuginfo/create_scope_map.rs
index 231dec276d9..237d31c4778 100644
--- a/src/librustc_trans/trans/debuginfo/create_scope_map.rs
+++ b/src/librustc_trans/trans/debuginfo/create_scope_map.rs
@@ -320,6 +320,7 @@ fn walk_expr(cx: &CrateContext,
         hir::ExprPath(..) => {}
 
         hir::ExprCast(ref sub_exp, _)     |
+        hir::ExprType(ref sub_exp, _) |
         hir::ExprAddrOf(_, ref sub_exp)  |
         hir::ExprField(ref sub_exp, _) |
         hir::ExprTupField(ref sub_exp, _) =>
diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs
index e73afc46174..ecf54cde9f6 100644
--- a/src/librustc_trans/trans/expr.rs
+++ b/src/librustc_trans/trans/expr.rs
@@ -2610,6 +2610,10 @@ fn expr_kind(tcx: &ty::ctxt, expr: &hir::Expr) -> ExprKind {
             }
         }
 
+        hir::ExprType(ref expr, _) => {
+            expr_kind(tcx, expr)
+        }
+
         hir::ExprUnary(hir::UnDeref, _) |
         hir::ExprField(..) |
         hir::ExprTupField(..) |
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index f186aff6d36..862c52dc4bd 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)
 
@@ -960,6 +963,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/parse/parser.rs b/src/libsyntax/parse/parser.rs
index e81f9a2a166..dd1fe22a4eb 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2789,6 +2789,10 @@ 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));
+                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.
@@ -2857,7 +2861,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/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 3c66220ae58..b8dd54790ce 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -693,14 +693,10 @@ 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)
         }
-        ExprType(ref subexpression, ref typ) => {
-            visitor.visit_expr(&**subexpression);
-            visitor.visit_ty(&**typ)
-        }
         ExprIf(ref head_expression, ref if_block, ref optional_else) => {
             visitor.visit_expr(head_expression);
             visitor.visit_block(if_block);
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 20b89b0e9db..12eabe0edfd 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -62,8 +62,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
     // parsed as `asm!(z)` with `z = "x": y` which is type ascription.
     let first_colon = tts.iter().position(|tt| {
         match *tt {
-            ast::TtToken(_, token::Colon) |
-            ast::TtToken(_, token::ModSep) => true,
+            ast::TokenTree::Token(_, token::Colon) |
+            ast::TokenTree::Token(_, token::ModSep) => true,
             _ => false
         }
     }).unwrap_or(tts.len());
@@ -99,7 +99,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 
                 // This is most likely malformed.
                 if p2.token != token::Eof {
-                    let mut extra_tts = p2.parse_all_token_trees();
+                    let mut extra_tts = panictry!(p2.parse_all_token_trees());
                     extra_tts.extend(tts[first_colon..].iter().cloned());
                     p = parse::tts_to_parser(cx.parse_sess, extra_tts, cx.cfg());
                 }
diff --git a/src/test/compile-fail/type-ascription-feature-gate.rs b/src/test/compile-fail/type-ascription-feature-gate.rs
new file mode 100644
index 00000000000..d3c07d653f4
--- /dev/null
+++ b/src/test/compile-fail/type-ascription-feature-gate.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Type ascription is feature gated
+
+fn main() {
+    let a = 10: u8; //~ ERROR type ascription is experimental
+}
diff --git a/src/test/run-pass/coerce-expect-unsized-ascribed.rs b/src/test/run-pass/coerce-expect-unsized-ascribed.rs
index 2b1204483ba..33e9b424fea 100644
--- a/src/test/run-pass/coerce-expect-unsized-ascribed.rs
+++ b/src/test/run-pass/coerce-expect-unsized-ascribed.rs
@@ -16,25 +16,25 @@ use std::fmt::Debug;
 // A version of coerce-expect-unsized that uses type ascription.
 
 pub fn main() {
-    let _ = box { [1, 2, 3] }: Box<[int]>;
-    let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[int]>;
-    let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[int]>;
-    let _ = box { |x| (x as u8) }: Box<Fn(int) -> _>;
+    let _ = box { [1, 2, 3] }: Box<[i32]>;
+    let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[i32]>;
+    let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[i32]>;
+    let _ = box { |x| (x as u8) }: Box<Fn(i32) -> _>;
     let _ = box if true { false } else { true }: Box<Debug>;
     let _ = box match true { true => 'a', false => 'b' }: Box<Debug>;
 
-    let _ = &{ [1, 2, 3] }: &[int];
-    let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[int];
-    let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[int];
-    let _ = &{ |x| (x as u8) }: &Fn(int) -> _;
+    let _ = &{ [1, 2, 3] }: &[i32];
+    let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[i32];
+    let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[i32];
+    let _ = &{ |x| (x as u8) }: &Fn(i32) -> _;
     let _ = &if true { false } else { true }: &Debug;
     let _ = &match true { true => 'a', false => 'b' }: &Debug;
 
-    let _ = Box::new([1, 2, 3]): Box<[int]>;
-    let _ = Box::new(|x| (x as u8)): Box<Fn(int) -> _>;
+    let _ = Box::new([1, 2, 3]): Box<[i32]>;
+    let _ = Box::new(|x| (x as u8)): Box<Fn(i32) -> _>;
 
     let _ = vec![
         Box::new(|x| (x as u8)),
         box |x| (x as i16 as u8),
-    ]: Vec<Box<Fn(int) -> _>>;
+    ]: Vec<Box<Fn(i32) -> _>>;
 }