diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 4f68569c600..94b85247bb8 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -606,3 +606,5 @@ impl<'a, 'gcx> HashStable> for mir::UserTypeAnnotation< } } } + +impl_stable_hash_for!(struct mir::UserTypeProjection<'tcx> { base }); diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 7c3d4713572..d2f67a74420 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -710,7 +710,7 @@ pub struct LocalDecl<'tcx> { /// e.g. via `let x: T`, then we carry that type here. The MIR /// borrow checker needs this information since it can affect /// region inference. - pub user_ty: Option<(UserTypeAnnotation<'tcx>, Span)>, + pub user_ty: Option<(UserTypeProjection<'tcx>, Span)>, /// Name of the local, used in debuginfo and pretty-printing. /// @@ -1741,7 +1741,7 @@ pub enum StatementKind<'tcx> { /// - `Contravariant` -- requires that `T_y :> T` /// - `Invariant` -- requires that `T_y == T` /// - `Bivariant` -- no effect - AscribeUserType(Place<'tcx>, ty::Variance, Box>), + AscribeUserType(Place<'tcx>, ty::Variance, Box>), /// No-op. Useful for deleting instructions without affecting statement indices. Nop, @@ -2449,6 +2449,17 @@ EnumLiftImpl! { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +pub struct UserTypeProjection<'tcx> { + pub base: UserTypeAnnotation<'tcx>, +} + +BraceStructTypeFoldableImpl! { + impl<'tcx> TypeFoldable<'tcx> for UserTypeProjection<'tcx> { + base + } +} + newtype_index! { pub struct Promoted { DEBUG_FORMAT = "promoted[{}]" diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 1a879ce5f7b..acca7ddcd3f 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -147,7 +147,7 @@ macro_rules! make_mir_visitor { fn visit_ascribe_user_ty(&mut self, place: & $($mutability)* Place<'tcx>, variance: & $($mutability)* ty::Variance, - user_ty: & $($mutability)* UserTypeAnnotation<'tcx>, + user_ty: & $($mutability)* UserTypeProjection<'tcx>, location: Location) { self.super_ascribe_user_ty(place, variance, user_ty, location); } @@ -213,6 +213,13 @@ macro_rules! make_mir_visitor { self.super_ty(ty); } + fn visit_user_type_projection( + &mut self, + ty: & $($mutability)* UserTypeProjection<'tcx>, + ) { + self.super_user_type_projection(ty); + } + fn visit_user_type_annotation( &mut self, ty: & $($mutability)* UserTypeAnnotation<'tcx>, @@ -639,10 +646,10 @@ macro_rules! make_mir_visitor { fn super_ascribe_user_ty(&mut self, place: & $($mutability)* Place<'tcx>, _variance: & $($mutability)* ty::Variance, - user_ty: & $($mutability)* UserTypeAnnotation<'tcx>, + user_ty: & $($mutability)* UserTypeProjection<'tcx>, location: Location) { self.visit_place(place, PlaceContext::Validate, location); - self.visit_user_type_annotation(user_ty); + self.visit_user_type_projection(user_ty); } fn super_place(&mut self, @@ -737,7 +744,7 @@ macro_rules! make_mir_visitor { source_info: *source_info, }); if let Some((user_ty, _)) = user_ty { - self.visit_user_type_annotation(user_ty); + self.visit_user_type_projection(user_ty); } self.visit_source_info(source_info); self.visit_source_scope(visibility_scope); @@ -784,6 +791,16 @@ macro_rules! make_mir_visitor { self.visit_source_scope(scope); } + fn super_user_type_projection( + &mut self, + ty: & $($mutability)* UserTypeProjection<'tcx>, + ) { + let UserTypeProjection { + ref $($mutability)* base, + } = *ty; + self.visit_user_type_annotation(base) + } + fn super_user_type_annotation( &mut self, _ty: & $($mutability)* UserTypeAnnotation<'tcx>, diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 495e84528a3..1d8d028137a 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -18,7 +18,7 @@ use rustc::mir::visit::TyContext; use rustc::mir::visit::Visitor; use rustc::mir::{BasicBlock, BasicBlockData, Location, Mir, Place, Rvalue}; use rustc::mir::{Statement, Terminator}; -use rustc::mir::UserTypeAnnotation; +use rustc::mir::UserTypeProjection; use rustc::ty::fold::TypeFoldable; use rustc::ty::subst::Substs; use rustc::ty::{self, ClosureSubsts, GeneratorSubsts, RegionVid}; @@ -183,7 +183,7 @@ impl<'cg, 'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'gcx &mut self, _place: &Place<'tcx>, _variance: &ty::Variance, - _user_ty: &UserTypeAnnotation<'tcx>, + _user_ty: &UserTypeProjection<'tcx>, _location: Location, ) { } 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 ff4651dfb45..708f2f3ad33 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -284,7 +284,7 @@ impl<'a, 'b, 'gcx, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'gcx, 'tcx> { if let Err(terr) = self.cx.relate_type_and_user_type( constant.ty, ty::Variance::Invariant, - user_ty, + UserTypeProjection { base: user_ty }, location.to_locations(), ConstraintCategory::Boring, ) { @@ -971,7 +971,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { &mut self, a: Ty<'tcx>, v: ty::Variance, - user_ty: UserTypeAnnotation<'tcx>, + user_ty: UserTypeProjection<'tcx>, locations: Locations, category: ConstraintCategory, ) -> Fallible<()> { @@ -980,7 +980,8 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { a, v, user_ty, locations, ); - match user_ty { + // FIXME + match user_ty.base { UserTypeAnnotation::Ty(canonical_ty) => { let (ty, _) = self.infcx .instantiate_canonical_with_fresh_inference_vars(DUMMY_SP, &canonical_ty); @@ -1172,7 +1173,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { if let Err(terr) = self.relate_type_and_user_type( rv_ty, ty::Variance::Invariant, - user_ty, + UserTypeProjection { base: user_ty }, location.to_locations(), ConstraintCategory::Boring, ) { diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs index 8d6b6bb5c74..bc03b6a5dd0 100644 --- a/src/librustc_mir/build/expr/as_place.rs +++ b/src/librustc_mir/build/expr/as_place.rs @@ -147,7 +147,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { kind: StatementKind::AscribeUserType( place.clone(), Variance::Invariant, - box user_ty, + box UserTypeProjection { base: user_ty }, ), }, ); @@ -167,7 +167,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { kind: StatementKind::AscribeUserType( Place::Local(temp.clone()), Variance::Invariant, - box user_ty, + box UserTypeProjection { base: user_ty }, ), }, ); diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 0d456a091c2..9bfb6d4e6de 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -491,7 +491,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { pub(super) fn visit_bindings( &mut self, pattern: &Pattern<'tcx>, - mut pattern_user_ty: Option<(PatternTypeAnnotation<'tcx>, Span)>, + mut pattern_user_ty: Option<(PatternTypeProjection<'tcx>, Span)>, f: &mut impl FnMut( &mut Self, Mutability, @@ -500,7 +500,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { NodeId, Span, Ty<'tcx>, - Option<(PatternTypeAnnotation<'tcx>, Span)>, + Option<(PatternTypeProjection<'tcx>, Span)>, ), ) { match *pattern.kind { @@ -626,7 +626,7 @@ struct Binding<'tcx> { struct Ascription<'tcx> { span: Span, source: Place<'tcx>, - user_ty: PatternTypeAnnotation<'tcx>, + user_ty: PatternTypeProjection<'tcx>, } #[derive(Clone, Debug)] @@ -1470,7 +1470,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { num_patterns: usize, var_id: NodeId, var_ty: Ty<'tcx>, - user_var_ty: Option<(PatternTypeAnnotation<'tcx>, Span)>, + user_var_ty: Option<(PatternTypeProjection<'tcx>, Span)>, has_guard: ArmHasGuard, opt_match_place: Option<(Option>, Span)>, pat_span: Span, @@ -1489,7 +1489,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { let local = LocalDecl::<'tcx> { mutability, ty: var_ty, - user_ty: user_var_ty.map(|(pat_ty, span)|(pat_ty.user_ty(), span)), + user_ty: user_var_ty.map(|(ut, sp)| (ut.user_ty(), sp)), name: Some(name), source_info, visibility_scope, diff --git a/src/librustc_mir/hair/cx/block.rs b/src/librustc_mir/hair/cx/block.rs index d89f250ef5b..586d6d87fa0 100644 --- a/src/librustc_mir/hair/cx/block.rs +++ b/src/librustc_mir/hair/cx/block.rs @@ -91,7 +91,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, ty: pattern.ty, span: pattern.span, kind: Box::new(PatternKind::AscribeUserType { - user_ty: PatternTypeAnnotation::from_c_ty(user_ty), + user_ty: PatternTypeProjection::from_canonical_ty(user_ty), user_ty_span: ty.span, subpattern: pattern }) diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index 11f5ce26003..888c14194c6 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -27,7 +27,7 @@ use self::cx::Cx; pub mod cx; pub mod pattern; -pub use self::pattern::{BindingMode, Pattern, PatternKind, PatternTypeAnnotation, FieldPattern}; +pub use self::pattern::{BindingMode, Pattern, PatternKind, PatternTypeProjection, FieldPattern}; mod util; diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 7d879db4a52..57b2638cc8d 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -20,7 +20,8 @@ use const_eval::{const_field, const_variant_index}; use hair::util::UserAnnotatedTyHelpers; -use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability, UserTypeAnnotation}; +use rustc::mir::{fmt_const_val, Field, BorrowKind, Mutability}; +use rustc::mir::{UserTypeAnnotation, UserTypeProjection}; use rustc::mir::interpret::{Scalar, GlobalId, ConstValue, sign_extend}; use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty}; use rustc::ty::subst::{Substs, Kind}; @@ -65,17 +66,22 @@ pub struct Pattern<'tcx> { } #[derive(Copy, Clone, Debug)] -pub struct PatternTypeAnnotation<'tcx>(UserTypeAnnotation<'tcx>); +pub struct PatternTypeProjection<'tcx>(UserTypeProjection<'tcx>); -impl<'tcx> PatternTypeAnnotation<'tcx> { - pub(crate) fn from_c_ty(c_ty: ty::CanonicalTy<'tcx>) -> Self { - Self::from_u_ty(UserTypeAnnotation::Ty(c_ty)) - } - pub(crate) fn from_u_ty(u_ty: UserTypeAnnotation<'tcx>) -> Self { - PatternTypeAnnotation(u_ty) +impl<'tcx> PatternTypeProjection<'tcx> { + pub(crate) fn from_canonical_ty(c_ty: ty::CanonicalTy<'tcx>) -> Self { + Self::from_user_type(UserTypeAnnotation::Ty(c_ty)) } - pub(crate) fn user_ty(self) -> UserTypeAnnotation<'tcx> { self.0 } + pub(crate) fn from_user_type(u_ty: UserTypeAnnotation<'tcx>) -> Self { + Self::from_user_type_proj(UserTypeProjection { base: u_ty }) + } + + pub(crate) fn from_user_type_proj(u_ty: UserTypeProjection<'tcx>) -> Self { + PatternTypeProjection(u_ty) + } + + pub(crate) fn user_ty(self) -> UserTypeProjection<'tcx> { self.0 } } #[derive(Clone, Debug)] @@ -83,7 +89,7 @@ pub enum PatternKind<'tcx> { Wild, AscribeUserType { - user_ty: PatternTypeAnnotation<'tcx>, + user_ty: PatternTypeProjection<'tcx>, subpattern: Pattern<'tcx>, user_ty_span: Span, }, @@ -704,7 +710,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> { debug!("pattern user_ty = {:?} for pattern at {:?}", user_ty, span); - let pat_ty = PatternTypeAnnotation::from_u_ty(user_ty); + let pat_ty = PatternTypeProjection::from_user_type(user_ty); kind = PatternKind::AscribeUserType { subpattern, user_ty: pat_ty, @@ -995,7 +1001,8 @@ macro_rules! CloneImpls { CloneImpls!{ <'tcx> Span, Field, Mutability, ast::Name, ast::NodeId, usize, &'tcx ty::Const<'tcx>, Region<'tcx>, Ty<'tcx>, BindingMode<'tcx>, &'tcx AdtDef, - &'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>, PatternTypeAnnotation<'tcx> + &'tcx Substs<'tcx>, &'tcx Kind<'tcx>, UserTypeAnnotation<'tcx>, + UserTypeProjection<'tcx>, PatternTypeProjection<'tcx> } impl<'tcx> PatternFoldable<'tcx> for FieldPattern<'tcx> {