Lower type ascriptions to HAIR and MIR

This commit is contained in:
Keith Yeung 2018-09-20 18:43:35 -07:00
parent 8132d4e100
commit fba9d14779
7 changed files with 73 additions and 4 deletions

View file

@ -16,6 +16,7 @@ use build::{BlockAnd, BlockAndExtension, Builder};
use hair::*;
use rustc::mir::interpret::EvalErrorKind::BoundsCheck;
use rustc::mir::*;
use rustc::ty::Variance;
use rustc_data_structures::indexed_vec::Idx;
@ -136,6 +137,40 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
ty: expr.ty,
}))),
ExprKind::PlaceTypeAscription { source, user_ty } => {
let place = unpack!(block = this.as_place(block, source));
this.cfg.push(
block,
Statement {
source_info,
kind: StatementKind::AscribeUserType(
place.clone(),
Variance::Invariant,
user_ty,
),
},
);
block.and(place)
}
ExprKind::ValueTypeAscription { source, user_ty } => {
let source = this.hir.mirror(source);
let temp = unpack!(
block = this.as_temp(block, source.temp_lifetime, source, mutability)
);
this.cfg.push(
block,
Statement {
source_info,
kind: StatementKind::AscribeUserType(
Place::Local(temp.clone()),
Variance::Invariant,
user_ty,
),
},
);
block.and(Place::Local(temp))
}
ExprKind::Array { .. }
| ExprKind::Tuple { .. }
| ExprKind::Adt { .. }

View file

@ -386,7 +386,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
| ExprKind::Continue { .. }
| ExprKind::Return { .. }
| ExprKind::InlineAsm { .. }
| ExprKind::StaticRef { .. } => {
| ExprKind::StaticRef { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. } => {
// these do not have corresponding `Rvalue` variants,
// so make an operand and then return that
debug_assert!(match Category::of(&expr.kind) {

View file

@ -50,7 +50,9 @@ impl Category {
| ExprKind::Index { .. }
| ExprKind::SelfRef
| ExprKind::VarRef { .. }
| ExprKind::StaticRef { .. } => Some(Category::Place),
| ExprKind::StaticRef { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. } => Some(Category::Place),
ExprKind::LogicalOp { .. }
| ExprKind::If { .. }

View file

@ -391,7 +391,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
| ExprKind::Adt { .. }
| ExprKind::Closure { .. }
| ExprKind::Literal { .. }
| ExprKind::Yield { .. } => {
| ExprKind::Yield { .. }
| ExprKind::PlaceTypeAscription { .. }
| ExprKind::ValueTypeAscription { .. } => {
debug_assert!(match Category::of(&expr.kind).unwrap() {
Category::Rvalue(RvalueFunc::Into) => false,
_ => true,

View file

@ -718,7 +718,23 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
ExprKind::Cast { source }
}
}
hir::ExprKind::Type(ref source, _) => return source.make_mirror(cx),
hir::ExprKind::Type(ref source, ref ty) => {
let user_provided_tys = cx.tables.user_provided_tys();
let user_ty = *user_provided_tys
.get(ty.hir_id)
.expect(&format!("{:?} not found in user_provided_tys, source: {:?}", ty, source));
if source.is_place_expr() {
ExprKind::PlaceTypeAscription {
source: source.to_ref(),
user_ty,
}
} else {
ExprKind::ValueTypeAscription {
source: source.to_ref(),
user_ty,
}
}
}
hir::ExprKind::Box(ref value) => {
ExprKind::Box {
value: value.to_ref(),

View file

@ -268,6 +268,16 @@ pub enum ExprKind<'tcx> {
fields: Vec<FieldExprRef<'tcx>>,
base: Option<FruInfo<'tcx>>
},
PlaceTypeAscription {
source: ExprRef<'tcx>,
/// Type that the user gave to this expression
user_ty: CanonicalTy<'tcx>,
},
ValueTypeAscription {
source: ExprRef<'tcx>,
/// Type that the user gave to this expression
user_ty: CanonicalTy<'tcx>,
},
Closure {
closure_id: DefId,
substs: UpvarSubsts<'tcx>,

View file

@ -4118,6 +4118,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
hir::ExprKind::Type(ref e, ref t) => {
let ty = self.to_ty(&t);
self.check_expr_eq_type(&e, ty);
let c_ty = self.infcx.canonicalize_response(&ty);
self.tables.borrow_mut().user_provided_tys_mut().insert(t.hir_id, c_ty);
ty
}
hir::ExprKind::Array(ref args) => {