提交 dd3cc966 编写于 作者: N Niko Matsakis

add the `AscribeUserType` statement kind

Make it have the semantics of subtype.
上级 22f9bcce
...@@ -255,9 +255,9 @@ fn hash_stable<W: StableHasherResult>(&self, ...@@ -255,9 +255,9 @@ fn hash_stable<W: StableHasherResult>(&self,
op.hash_stable(hcx, hasher); op.hash_stable(hcx, hasher);
places.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); c_ty.hash_stable(hcx, hasher);
local.hash_stable(hcx, hasher);
} }
mir::StatementKind::Nop => {} mir::StatementKind::Nop => {}
mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => { mir::StatementKind::InlineAsm { ref asm, ref outputs, ref inputs } => {
......
...@@ -1636,22 +1636,14 @@ pub enum StatementKind<'tcx> { ...@@ -1636,22 +1636,14 @@ pub enum StatementKind<'tcx> {
/// (The starting point(s) arise implicitly from borrows.) /// (The starting point(s) arise implicitly from borrows.)
EndRegion(region::Scope), EndRegion(region::Scope),
/// Encodes a user's type assertion. These need to be preserved intact so that NLL can respect /// Encodes a user's type ascription. These need to be preserved
/// them. For example: /// 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` /// Here we would insert a `AscribeUserType` that ensures that the
/// is the right thing. /// type `Y` of `y` is a subtype of `T` (`Y <: T`).
/// AscribeUserType(Place<'tcx>, CanonicalTy<'tcx>),
/// `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),
/// No-op. Useful for deleting instructions without affecting statement indices. /// No-op. Useful for deleting instructions without affecting statement indices.
Nop, Nop,
...@@ -1728,8 +1720,8 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { ...@@ -1728,8 +1720,8 @@ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
ref outputs, ref outputs,
ref inputs, ref inputs,
} => write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs), } => write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs),
UserAssertTy(ref c_ty, ref local) => { AscribeUserType(ref place, ref c_ty) => {
write!(fmt, "UserAssertTy({:?}, {:?})", c_ty, local) write!(fmt, "AscribeUserType({:?}, {:?})", place, c_ty)
} }
Nop => write!(fmt, "nop"), Nop => write!(fmt, "nop"),
} }
...@@ -2652,7 +2644,7 @@ impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> { ...@@ -2652,7 +2644,7 @@ impl<'tcx> TypeFoldable<'tcx> for StatementKind<'tcx> {
(StatementKind::InlineAsm) { asm, outputs, inputs }, (StatementKind::InlineAsm) { asm, outputs, inputs },
(StatementKind::Validate)(a, b), (StatementKind::Validate)(a, b),
(StatementKind::EndRegion)(a), (StatementKind::EndRegion)(a),
(StatementKind::UserAssertTy)(a, b), (StatementKind::AscribeUserType)(a, b),
(StatementKind::Nop), (StatementKind::Nop),
} }
} }
......
...@@ -144,11 +144,11 @@ fn visit_operand(&mut self, ...@@ -144,11 +144,11 @@ fn visit_operand(&mut self,
self.super_operand(operand, location); self.super_operand(operand, location);
} }
fn visit_user_assert_ty(&mut self, fn visit_ascribe_user_ty(&mut self,
place: & $($mutability)* Place<'tcx>,
c_ty: & $($mutability)* CanonicalTy<'tcx>, c_ty: & $($mutability)* CanonicalTy<'tcx>,
local: & $($mutability)* Local,
location: Location) { location: Location) {
self.super_user_assert_ty(c_ty, local, location); self.super_ascribe_user_ty(place, c_ty, location);
} }
fn visit_place(&mut self, fn visit_place(&mut self,
...@@ -386,9 +386,11 @@ fn super_statement(&mut self, ...@@ -386,9 +386,11 @@ fn super_statement(&mut self,
self.visit_operand(input, location); self.visit_operand(input, location);
} }
} }
StatementKind::UserAssertTy(ref $($mutability)* c_ty, StatementKind::AscribeUserType(
ref $($mutability)* local) => { ref $($mutability)* place,
self.visit_user_assert_ty(c_ty, local, location); ref $($mutability)* c_ty,
) => {
self.visit_ascribe_user_ty(place, c_ty, location);
} }
StatementKind::Nop => {} StatementKind::Nop => {}
} }
...@@ -629,12 +631,12 @@ fn super_operand(&mut self, ...@@ -629,12 +631,12 @@ fn super_operand(&mut self,
} }
} }
fn super_user_assert_ty(&mut self, fn super_ascribe_user_ty(&mut self,
place: & $($mutability)* Place<'tcx>,
c_ty: & $($mutability)* CanonicalTy<'tcx>, c_ty: & $($mutability)* CanonicalTy<'tcx>,
local: & $($mutability)* Local,
location: Location) { location: Location) {
self.visit_place(place, PlaceContext::Validate, location);
self.visit_canonical_ty(c_ty); self.visit_canonical_ty(c_ty);
self.visit_local(local, PlaceContext::Validate, location);
} }
fn super_place(&mut self, fn super_place(&mut self,
......
...@@ -356,8 +356,8 @@ pub struct TypeckTables<'tcx> { ...@@ -356,8 +356,8 @@ pub struct TypeckTables<'tcx> {
/// belongs, but it may not exist if it's a tuple field (`tuple.0`). /// belongs, but it may not exist if it's a tuple field (`tuple.0`).
field_indices: ItemLocalMap<usize>, field_indices: ItemLocalMap<usize>,
/// Stores the canonicalized types provided by the user. See also `UserAssertTy` statement in /// Stores the canonicalized types provided by the user. See also
/// MIR. /// `AscribeUserType` statement in MIR.
user_provided_tys: ItemLocalMap<CanonicalTy<'tcx>>, user_provided_tys: ItemLocalMap<CanonicalTy<'tcx>>,
/// Stores the types for various nodes in the AST. Note that this table /// Stores the types for various nodes in the AST. Note that this table
......
...@@ -92,7 +92,7 @@ pub fn codegen_statement(&mut self, ...@@ -92,7 +92,7 @@ pub fn codegen_statement(&mut self,
mir::StatementKind::ReadForMatch(_) | mir::StatementKind::ReadForMatch(_) |
mir::StatementKind::EndRegion(_) | mir::StatementKind::EndRegion(_) |
mir::StatementKind::Validate(..) | mir::StatementKind::Validate(..) |
mir::StatementKind::UserAssertTy(..) | mir::StatementKind::AscribeUserType(..) |
mir::StatementKind::Nop => bx, mir::StatementKind::Nop => bx,
} }
} }
......
...@@ -535,10 +535,10 @@ fn visit_statement_entry( ...@@ -535,10 +535,10 @@ fn visit_statement_entry(
// flow_state already handled). // flow_state already handled).
} }
StatementKind::Nop StatementKind::Nop
| StatementKind::UserAssertTy(..) | StatementKind::AscribeUserType(..)
| StatementKind::Validate(..) | StatementKind::Validate(..)
| StatementKind::StorageLive(..) => { | StatementKind::StorageLive(..) => {
// `Nop`, `UserAssertTy`, `Validate`, and `StorageLive` are irrelevant // `Nop`, `AscribeUserType`, `Validate`, and `StorageLive` are irrelevant
// to borrow check. // to borrow check.
} }
StatementKind::StorageDead(local) => { StatementKind::StorageDead(local) => {
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
use rustc::mir::visit::TyContext; use rustc::mir::visit::TyContext;
use rustc::mir::visit::Visitor; use rustc::mir::visit::Visitor;
use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue}; 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::fold::TypeFoldable;
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, RegionVid}; use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, RegionVid};
...@@ -175,10 +175,10 @@ fn visit_terminator( ...@@ -175,10 +175,10 @@ fn visit_terminator(
self.super_terminator(block, terminator, location); self.super_terminator(block, terminator, location);
} }
fn visit_user_assert_ty( fn visit_ascribe_user_ty(
&mut self, &mut self,
_place: &Place<'tcx>,
_c_ty: &CanonicalTy<'tcx>, _c_ty: &CanonicalTy<'tcx>,
_local: &Local,
_location: Location, _location: Location,
) { ) {
} }
......
...@@ -144,10 +144,10 @@ fn visit_statement(&mut self, ...@@ -144,10 +144,10 @@ fn visit_statement(&mut self,
// EndRegion matters to older NLL/MIR AST borrowck, not to alias NLL // EndRegion matters to older NLL/MIR AST borrowck, not to alias NLL
StatementKind::EndRegion(..) | StatementKind::EndRegion(..) |
StatementKind::Nop | StatementKind::Nop |
StatementKind::UserAssertTy(..) | StatementKind::AscribeUserType(..) |
StatementKind::Validate(..) | StatementKind::Validate(..) |
StatementKind::StorageLive(..) => { StatementKind::StorageLive(..) => {
// `Nop`, `UserAssertTy`, `Validate`, and `StorageLive` are irrelevant // `Nop`, `AscribeUserType`, `Validate`, and `StorageLive` are irrelevant
// to borrow check. // to borrow check.
} }
StatementKind::StorageDead(local) => { StatementKind::StorageDead(local) => {
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, Ty, TypeFoldable}; 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::mir::visit::{MutVisitor, TyContext};
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin}; use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
...@@ -112,8 +112,12 @@ fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: L ...@@ -112,8 +112,12 @@ fn visit_closure_substs(&mut self, substs: &mut ClosureSubsts<'tcx>, location: L
debug!("visit_closure_substs: substs={:?}", substs); debug!("visit_closure_substs: substs={:?}", substs);
} }
fn visit_user_assert_ty(&mut self, _c_ty: &mut CanonicalTy<'tcx>, _local: &mut Local, fn visit_ascribe_user_ty(
_location: Location) { &mut self,
_place: &mut Place<'tcx>,
_c_ty: &mut CanonicalTy<'tcx>,
_location: Location,
) {
// User-assert-ty statements represent types that the user added explicitly. // 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 // We don't want to erase the regions from these types: rather, we want to
// add them as constraints at type-check time. // add them as constraints at type-check time.
......
...@@ -248,7 +248,7 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) { ...@@ -248,7 +248,7 @@ fn visit_constant(&mut self, constant: &Constant<'tcx>, location: Location) {
if let Some(user_ty) = constant.user_ty { if let Some(user_ty) = constant.user_ty {
if let Err(terr) = if let Err(terr) =
self.cx 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!( span_mirbug!(
self, self,
...@@ -850,13 +850,28 @@ fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> Fallib ...@@ -850,13 +850,28 @@ fn eq_types(&mut self, a: Ty<'tcx>, b: Ty<'tcx>, locations: Locations) -> Fallib
) )
} }
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, &mut self,
a: CanonicalTy<'tcx>, a: CanonicalTy<'tcx>,
b: Ty<'tcx>, b: Ty<'tcx>,
locations: Locations, locations: Locations,
) -> Fallible<()> { ) -> Fallible<()> {
relate_tys::eq_canonical_type_and_type( relate_tys::eq_user_type_and_type(
self.infcx, self.infcx,
a, a,
b, b,
...@@ -905,7 +920,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca ...@@ -905,7 +920,7 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
} }
if let Some(user_ty) = self.rvalue_user_ty(rv) { 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, user_ty,
rv_ty, rv_ty,
location.boring(), location.boring(),
...@@ -955,15 +970,15 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca ...@@ -955,15 +970,15 @@ fn check_stmt(&mut self, mir: &Mir<'tcx>, stmt: &Statement<'tcx>, location: Loca
); );
}; };
} }
StatementKind::UserAssertTy(c_ty, local) => { StatementKind::AscribeUserType(ref place, c_ty) => {
let local_ty = mir.local_decls()[local].ty; let place_ty = place.ty(mir, tcx).to_ty(tcx);
if let Err(terr) = self.eq_canonical_type_and_type(c_ty, local_ty, Locations::All) { if let Err(terr) = self.sub_type_and_user_type(place_ty, c_ty, Locations::All) {
span_mirbug!( span_mirbug!(
self, self,
stmt, stmt,
"bad type assert ({:?} = {:?}): {:?}", "bad type assert ({:?} <: {:?}): {:?}",
place_ty,
c_ty, c_ty,
local_ty,
terr terr
); );
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::indexed_vec::IndexVec; use rustc_data_structures::indexed_vec::IndexVec;
/// Adds sufficient constraints to ensure that `a <: b`.
pub(super) fn sub_types<'tcx>( pub(super) fn sub_types<'tcx>(
infcx: &InferCtxt<'_, '_, 'tcx>, infcx: &InferCtxt<'_, '_, 'tcx>,
a: Ty<'tcx>, a: Ty<'tcx>,
...@@ -40,6 +41,7 @@ pub(super) fn sub_types<'tcx>( ...@@ -40,6 +41,7 @@ pub(super) fn sub_types<'tcx>(
Ok(()) Ok(())
} }
/// Adds sufficient constraints to ensure that `a == b`.
pub(super) fn eq_types<'tcx>( pub(super) fn eq_types<'tcx>(
infcx: &InferCtxt<'_, '_, 'tcx>, infcx: &InferCtxt<'_, '_, 'tcx>,
a: Ty<'tcx>, a: Ty<'tcx>,
...@@ -58,7 +60,43 @@ pub(super) fn eq_types<'tcx>( ...@@ -58,7 +60,43 @@ pub(super) fn eq_types<'tcx>(
Ok(()) 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>, infcx: &InferCtxt<'_, '_, 'tcx>,
a: CanonicalTy<'tcx>, a: CanonicalTy<'tcx>,
b: Ty<'tcx>, b: Ty<'tcx>,
...@@ -66,16 +104,21 @@ pub(super) fn eq_canonical_type_and_type<'tcx>( ...@@ -66,16 +104,21 @@ pub(super) fn eq_canonical_type_and_type<'tcx>(
borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>, borrowck_context: Option<&mut BorrowCheckContext<'_, 'tcx>>,
) -> Fallible<()> { ) -> Fallible<()> {
debug!( debug!(
"eq_canonical_type_and_type(a={:?}, b={:?}, locations={:?})", "eq_user_type_and_type(a={:?}, b={:?}, locations={:?})",
a, b, locations a, b, locations
); );
let Canonical { let Canonical {
variables: a_variables, variables: a_variables,
value: a_value, value: a_value,
} = a; } = 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( TypeRelating::new(
infcx, infcx,
ty::Variance::Invariant, ty::Variance::Invariant, // (*)
locations, locations,
borrowck_context, borrowck_context,
a_variables, a_variables,
......
...@@ -338,7 +338,7 @@ fn statement_effect(&self, sets: &mut BlockSets<BorrowIndex>, location: Location ...@@ -338,7 +338,7 @@ fn statement_effect(&self, sets: &mut BlockSets<BorrowIndex>, location: Location
mir::StatementKind::SetDiscriminant { .. } | mir::StatementKind::SetDiscriminant { .. } |
mir::StatementKind::StorageLive(..) | mir::StatementKind::StorageLive(..) |
mir::StatementKind::Validate(..) | mir::StatementKind::Validate(..) |
mir::StatementKind::UserAssertTy(..) | mir::StatementKind::AscribeUserType(..) |
mir::StatementKind::Nop => {} mir::StatementKind::Nop => {}
} }
......
...@@ -304,7 +304,7 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) { ...@@ -304,7 +304,7 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
} }
StatementKind::EndRegion(_) | StatementKind::EndRegion(_) |
StatementKind::Validate(..) | StatementKind::Validate(..) |
StatementKind::UserAssertTy(..) | StatementKind::AscribeUserType(..) |
StatementKind::Nop => {} StatementKind::Nop => {}
} }
} }
......
...@@ -159,7 +159,7 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> { ...@@ -159,7 +159,7 @@ fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx> {
} }
EndRegion(..) => {} EndRegion(..) => {}
UserAssertTy(..) => {} AscribeUserType(..) => {}
// Defined to do nothing. These are added by optimization passes, to avoid changing the // Defined to do nothing. These are added by optimization passes, to avoid changing the
// size of MIR constantly. // size of MIR constantly.
......
...@@ -114,7 +114,7 @@ fn visit_statement(&mut self, ...@@ -114,7 +114,7 @@ fn visit_statement(&mut self,
StatementKind::StorageDead(..) | StatementKind::StorageDead(..) |
StatementKind::EndRegion(..) | StatementKind::EndRegion(..) |
StatementKind::Validate(..) | StatementKind::Validate(..) |
StatementKind::UserAssertTy(..) | StatementKind::AscribeUserType(..) |
StatementKind::Nop => { StatementKind::Nop => {
// safe (at least as emitted during MIR construction) // safe (at least as emitted during MIR construction)
} }
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
//! //!
//! - `CleanEndRegions`, that reduces the set of `EndRegion` statements //! - `CleanEndRegions`, that reduces the set of `EndRegion` statements
//! in the MIR. //! in the MIR.
//! - `CleanUserAssertTy`, that replaces all `UserAssertTy` statements //! - `CleanAscribeUserType`, that replaces all `AscribeUserType` statements
//! with `Nop`. //! with `Nop`.
//! //!
//! The `CleanEndRegions` "pass" is actually implemented as two //! The `CleanEndRegions` "pass" is actually implemented as two
...@@ -24,10 +24,10 @@ ...@@ -24,10 +24,10 @@
//! MIR and removes any `EndRegion` that is applied to a region that //! MIR and removes any `EndRegion` that is applied to a region that
//! was not seen in the previous pass. //! was not seen in the previous pass.
//! //!
//! The `CleanUserAssertTy` pass runs at a distinct time from the //! The `CleanAscribeUserType` pass runs at a distinct time from the
//! `CleanEndRegions` pass. It is important that the `CleanUserAssertTy` //! `CleanEndRegions` pass. It is important that the `CleanAscribeUserType`
//! pass runs after the MIR borrowck so that the NLL type checker can //! 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. //! statements.
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
...@@ -110,26 +110,26 @@ fn visit_statement(&mut self, ...@@ -110,26 +110,26 @@ fn visit_statement(&mut self,
} }
} }
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, fn run_pass<'a, 'tcx>(&self,
_tcx: TyCtxt<'a, 'tcx, 'tcx>, _tcx: TyCtxt<'a, 'tcx, 'tcx>,
_source: MirSource, _source: MirSource,
mir: &mut Mir<'tcx>) { mir: &mut Mir<'tcx>) {
let mut delete = DeleteUserAssertTy; let mut delete = DeleteAscribeUserType;
delete.visit_mir(mir); delete.visit_mir(mir);
} }
} }
impl<'tcx> MutVisitor<'tcx> for DeleteUserAssertTy { impl<'tcx> MutVisitor<'tcx> for DeleteAscribeUserType {
fn visit_statement(&mut self, fn visit_statement(&mut self,
block: BasicBlock, block: BasicBlock,
statement: &mut Statement<'tcx>, statement: &mut Statement<'tcx>,
location: Location) { location: Location) {
if let StatementKind::UserAssertTy(..) = statement.kind { if let StatementKind::AscribeUserType(..) = statement.kind {
statement.make_nop(); statement.make_nop();
} }
self.super_statement(block, statement, location); self.super_statement(block, statement, location);
......
...@@ -238,8 +238,8 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ...@@ -238,8 +238,8 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
simplify_branches::SimplifyBranches::new("initial"), simplify_branches::SimplifyBranches::new("initial"),
remove_noop_landing_pads::RemoveNoopLandingPads, remove_noop_landing_pads::RemoveNoopLandingPads,
simplify::SimplifyCfg::new("early-opt"), simplify::SimplifyCfg::new("early-opt"),
// Remove all `UserAssertTy` statements. // Remove all `AscribeUserType` statements.
cleanup_post_borrowck::CleanUserAssertTy, cleanup_post_borrowck::CleanAscribeUserType,
// These next passes must be executed together // These next passes must be executed together
add_call_guards::CriticalCallEdges, add_call_guards::CriticalCallEdges,
......
...@@ -1098,7 +1098,7 @@ fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>, locat ...@@ -1098,7 +1098,7 @@ fn visit_statement(&mut self, bb: BasicBlock, statement: &Statement<'tcx>, locat
StatementKind::InlineAsm {..} | StatementKind::InlineAsm {..} |
StatementKind::EndRegion(_) | StatementKind::EndRegion(_) |
StatementKind::Validate(..) | StatementKind::Validate(..) |
StatementKind::UserAssertTy(..) | StatementKind::AscribeUserType(..) |
StatementKind::Nop => {} StatementKind::Nop => {}
} }
}); });
......
...@@ -53,7 +53,7 @@ fn is_nop_landing_pad( ...@@ -53,7 +53,7 @@ fn is_nop_landing_pad(
StatementKind::StorageLive(_) | StatementKind::StorageLive(_) |
StatementKind::StorageDead(_) | StatementKind::StorageDead(_) |
StatementKind::EndRegion(_) | StatementKind::EndRegion(_) |
StatementKind::UserAssertTy(..) | StatementKind::AscribeUserType(..) |
StatementKind::Nop => { StatementKind::Nop => {
// These are all nops in a landing pad (there's some // These are all nops in a landing pad (there's some
// borrowck interaction between EndRegion and storage // borrowck interaction between EndRegion and storage
......
...@@ -163,7 +163,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ...@@ -163,7 +163,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir::StatementKind::InlineAsm { .. } | mir::StatementKind::InlineAsm { .. } |
mir::StatementKind::EndRegion(_) | mir::StatementKind::EndRegion(_) |
mir::StatementKind::Validate(..) | mir::StatementKind::Validate(..) |
mir::StatementKind::UserAssertTy(..) | mir::StatementKind::AscribeUserType(..) |
mir::StatementKind::Nop => continue, mir::StatementKind::Nop => continue,
mir::StatementKind::SetDiscriminant{ .. } => mir::StatementKind::SetDiscriminant{ .. } =>
span_bug!(stmt.source_info.span, span_bug!(stmt.source_info.span,
......
...@@ -92,7 +92,7 @@ fn visit_statement(&mut self, ...@@ -92,7 +92,7 @@ fn visit_statement(&mut self,
StatementKind::StorageLive(..) => "StatementKind::StorageLive", StatementKind::StorageLive(..) => "StatementKind::StorageLive",
StatementKind::StorageDead(..) => "StatementKind::StorageDead", StatementKind::StorageDead(..) => "StatementKind::StorageDead",
StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm", StatementKind::InlineAsm { .. } => "StatementKind::InlineAsm",
StatementKind::UserAssertTy(..) => "StatementKind::UserAssertTy", StatementKind::AscribeUserType(..) => "StatementKind::AscribeUserType",
StatementKind::Nop => "StatementKind::Nop", StatementKind::Nop => "StatementKind::Nop",
}, &statement.kind); }, &statement.kind);
self.super_statement(block, statement, location); self.super_statement(block, statement, location);
......
...@@ -48,7 +48,7 @@ fn main() { ...@@ -48,7 +48,7 @@ fn main() {
// _2 = move _3; // _2 = move _3;
// StorageDead(_3); // StorageDead(_3);
// StorageLive(_4); // 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; // _4 = std::option::Option<std::boxed::Box<u32>>::None;
// StorageLive(_5); // StorageLive(_5);
// StorageLive(_6); // StorageLive(_6);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册