Skip to content

Commit e0ceef5

Browse files
committed
Add ExprType to HIR and make everything compile
+ Apply parser changes manually + Add feature gate
1 parent b8157cc commit e0ceef5

File tree

19 files changed

+83
-31
lines changed

19 files changed

+83
-31
lines changed

src/librustc/middle/const_eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1126,7 +1126,7 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
11261126
None => unreachable!(),
11271127
}
11281128
}
1129-
hir::ExprType(ref e, _) => try!(eval_const_expr_partial(tcx, &**e, ety)),
1129+
hir::ExprType(ref e, _) => try!(eval_const_expr_partial(tcx, &**e, ty_hint, fn_args)),
11301130
hir::ExprTup(_) => Tuple(e.id),
11311131
hir::ExprStruct(..) => Struct(e.id),
11321132
hir::ExprIndex(ref arr, ref idx) => {

src/librustc/middle/ty/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,10 @@ impl<'tcx> ctxt<'tcx> {
21082108
}
21092109
}
21102110

2111+
hir::ExprType(ref e, _) => {
2112+
self.expr_is_lval(e)
2113+
}
2114+
21112115
hir::ExprUnary(hir::UnDeref, _) |
21122116
hir::ExprField(..) |
21132117
hir::ExprTupField(..) |

src/librustc_front/fold.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,9 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
10421042
ExprCast(expr, ty) => {
10431043
ExprCast(folder.fold_expr(expr), folder.fold_ty(ty))
10441044
}
1045+
ExprType(expr, ty) => {
1046+
ExprType(folder.fold_expr(expr), folder.fold_ty(ty))
1047+
}
10451048
ExprAddrOf(m, ohs) => ExprAddrOf(m, folder.fold_expr(ohs)),
10461049
ExprIf(cond, tr, fl) => {
10471050
ExprIf(folder.fold_expr(cond),

src/librustc_front/hir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,7 @@ pub enum Expr_ {
720720
ExprLit(P<Lit>),
721721
/// A cast (`foo as f64`)
722722
ExprCast(P<Expr>, P<Ty>),
723+
ExprType(P<Expr>, P<Ty>),
723724
/// An `if` block, with an optional else block
724725
///
725726
/// `if expr { block } else { expr }`

src/librustc_front/intravisit.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
732732
visitor.visit_expr(subexpression)
733733
}
734734
ExprLit(_) => {}
735-
ExprCast(ref subexpression, ref typ) => {
735+
ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => {
736736
visitor.visit_expr(subexpression);
737737
visitor.visit_ty(typ)
738738
}

src/librustc_front/lowering.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1125,6 +1125,10 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
11251125
let expr = lower_expr(lctx, expr);
11261126
hir::ExprCast(expr, lower_ty(lctx, ty))
11271127
}
1128+
ExprType(ref expr, ref ty) => {
1129+
let expr = lower_expr(lctx, expr);
1130+
hir::ExprType(expr, lower_ty(lctx, ty))
1131+
}
11281132
ExprAddrOf(m, ref ohs) => {
11291133
let m = lower_mutability(lctx, m);
11301134
let ohs = lower_expr(lctx, ohs);

src/librustc_front/print/pprust.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ fn needs_parentheses(expr: &hir::Expr) -> bool {
336336
hir::ExprBinary(..) |
337337
hir::ExprClosure(..) |
338338
hir::ExprAssignOp(..) |
339-
hir::ExprCast(..) => true,
339+
hir::ExprCast(..) |
340+
hir::ExprType(..) => true,
340341
_ => false,
341342
}
342343
}
@@ -1354,6 +1355,11 @@ impl<'a> State<'a> {
13541355
try!(self.word_space("as"));
13551356
try!(self.print_type(&**ty));
13561357
}
1358+
hir::ExprType(ref expr, ref ty) => {
1359+
try!(self.print_expr(&**expr));
1360+
try!(self.word_space(":"));
1361+
try!(self.print_type(&**ty));
1362+
}
13571363
hir::ExprIf(ref test, ref blk, ref elseopt) => {
13581364
try!(self.print_if(&**test, &**blk, elseopt.as_ref().map(|e| &**e)));
13591365
}

src/librustc_lint/unused.rs

+1
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ impl UnusedParens {
319319
}
320320
ast::ExprUnary(_, ref x) |
321321
ast::ExprCast(ref x, _) |
322+
ast::ExprType(ref x, _) |
322323
ast::ExprField(ref x, _) |
323324
ast::ExprTupField(ref x, _) |
324325
ast::ExprIndex(ref x, _) => {

src/librustc_mir/hair/cx/expr.rs

+2
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
320320
name: Field::new(index.node as usize) },
321321
hir::ExprCast(ref source, _) =>
322322
ExprKind::Cast { source: source.to_ref() },
323+
hir::ExprType(ref source, _) =>
324+
return source.make_mirror(cx),
323325
hir::ExprBox(ref value) =>
324326
ExprKind::Box { value: value.to_ref() },
325327
hir::ExprVec(ref fields) =>

src/librustc_trans/trans/consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1004,7 +1004,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
10041004
try!(const_fn_call(cx, MethodCallKey(method_call),
10051005
method_did, &arg_vals, param_substs, trueconst))
10061006
},
1007-
hir::ExprType(ref e, _) => const_expr(cx, &**e, param_substs).0,
1007+
hir::ExprType(ref e, _) => try!(const_expr(cx, &**e, param_substs, fn_args, trueconst)).0,
10081008
hir::ExprBlock(ref block) => {
10091009
match block.expr {
10101010
Some(ref expr) => try!(const_expr(

src/librustc_trans/trans/debuginfo/create_scope_map.rs

+1
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ fn walk_expr(cx: &CrateContext,
320320
hir::ExprPath(..) => {}
321321

322322
hir::ExprCast(ref sub_exp, _) |
323+
hir::ExprType(ref sub_exp, _) |
323324
hir::ExprAddrOf(_, ref sub_exp) |
324325
hir::ExprField(ref sub_exp, _) |
325326
hir::ExprTupField(ref sub_exp, _) =>

src/librustc_trans/trans/expr.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2610,6 +2610,10 @@ fn expr_kind(tcx: &ty::ctxt, expr: &hir::Expr) -> ExprKind {
26102610
}
26112611
}
26122612

2613+
hir::ExprType(ref expr, _) => {
2614+
expr_kind(tcx, expr)
2615+
}
2616+
26132617
hir::ExprUnary(hir::UnDeref, _) |
26142618
hir::ExprField(..) |
26152619
hir::ExprTupField(..) |

src/libsyntax/feature_gate.rs

+7
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
233233

234234
// Allows `#[deprecated]` attribute
235235
("deprecated", "1.6.0", Some(29935), Active),
236+
237+
// allow using type ascription in expressions
238+
("type_ascription", "1.6.0", Some(23416), Active),
236239
];
237240
// (changing above list without updating src/doc/reference.md makes @cmr sad)
238241

@@ -960,6 +963,10 @@ impl<'a, 'v> Visitor<'v> for PostExpansionVisitor<'a> {
960963
"box expression syntax is experimental; \
961964
you can call `Box::new` instead.");
962965
}
966+
ast::ExprType(..) => {
967+
self.gate_feature("type_ascription", e.span,
968+
"type ascription is experimental");
969+
}
963970
_ => {}
964971
}
965972
visit::walk_expr(self, e);

src/libsyntax/parse/parser.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -2789,6 +2789,10 @@ impl<'a> Parser<'a> {
27892789
lhs = self.mk_expr(lhs.span.lo, rhs.span.hi,
27902790
ExprCast(lhs, rhs), None);
27912791
continue
2792+
} else if op == AssocOp::Colon {
2793+
let rhs = try!(self.parse_ty());
2794+
lhs = self.mk_expr(lhs.span.lo, rhs.span.hi, ExprType(lhs, rhs));
2795+
continue
27922796
} else if op == AssocOp::DotDot {
27932797
// If we didn’t have to handle `x..`, it would be pretty easy to generalise
27942798
// it to the Fixity::None code.
@@ -2857,7 +2861,9 @@ impl<'a> Parser<'a> {
28572861
let aopexpr = self.mk_assign_op(codemap::respan(cur_op_span, aop), lhs, rhs);
28582862
self.mk_expr(lhs_span.lo, rhs_span.hi, aopexpr, None)
28592863
}
2860-
AssocOp::As | AssocOp::DotDot => self.bug("As or DotDot branch reached")
2864+
AssocOp::As | AssocOp::Colon | AssocOp::DotDot => {
2865+
self.bug("As, Colon or DotDot branch reached")
2866+
}
28612867
};
28622868

28632869
if op.fixity() == Fixity::None { break }

src/libsyntax/util/parser.rs

+9-7
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ pub enum AssocOp {
6060
/// `as`
6161
As,
6262
/// `..` range
63-
DotDot
63+
DotDot,
64+
/// `:`
65+
Colon,
6466
}
6567

6668
#[derive(Debug, PartialEq, Eq)]
@@ -100,6 +102,7 @@ impl AssocOp {
100102
Token::AndAnd => Some(LAnd),
101103
Token::OrOr => Some(LOr),
102104
Token::DotDot => Some(DotDot),
105+
Token::Colon => Some(Colon),
103106
_ if t.is_keyword(keywords::As) => Some(As),
104107
_ => None
105108
}
@@ -134,7 +137,7 @@ impl AssocOp {
134137
pub fn precedence(&self) -> usize {
135138
use self::AssocOp::*;
136139
match *self {
137-
As => 14,
140+
As | Colon => 14,
138141
Multiply | Divide | Modulus => 13,
139142
Add | Subtract => 12,
140143
ShiftLeft | ShiftRight => 11,
@@ -158,7 +161,7 @@ impl AssocOp {
158161
Inplace | Assign | AssignOp(_) => Fixity::Right,
159162
As | Multiply | Divide | Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd |
160163
BitXor | BitOr | Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual |
161-
LAnd | LOr => Fixity::Left,
164+
LAnd | LOr | Colon => Fixity::Left,
162165
DotDot => Fixity::None
163166
}
164167
}
@@ -168,7 +171,7 @@ impl AssocOp {
168171
match *self {
169172
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual => true,
170173
Inplace | Assign | AssignOp(_) | As | Multiply | Divide | Modulus | Add | Subtract |
171-
ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot => false
174+
ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd | LOr | DotDot | Colon => false
172175
}
173176
}
174177

@@ -178,7 +181,7 @@ impl AssocOp {
178181
Assign | AssignOp(_) | Inplace => true,
179182
Less | Greater | LessEqual | GreaterEqual | Equal | NotEqual | As | Multiply | Divide |
180183
Modulus | Add | Subtract | ShiftLeft | ShiftRight | BitAnd | BitXor | BitOr | LAnd |
181-
LOr | DotDot => false
184+
LOr | DotDot | Colon => false
182185
}
183186
}
184187

@@ -203,8 +206,7 @@ impl AssocOp {
203206
BitOr => Some(ast::BiBitOr),
204207
LAnd => Some(ast::BiAnd),
205208
LOr => Some(ast::BiOr),
206-
Inplace | Assign | AssignOp(_) | As | DotDot => None
209+
Inplace | Assign | AssignOp(_) | As | DotDot | Colon => None
207210
}
208211
}
209-
210212
}

src/libsyntax/visit.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -693,14 +693,10 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
693693
visitor.visit_expr(subexpression)
694694
}
695695
ExprLit(_) => {}
696-
ExprCast(ref subexpression, ref typ) => {
696+
ExprCast(ref subexpression, ref typ) | ExprType(ref subexpression, ref typ) => {
697697
visitor.visit_expr(subexpression);
698698
visitor.visit_ty(typ)
699699
}
700-
ExprType(ref subexpression, ref typ) => {
701-
visitor.visit_expr(&**subexpression);
702-
visitor.visit_ty(&**typ)
703-
}
704700
ExprIf(ref head_expression, ref if_block, ref optional_else) => {
705701
visitor.visit_expr(head_expression);
706702
visitor.visit_block(if_block);

src/libsyntax_ext/asm.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
6262
// parsed as `asm!(z)` with `z = "x": y` which is type ascription.
6363
let first_colon = tts.iter().position(|tt| {
6464
match *tt {
65-
ast::TtToken(_, token::Colon) |
66-
ast::TtToken(_, token::ModSep) => true,
65+
ast::TokenTree::Token(_, token::Colon) |
66+
ast::TokenTree::Token(_, token::ModSep) => true,
6767
_ => false
6868
}
6969
}).unwrap_or(tts.len());
@@ -99,7 +99,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
9999

100100
// This is most likely malformed.
101101
if p2.token != token::Eof {
102-
let mut extra_tts = p2.parse_all_token_trees();
102+
let mut extra_tts = panictry!(p2.parse_all_token_trees());
103103
extra_tts.extend(tts[first_colon..].iter().cloned());
104104
p = parse::tts_to_parser(cx.parse_sess, extra_tts, cx.cfg());
105105
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Type ascription is feature gated
12+
13+
fn main() {
14+
let a = 10: u8; //~ ERROR type ascription is experimental
15+
}

src/test/run-pass/coerce-expect-unsized-ascribed.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -16,25 +16,25 @@ use std::fmt::Debug;
1616
// A version of coerce-expect-unsized that uses type ascription.
1717

1818
pub fn main() {
19-
let _ = box { [1, 2, 3] }: Box<[int]>;
20-
let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[int]>;
21-
let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[int]>;
22-
let _ = box { |x| (x as u8) }: Box<Fn(int) -> _>;
19+
let _ = box { [1, 2, 3] }: Box<[i32]>;
20+
let _ = box if true { [1, 2, 3] } else { [1, 3, 4] }: Box<[i32]>;
21+
let _ = box match true { true => [1, 2, 3], false => [1, 3, 4] }: Box<[i32]>;
22+
let _ = box { |x| (x as u8) }: Box<Fn(i32) -> _>;
2323
let _ = box if true { false } else { true }: Box<Debug>;
2424
let _ = box match true { true => 'a', false => 'b' }: Box<Debug>;
2525

26-
let _ = &{ [1, 2, 3] }: &[int];
27-
let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[int];
28-
let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[int];
29-
let _ = &{ |x| (x as u8) }: &Fn(int) -> _;
26+
let _ = &{ [1, 2, 3] }: &[i32];
27+
let _ = &if true { [1, 2, 3] } else { [1, 3, 4] }: &[i32];
28+
let _ = &match true { true => [1, 2, 3], false => [1, 3, 4] }: &[i32];
29+
let _ = &{ |x| (x as u8) }: &Fn(i32) -> _;
3030
let _ = &if true { false } else { true }: &Debug;
3131
let _ = &match true { true => 'a', false => 'b' }: &Debug;
3232

33-
let _ = Box::new([1, 2, 3]): Box<[int]>;
34-
let _ = Box::new(|x| (x as u8)): Box<Fn(int) -> _>;
33+
let _ = Box::new([1, 2, 3]): Box<[i32]>;
34+
let _ = Box::new(|x| (x as u8)): Box<Fn(i32) -> _>;
3535

3636
let _ = vec![
3737
Box::new(|x| (x as u8)),
3838
box |x| (x as i16 as u8),
39-
]: Vec<Box<Fn(int) -> _>>;
39+
]: Vec<Box<Fn(i32) -> _>>;
4040
}

0 commit comments

Comments
 (0)