about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFelix S. Klock II <pnkfelix@pnkfx.org>2018-10-22 11:58:06 +0200
committerFelix S. Klock II <pnkfelix@pnkfx.org>2018-10-26 23:44:52 +0200
commit28ce99df86bc4e7e1f36a266e4e19da3f1cfff8a (patch)
treee9e8572f5915c8591f59d7812d4034f9fc9e5a11
parent36d8432a6d808dcd9e792679930729c0ab9a0212 (diff)
downloadrust-28ce99df86bc4e7e1f36a266e4e19da3f1cfff8a.tar.gz
rust-28ce99df86bc4e7e1f36a266e4e19da3f1cfff8a.zip
Added `mir::UserTypeProjection`, a stub for a structure that projects *into* a given UserTypeAnnotation.
(That is, it will pull out some component type held or referenced by
the type annotation.)

Note: this still needs to actually do projection itself. That comes in
a later commit
-rw-r--r--src/librustc/ich/impls_mir.rs2
-rw-r--r--src/librustc/mir/mod.rs15
-rw-r--r--src/librustc/mir/visit.rs25
-rw-r--r--src/librustc_mir/borrow_check/nll/constraint_generation.rs4
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs9
-rw-r--r--src/librustc_mir/build/expr/as_place.rs4
-rw-r--r--src/librustc_mir/build/matches/mod.rs10
-rw-r--r--src/librustc_mir/hair/cx/block.rs2
-rw-r--r--src/librustc_mir/hair/mod.rs2
-rw-r--r--src/librustc_mir/hair/pattern/mod.rs29
10 files changed, 70 insertions, 32 deletions
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<StableHashingContext<'a>> 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<UserTypeAnnotation<'tcx>>),
+    AscribeUserType(Place<'tcx>, ty::Variance, Box<UserTypeProjection<'tcx>>),
 
     /// 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<Place<'tcx>>, 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))
+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 from_u_ty(u_ty: UserTypeAnnotation<'tcx>) -> Self {
-        PatternTypeAnnotation(u_ty)
+
+    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) -> UserTypeAnnotation<'tcx> { self.0 }
+    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> {