about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-08-31 18:59:35 -0400
committerNiko Matsakis <niko@alum.mit.edu>2018-09-10 08:22:31 -0400
commitdd3cc9669acba363abdf4f1bf5744aea383ecc46 (patch)
tree748c8e198f9d13dd4691546b1ac3d8eb73dc98fb
parent22f9bcce042d8ab77c534f22173c31f9a9ee224e (diff)
downloadrust-dd3cc9669acba363abdf4f1bf5744aea383ecc46.tar.gz
rust-dd3cc9669acba363abdf4f1bf5744aea383ecc46.zip
add the `AscribeUserType` statement kind
Make it have the semantics of subtype.
-rw-r--r--src/librustc/ich/impls_mir.rs4
-rw-r--r--src/librustc/mir/mod.rs26
-rw-r--r--src/librustc/mir/visit.rs28
-rw-r--r--src/librustc/ty/context.rs4
-rw-r--r--src/librustc_codegen_llvm/mir/statement.rs2
-rw-r--r--src/librustc_mir/borrow_check/mod.rs4
-rw-r--r--src/librustc_mir/borrow_check/nll/constraint_generation.rs6
-rw-r--r--src/librustc_mir/borrow_check/nll/invalidation.rs4
-rw-r--r--src/librustc_mir/borrow_check/nll/renumber.rs10
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs33
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs49
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs2
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs2
-rw-r--r--src/librustc_mir/interpret/step.rs2
-rw-r--r--src/librustc_mir/transform/check_unsafety.rs2
-rw-r--r--src/librustc_mir/transform/cleanup_post_borrowck.rs20
-rw-r--r--src/librustc_mir/transform/mod.rs4
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs2
-rw-r--r--src/librustc_mir/transform/remove_noop_landing_pads.rs2
-rw-r--r--src/librustc_mir/transform/rustc_peek.rs2
-rw-r--r--src/librustc_passes/mir_stats.rs2
-rw-r--r--src/test/mir-opt/basic_assignment.rs2
22 files changed, 134 insertions, 78 deletions
diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs
index 8b7438cbe63..b0444848d61 100644
--- a/src/librustc/ich/impls_mir.rs
+++ b/src/librustc/ich/impls_mir.rs
@@ -255,9 +255,9 @@ for mir::StatementKind<'gcx> {
                 op.hash_stable(hcx, hasher);
                 places.hash_stable(hcx, hasher);
             }
-            mir::StatementKind::UserAssertTy(ref c_ty, ref local) => {
+            mir::StatementKind::AscribeUserType(ref place, ref c_ty) => {
+                place.hash_stable(hcx, hasher);
                 c_ty.hash_stable(hcx, hasher);
-                local.hash_stable(hcx, hasher);
             }
             mir::StatementKind::Nop => {}
             mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 708ce8e2031..8feb8f94946 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1636,22 +1636,14 @@ pub enum StatementKind<'tcx> {
     /// (The starting point(s) arise implicitly from borrows.)
     EndRegion(region::Scope),
 
-    /// Encodes a user's type assertion. These need to be preserved intact so that NLL can respect
-    /// them. For example:
+    /// Encodes a user's type ascription. These need to be preserved
+    /// intact so that NLL can respect them. For example:
     ///
-    ///     let (a, b): (T, U) = y;
+    ///     let a: T = y;
     ///
-    /// Here we would insert a `UserAssertTy<(T, U)>(y)` instruction to check that the type of `y`
-    /// is the right thing.
-    ///
-    /// `CanonicalTy` is used to capture "inference variables" from the user's types. For example:
-    ///
-    ///     let x: Vec<_> = ...;
-    ///     let y: &u32 = ...;
-    ///
-    /// would result in `Vec<?0>` and `&'?0 u32` respectively (where `?0` is a canonicalized
-    /// variable).
-    UserAssertTy(CanonicalTy<'tcx>, Local),
+    /// Here we would insert a `AscribeUserType` that ensures that the
+    /// type `Y` of `y` is a subtype of `T` (`Y <: T`).
+    AscribeUserType(Place<'tcx>, CanonicalTy<'tcx>),
 
     /// No-op. Useful for deleting instructions without affecting statement indices.
     Nop,
@@ -1728,8 +1720,8 @@ impl<'tcx> Debug for Statement<'tcx> {
                 ref outputs,
                 ref inputs,
             } => write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs),
-            UserAssertTy(ref c_ty, ref local) => {
-                write!(fmt, "UserAssertTy({:?}, {:?})", c_ty, local)
+            AscribeUserType(ref place, ref c_ty) => {
+                write!(fmt, "AscribeUserType({:?}, {:?})", place, c_ty)
             }
             Nop => write!(fmt, "nop"),
         }
@@ -2652,7 +2644,7 @@ EnumTypeFoldableImpl! {
         (StatementKind::InlineAsm) { asm, outputs, inputs },
         (StatementKind::Validate)(a, b),
         (StatementKind::EndRegion)(a),
-        (StatementKind::UserAssertTy)(a, b),
+        (StatementKind::AscribeUserType)(a, b),
         (StatementKind::Nop),
     }
 }
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index c7723fdf191..a70ec8a5c57 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -144,11 +144,11 @@ macro_rules! make_mir_visitor {
                 self.super_operand(operand, location);
             }
 
-            fn visit_user_assert_ty(&mut self,
-                                    c_ty: & $($mutability)* CanonicalTy<'tcx>,
-                                    local: & $($mutability)* Local,
-                                    location: Location) {
-                self.super_user_assert_ty(c_ty, local, location);
+            fn visit_ascribe_user_ty(&mut self,
+                                     place: & $($mutability)* Place<'tcx>,
+                                     c_ty: & $($mutability)* CanonicalTy<'tcx>,
+                                     location: Location) {
+                self.super_ascribe_user_ty(place, c_ty, location);
             }
 
             fn visit_place(&mut self,
@@ -386,9 +386,11 @@ macro_rules! make_mir_visitor {
                             self.visit_operand(input, location);
                         }
                     }
-                    StatementKind::UserAssertTy(ref $($mutability)* c_ty,
-                                                ref $($mutability)* local) => {
-                        self.visit_user_assert_ty(c_ty, local, location);
+                    StatementKind::AscribeUserType(
+                        ref $($mutability)* place,
+                        ref $($mutability)* c_ty,
+                    ) => {
+                        self.visit_ascribe_user_ty(place, c_ty, location);
                     }
                     StatementKind::Nop => {}
                 }
@@ -629,12 +631,12 @@ macro_rules! make_mir_visitor {
                 }
             }
 
-            fn super_user_assert_ty(&mut self,
-                                    c_ty: & $($mutability)* CanonicalTy<'tcx>,
-                                    local: & $($mutability)* Local,
-                                    location: Location) {
+            fn super_ascribe_user_ty(&mut self,
+                                     place: & $($mutability)* Place<'tcx>,
+                                     c_ty: & $($mutability)* CanonicalTy<'tcx>,
+                                     location: Location) {
+                self.visit_place(place, PlaceContext::Validate, location);
                 self.visit_canonical_ty(c_ty);
-                self.visit_local(local, PlaceContext::Validate, location);
             }
 
             fn super_place(&mut self,
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index eb6f7140a7d..83d6b715e95 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -356,8 +356,8 @@ pub struct TypeckTables<'tcx> {
     /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
     field_indices: ItemLocalMap<usize>,
 
-    /// Stores the canonicalized types provided by the user. See also `UserAssertTy` statement in
-    /// MIR.
+    /// Stores the canonicalized types provided by the user. See also
+    /// `AscribeUserType` statement in MIR.
     user_provided_tys: ItemLocalMap<CanonicalTy<'tcx>>,
 
     /// Stores the types for various nodes in the AST.  Note that this table
diff --git a/src/librustc_codegen_llvm/mir/statement.rs b/src/librustc_codegen_llvm/mir/statement.rs
index dd62a12553c..0cb8f99efc3 100644
--- a/src/librustc_codegen_llvm/mir/statement.rs
+++ b/src/librustc_codegen_llvm/mir/statement.rs
@@ -92,7 +92,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
             mir::StatementKind::ReadForMatch(_) |
             mir::StatementKind::EndRegion(_) |
             mir::StatementKind::Validate(..) |
-            mir::StatementKind::UserAssertTy(..) |
+            mir::StatementKind::AscribeUserType(..) |
             mir::StatementKind::Nop => bx,
         }
     }
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 76f6bcb5e56..60aeb92d91a 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -535,10 +535,10 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
                 // flow_state already handled).
             }
             StatementKind::Nop
-            | StatementKind::UserAssertTy(..)
+            | StatementKind::AscribeUserType(..)
             | StatementKind::Validate(..)
             | StatementKind::StorageLive(..) => {
-                // `Nop`, `UserAssertTy`, `Validate`, and `StorageLive` are irrelevant
+                // `Nop`, `AscribeUserType`, `Validate`, and `StorageLive` are irrelevant
                 // to borrow check.
             }
             StatementKind::StorageDead(local) => {
diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
index 457499ded56..1ec3506feb4 100644
--- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs
+++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs
@@ -17,7 +17,7 @@ use rustc::infer::InferCtxt;
 use rustc::mir::visit::TyContext;
 use rustc::mir::visit::Visitor;
 use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue};
-use rustc::mir::{Local, Statement, Terminator};
+use rustc::mir::{Statement, Terminator};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, RegionVid};
@@ -175,10 +175,10 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx
         self.super_terminator(block, terminator, location);
     }
 
-    fn visit_user_assert_ty(
+    fn visit_ascribe_user_ty(
         &mut self,
+        _place: &Place<'tcx>,
         _c_ty: &CanonicalTy<'tcx>,
-        _local: &Local,
         _location: Location,
     ) {
     }
diff --git a/src/librustc_mir/borrow_check/nll/invalidation.rs b/src/librustc_mir/borrow_check/nll/invalidation.rs
index f233a17597a..71345f22e44 100644
--- a/src/librustc_mir/borrow_check/nll/invalidation.rs
+++ b/src/librustc_mir/borrow_check/nll/invalidation.rs
@@ -144,10 +144,10 @@ impl<'cg, 'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cg, 'cx, 'tc
             // EndRegion matters to older NLL/MIR AST borrowck, not to alias NLL
             StatementKind::EndRegion(..) |
             StatementKind::Nop |
-            StatementKind::UserAssertTy(..) |
+            StatementKind::AscribeUserType(..) |
             StatementKind::Validate(..) |
             StatementKind::StorageLive(..) => {
-                // `Nop`, `UserAssertTy`, `Validate`, and `StorageLive` are irrelevant
+                // `Nop`, `AscribeUserType`, `Validate`, and `StorageLive` are irrelevant
                 // to borrow check.
             }
             StatementKind::StorageDead(local) => {
diff --git a/src/librustc_mir/borrow_check/nll/renumber.rs b/src/librustc_mir/borrow_check/nll/renumber.rs
index e1bd8530629..5de3247bad2 100644
--- a/src/librustc_mir/borrow_check/nll/renumber.rs
+++ b/src/librustc_mir/borrow_check/nll/renumber.rs
@@ -10,7 +10,7 @@
 
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable};
-use rustc::mir::{BasicBlock, Local, Location, Mir, Statement, StatementKind};
+use rustc::mir::{BasicBlock, Location, Mir, Place, Statement, StatementKind};
 use rustc::mir::visit::{MutVisitor, TyContext};
 use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
 
@@ -112,8 +112,12 @@ impl<'a, 'gcx, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'gcx, 'tcx> {
         debug!("visit_closure_substs: substs={:?}", substs);
     }
 
-    fn visit_user_assert_ty(&mut self, _c_ty: &mut CanonicalTy<'tcx>, _local: &mut Local,
-                            _location: Location) {
+    fn visit_ascribe_user_ty(
+        &mut self,
+        _place: &mut Place<'tcx>,
+        _c_ty: &mut CanonicalTy<'tcx>,
+        _location: Location,
+    ) {
         // User-assert-ty statements represent types that the user added explicitly.
         // We don't want to erase the regions from these types: rather, we want to
         // add them as constraints at type-check time.
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 82158acc9e6..682bce9266c 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -248,7 +248,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> {
         if let Some(user_ty) = constant.user_ty {
             if let Err(terr) =
                 self.cx
-                    .eq_canonical_type_and_type(user_ty, constant.ty, location.boring())
+                    .eq_user_type_and_type(user_ty, constant.ty, location.boring())
             {
                 span_mirbug!(
                     self,
@@ -850,13 +850,28 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
         )
     }
 
-    fn eq_canonical_type_and_type(
+    fn sub_type_and_user_type(
+        &mut self,
+        a: Ty<'tcx>,
+        b: CanonicalTy<'tcx>,
+        locations: Locations,
+    ) -> Fallible<()> {
+        relate_tys::sub_type_and_user_type(
+            self.infcx,
+            a,
+            b,
+            locations,
+            self.borrowck_context.as_mut().map(|x| &mut **x),
+        )
+    }
+
+    fn eq_user_type_and_type(
         &mut self,
         a: CanonicalTy<'tcx>,
         b: Ty<'tcx>,
         locations: Locations,
     ) -> Fallible<()> {
-        relate_tys::eq_canonical_type_and_type(
+        relate_tys::eq_user_type_and_type(
             self.infcx,
             a,
             b,
@@ -905,7 +920,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 }
 
                 if let Some(user_ty) = self.rvalue_user_ty(rv) {
-                    if let Err(terr) = self.eq_canonical_type_and_type(
+                    if let Err(terr) = self.eq_user_type_and_type(
                         user_ty,
                         rv_ty,
                         location.boring(),
@@ -955,15 +970,15 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                     );
                 };
             }
-            StatementKind::UserAssertTy(c_ty, local) => {
-                let local_ty = mir.local_decls()[local].ty;
-                if let Err(terr) = self.eq_canonical_type_and_type(c_ty, local_ty, Locations::All) {
+            StatementKind::AscribeUserType(ref place, c_ty) => {
+                let place_ty = place.ty(mir, tcx).to_ty(tcx);
+                if let Err(terr) = self.sub_type_and_user_type(place_ty, c_ty, Locations::All) {
                     span_mirbug!(
                         self,
                         stmt,
-                        "bad type assert ({:?} = {:?}): {:?}",
+                        "bad type assert ({:?} <: {:?}): {:?}",
+                        place_ty,
                         c_ty,
-                        local_ty,
                         terr
                     );
                 }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
index 195a284e69e..67b469c01b2 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/relate_tys.rs
@@ -22,6 +22,7 @@ use rustc::ty::{self, CanonicalTy, CanonicalVar, RegionVid, Ty, TyCtxt};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::IndexVec;
 
+/// Adds sufficient constraints to ensure that `a <: b`.
 pub(super) fn sub_types<'tcx>(
     infcx: &InferCtxt<'_, '_, 'tcx>,
     a: Ty<'tcx>,
@@ -40,6 +41,7 @@ pub(super) fn sub_types<'tcx>(
     Ok(())
 }
 
+/// Adds sufficient constraints to ensure that `a == b`.
 pub(super) fn eq_types<'tcx>(
     infcx: &InferCtxt<'_, '_, 'tcx>,
     a: Ty<'tcx>,
@@ -58,7 +60,43 @@ pub(super) fn eq_types<'tcx>(
     Ok(())
 }
 
-pub(super) fn eq_canonical_type_and_type<'tcx>(
+/// Adds sufficient constraints to ensure that `a <: b`, where `b` is
+/// a user-given type (which means it may have canonical variables
+/// encoding things like `_`).
+pub(super) fn sub_type_and_user_type<'tcx>(
+    infcx: &InferCtxt<'_, '_, 'tcx>,
+    a: Ty<'tcx>,
+    b: CanonicalTy<'tcx>,
+    locations: Locations,
+    borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
+) -> Fallible<()> {
+    debug!(
+        "sub_type_and_user_type(a={:?}, b={:?}, locations={:?})",
+        a, b, locations
+    );
+    let Canonical {
+        variables: b_variables,
+        value: b_value,
+    } = b;
+
+    // (*) The `TypeRelating` code assumes that the "canonical variables"
+    // appear in the "a" side, so start with `Contravariant` ambient
+    // variance to get the right relationship.
+
+    TypeRelating::new(
+        infcx,
+        ty::Variance::Contravariant, // (*)
+        locations,
+        borrowck_context,
+        b_variables,
+    ).relate(&b_value, &a)?;
+    Ok(())
+}
+
+/// Adds sufficient constraints to ensure that `a <: b`, where `b` is
+/// a user-given type (which means it may have canonical variables
+/// encoding things like `_`).
+pub(super) fn eq_user_type_and_type<'tcx>(
     infcx: &InferCtxt<'_, '_, 'tcx>,
     a: CanonicalTy<'tcx>,
     b: Ty<'tcx>,
@@ -66,16 +104,21 @@ pub(super) fn eq_canonical_type_and_type<'tcx>(
     borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
 ) -> Fallible<()> {
     debug!(
-        "eq_canonical_type_and_type(a={:?}, b={:?}, locations={:?})",
+        "eq_user_type_and_type(a={:?}, b={:?}, locations={:?})",
         a, b, locations
     );
     let Canonical {
         variables: a_variables,
         value: a_value,
     } = a;
+
+    // (*) The `TypeRelating` code assumes that the "canonical variables"
+    // appear in the "a" side, so start with `Contravariant` ambient
+    // variance to get the right relationship.
+
     TypeRelating::new(
         infcx,
-        ty::Variance::Invariant,
+        ty::Variance::Invariant, // (*)
         locations,
         borrowck_context,
         a_variables,
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index f42612b4b7a..cc92cdecc60 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -338,7 +338,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {
             mir::StatementKind::SetDiscriminant { .. } |
             mir::StatementKind::StorageLive(..) |
             mir::StatementKind::Validate(..) |
-            mir::StatementKind::UserAssertTy(..) |
+            mir::StatementKind::AscribeUserType(..) |
             mir::StatementKind::Nop => {}
 
         }
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index dde2e819fd2..5451d27082d 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -304,7 +304,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
             }
             StatementKind::EndRegion(_) |
             StatementKind::Validate(..) |
-            StatementKind::UserAssertTy(..) |
+            StatementKind::AscribeUserType(..) |
             StatementKind::Nop => {}
         }
     }
diff --git a/src/librustc_mir/interpret/step.rs b/src/librustc_mir/interpret/step.rs
index 545333e8791..cb8e1284d09 100644
--- a/src/librustc_mir/interpret/step.rs
+++ b/src/librustc_mir/interpret/step.rs
@@ -159,7 +159,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
             }
 
             EndRegion(..) => {}
-            UserAssertTy(..) => {}
+            AscribeUserType(..) => {}
 
             // Defined to do nothing. These are added by optimization passes, to avoid changing the
             // size of MIR constantly.
diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs
index ec7fd371a44..6fbc2f85c08 100644
--- a/src/librustc_mir/transform/check_unsafety.rs
+++ b/src/librustc_mir/transform/check_unsafety.rs
@@ -114,7 +114,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
             StatementKind::StorageDead(..) |
             StatementKind::EndRegion(..) |
             StatementKind::Validate(..) |
-            StatementKind::UserAssertTy(..) |
+            StatementKind::AscribeUserType(..) |
             StatementKind::Nop => {
                 // safe (at least as emitted during MIR construction)
             }
diff --git a/src/librustc_mir/transform/cleanup_post_borrowck.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs
index 256b1fd66e9..9edb1a1f76a 100644
--- a/src/librustc_mir/transform/cleanup_post_borrowck.rs
+++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs
@@ -12,7 +12,7 @@
 //!
 //!   - `CleanEndRegions`, that reduces the set of `EndRegion` statements
 //!     in the MIR.
-//!   - `CleanUserAssertTy`, that replaces all `UserAssertTy` statements
+//!   - `CleanAscribeUserType`, that replaces all `AscribeUserType` statements
 //!     with `Nop`.
 //!
 //! The `CleanEndRegions` "pass" is actually implemented as two
@@ -24,10 +24,10 @@
 //! MIR and removes any `EndRegion` that is applied to a region that
 //! was not seen in the previous pass.
 //!
-//! The `CleanUserAssertTy` pass runs at a distinct time from the
-//! `CleanEndRegions` pass. It is important that the `CleanUserAssertTy`
+//! The `CleanAscribeUserType` pass runs at a distinct time from the
+//! `CleanEndRegions` pass. It is important that the `CleanAscribeUserType`
 //! pass runs after the MIR borrowck so that the NLL type checker can
-//! perform the type assertion when it encounters the `UserAssertTy`
+//! perform the type assertion when it encounters the `AscribeUserType`
 //! statements.
 
 use rustc_data_structures::fx::FxHashSet;
@@ -110,26 +110,26 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DeleteTrivialEndRegions<'a> {
     }
 }
 
-pub struct CleanUserAssertTy;
+pub struct CleanAscribeUserType;
 
-pub struct DeleteUserAssertTy;
+pub struct DeleteAscribeUserType;
 
-impl MirPass for CleanUserAssertTy {
+impl MirPass for CleanAscribeUserType {
     fn run_pass<'a, 'tcx>(&self,
                           _tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           _source: MirSource,
                           mir: &mut Mir<'tcx>) {
-        let mut delete = DeleteUserAssertTy;
+        let mut delete = DeleteAscribeUserType;
         delete.visit_mir(mir);
     }
 }
 
-impl<'tcx> MutVisitor<'tcx> for DeleteUserAssertTy {
+impl<'tcx> MutVisitor<'tcx> for DeleteAscribeUserType {
     fn visit_statement(&mut self,
                        block: BasicBlock,
                        statement: &mut Statement<'tcx>,
                        location: Location) {
-        if let StatementKind::UserAssertTy(..) = statement.kind {
+        if let StatementKind::AscribeUserType(..) = statement.kind {
             statement.make_nop();
         }
         self.super_statement(block, statement, location);
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 1e05b07030e..19fb35be9d4 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -238,8 +238,8 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
         simplify_branches::SimplifyBranches::new("initial"),
         remove_noop_landing_pads::RemoveNoopLandingPads,
         simplify::SimplifyCfg::new("early-opt"),
-        // Remove all `UserAssertTy` statements.
-        cleanup_post_borrowck::CleanUserAssertTy,
+        // Remove all `AscribeUserType` statements.
+        cleanup_post_borrowck::CleanAscribeUserType,
 
         // These next passes must be executed together
         add_call_guards::CriticalCallEdges,
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 81fc235c233..a2175dce33a 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1098,7 +1098,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 StatementKind::InlineAsm {..} |
                 StatementKind::EndRegion(_) |
                 StatementKind::Validate(..) |
-                StatementKind::UserAssertTy(..) |
+                StatementKind::AscribeUserType(..) |
                 StatementKind::Nop => {}
             }
         });
diff --git a/src/librustc_mir/transform/remove_noop_landing_pads.rs b/src/librustc_mir/transform/remove_noop_landing_pads.rs
index 04a7a81eb12..a2561d3d793 100644
--- a/src/librustc_mir/transform/remove_noop_landing_pads.rs
+++ b/src/librustc_mir/transform/remove_noop_landing_pads.rs
@@ -53,7 +53,7 @@ impl RemoveNoopLandingPads {
                 StatementKind::StorageLive(_) |
                 StatementKind::StorageDead(_) |
                 StatementKind::EndRegion(_) |
-                StatementKind::UserAssertTy(..) |
+                StatementKind::AscribeUserType(..) |
                 StatementKind::Nop => {
                     // These are all nops in a landing pad (there's some
                     // borrowck interaction between EndRegion and storage
diff --git a/src/librustc_mir/transform/rustc_peek.rs b/src/librustc_mir/transform/rustc_peek.rs
index 9faaeea3f5b..f3e0f557363 100644
--- a/src/librustc_mir/transform/rustc_peek.rs
+++ b/src/librustc_mir/transform/rustc_peek.rs
@@ -163,7 +163,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             mir::StatementKind::InlineAsm { .. } |
             mir::StatementKind::EndRegion(_) |
             mir::StatementKind::Validate(..) |
-            mir::StatementKind::UserAssertTy(..) |
+            mir::StatementKind::AscribeUserType(..) |
             mir::StatementKind::Nop => continue,
             mir::StatementKind::SetDiscriminant{ .. } =>
                 span_bug!(stmt.source_info.span,
diff --git a/src/librustc_passes/mir_stats.rs b/src/librustc_passes/mir_stats.rs
index 3206fa6e172..7c9f77042cb 100644
--- a/src/librustc_passes/mir_stats.rs
+++ b/src/librustc_passes/mir_stats.rs
@@ -92,7 +92,7 @@ impl<'a, 'tcx> mir_visit::Visitor<'tcx> for StatCollector<'a, 'tcx> {
             StatementKind::StorageLive(..) => "StatementKind::StorageLive",
             StatementKind::StorageDead(..) => "StatementKind::StorageDead",
             StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm",
-            StatementKind::UserAssertTy(..) => "StatementKind::UserAssertTy",
+            StatementKind::AscribeUserType(..) => "StatementKind::AscribeUserType",
             StatementKind::Nop => "StatementKind::Nop",
         }, &statement.kind);
         self.super_statement(block, statement, location);
diff --git a/src/test/mir-opt/basic_assignment.rs b/src/test/mir-opt/basic_assignment.rs
index 54b7a3821ca..503e8e009b9 100644
--- a/src/test/mir-opt/basic_assignment.rs
+++ b/src/test/mir-opt/basic_assignment.rs
@@ -48,7 +48,7 @@ fn main() {
 //         _2 = move _3;
 //         StorageDead(_3);
 //         StorageLive(_4);
-//         UserAssertTy(Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> }, _4);
+//         AscribeUserType(_4, Canonical { variables: [], value: std::option::Option<std::boxed::Box<u32>> });
 //         _4 = std::option::Option<std::boxed::Box<u32>>::None;
 //         StorageLive(_5);
 //         StorageLive(_6);