Skip to content

Commit 440ef8b

Browse files
committed
Auto merge of #30184 - petrochenkov:ascr, r=nikomatsakis
This PR is a rebase of the original PR by @eddyb #21836 with some unrebasable parts manually reapplied, feature gate added + type equality restriction added as described below. This implementation is partial because the type equality restriction is applied to all type ascription expressions and not only those in lvalue contexts. Thus, all difficulties with detection of these contexts and translation of coercions having effect in runtime are avoided. So, you can't write things with coercions like `let slice = &[1, 2, 3]: &[u8];`. It obviously makes type ascription less useful than it should be, but it's still much more useful than not having type ascription at all. In particular, things like `let v = something.iter().collect(): Vec<_>;` and `let u = t.into(): U;` work as expected and I'm pretty happy with these improvements alone. Part of #23416
2 parents 8ad12c3 + 95fdaf2 commit 440ef8b

36 files changed

+321
-24
lines changed

src/doc/reference.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2388,6 +2388,8 @@ The currently implemented features of the reference compiler are:
23882388

23892389
* - `deprecated` - Allows using the `#[deprecated]` attribute.
23902390

2391+
* - `type_ascription` - Allows type ascription expressions `expr: Type`.
2392+
23912393
If a feature is promoted to a language feature, then all existing programs will
23922394
start to receive compilation warnings about `#![feature]` directives which enabled
23932395
the new feature (because the directive is no longer necessary). However, if a

src/librustc/middle/cfg/construct.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
352352
hir::ExprBox(ref e) |
353353
hir::ExprAddrOf(_, ref e) |
354354
hir::ExprCast(ref e, _) |
355+
hir::ExprType(ref e, _) |
355356
hir::ExprUnary(_, ref e) |
356357
hir::ExprField(ref e, _) |
357358
hir::ExprTupField(ref e, _) => {

src/librustc/middle/check_const.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
784784
hir::ExprField(..) |
785785
hir::ExprTupField(..) |
786786
hir::ExprVec(_) |
787+
hir::ExprType(..) |
787788
hir::ExprTup(..) => {}
788789

789790
// Conditional control flow (possible to implement).

src/librustc/middle/const_eval.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +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, ty_hint, fn_args)),
11291130
hir::ExprTup(_) => Tuple(e.id),
11301131
hir::ExprStruct(..) => Struct(e.id),
11311132
hir::ExprIndex(ref arr, ref idx) => {

src/librustc/middle/expr_use_visitor.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
373373
match expr.node {
374374
hir::ExprPath(..) => { }
375375

376+
hir::ExprType(ref subexpr, _) => {
377+
self.walk_expr(&**subexpr)
378+
}
379+
376380
hir::ExprUnary(hir::UnDeref, ref base) => { // *base
377381
if !self.walk_overloaded_operator(expr, &**base, Vec::new(), PassArgs::ByRef) {
378382
self.select_from_expr(&**base);

src/librustc/middle/liveness.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
496496
hir::ExprBlock(..) | hir::ExprAssign(..) | hir::ExprAssignOp(..) |
497497
hir::ExprStruct(..) | hir::ExprRepeat(..) |
498498
hir::ExprInlineAsm(..) | hir::ExprBox(..) |
499-
hir::ExprRange(..) => {
499+
hir::ExprRange(..) | hir::ExprType(..) => {
500500
intravisit::walk_expr(ir, expr);
501501
}
502502
}
@@ -1160,6 +1160,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
11601160
hir::ExprBox(ref e) |
11611161
hir::ExprAddrOf(_, ref e) |
11621162
hir::ExprCast(ref e, _) |
1163+
hir::ExprType(ref e, _) |
11631164
hir::ExprUnary(_, ref e) => {
11641165
self.propagate_through_expr(&**e, succ)
11651166
}
@@ -1443,7 +1444,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
14431444
hir::ExprBlock(..) | hir::ExprAddrOf(..) |
14441445
hir::ExprStruct(..) | hir::ExprRepeat(..) |
14451446
hir::ExprClosure(..) | hir::ExprPath(..) | hir::ExprBox(..) |
1446-
hir::ExprRange(..) => {
1447+
hir::ExprRange(..) | hir::ExprType(..) => {
14471448
intravisit::walk_expr(this, expr);
14481449
}
14491450
}

src/librustc/middle/mem_categorization.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,10 @@ impl<'t, 'a,'tcx> MemCategorizationContext<'t, 'a, 'tcx> {
518518
self.cat_def(expr.id, expr.span, expr_ty, def)
519519
}
520520

521+
hir::ExprType(ref e, _) => {
522+
self.cat_expr(&**e)
523+
}
524+
521525
hir::ExprAddrOf(..) | hir::ExprCall(..) |
522526
hir::ExprAssign(..) | hir::ExprAssignOp(..) |
523527
hir::ExprClosure(..) | hir::ExprRet(..) |

src/librustc/middle/ty/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2114,6 +2114,10 @@ impl<'tcx> ctxt<'tcx> {
21142114
}
21152115
}
21162116

2117+
hir::ExprType(ref e, _) => {
2118+
self.expr_is_lval(e)
2119+
}
2120+
21172121
hir::ExprUnary(hir::UnDeref, _) |
21182122
hir::ExprField(..) |
21192123
hir::ExprTupField(..) |

src/librustc_back/svh.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ mod svh_visitor {
234234
SawExprUnary(hir::UnOp),
235235
SawExprLit(ast::Lit_),
236236
SawExprCast,
237+
SawExprType,
237238
SawExprIf,
238239
SawExprWhile,
239240
SawExprMatch,
@@ -262,6 +263,7 @@ mod svh_visitor {
262263
ExprUnary(op, _) => SawExprUnary(op),
263264
ExprLit(ref lit) => SawExprLit(lit.node.clone()),
264265
ExprCast(..) => SawExprCast,
266+
ExprType(..) => SawExprType,
265267
ExprIf(..) => SawExprIf,
266268
ExprWhile(..) => SawExprWhile,
267269
ExprLoop(_, id) => SawExprLoop(id.map(|id| id.name.as_str())),

src/librustc_front/fold.rs

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

0 commit comments

Comments
 (0)