about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-05-25 01:20:07 +0000
committerbors <bors@rust-lang.org>2019-05-25 01:20:07 +0000
commit524580312039e4fa5ccf91e8f7093cd755bc1aad (patch)
treed9e75790ba24c417af1011a1920584cde727ec0a
parentdec4c5201f88efbc3020b04ba96a5ee2c3b6cfcd (diff)
parent123a456a4f6b1ddc02cf9fe54b55d2af076da0f6 (diff)
downloadrust-524580312039e4fa5ccf91e8f7093cd755bc1aad.tar.gz
rust-524580312039e4fa5ccf91e8f7093cd755bc1aad.zip
Auto merge of #60441 - vext01:try-to-kill-projection-params, r=oli-obk
Make place projections concrete.

**I'm not sure if we want this. I'm raising the PR  for discussion**

Whilst doing some work on our Rust fork, I noticed the following:

Once upon a time (commit 9bd35c07c26) there were two kinds of
projection: one for places, and one for constants. It therefore made
sense to share the `Projection` struct for both. Although the different
use-cases used different concrete types, sharing was made possible by
type-parameterisation of `Projection`.

Since then, however, the usage of projections in constants has
disappeared, meaning that (forgetting lifetimes for a moment) the
parameterised type is only every instantiated under one guise. So it may
as well be a concrete type. Right?

What do people think? This is entirely untested, although it does check.

If we *don't* want this, then we should at least update the incorrect comment against `Projection`.

Thanks
-rw-r--r--src/librustc/mir/mod.rs76
-rw-r--r--src/librustc/mir/visit.rs4
-rw-r--r--src/librustc_mir/borrow_check/conflict_errors.rs8
-rw-r--r--src/librustc_mir/borrow_check/move_errors.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs2
-rw-r--r--src/librustc_mir/borrow_check/places_conflict.rs10
-rw-r--r--src/librustc_mir/dataflow/drop_flag_effects.rs2
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs2
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs6
-rw-r--r--src/librustc_mir/transform/uniform_array_move_out.rs10
10 files changed, 55 insertions, 67 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index aab9d5e3a02..6de4350c2aa 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1914,7 +1914,7 @@ pub enum Place<'tcx> {
     Base(PlaceBase<'tcx>),
 
     /// projection out of a place (access a field, deref a pointer, etc)
-    Projection(Box<PlaceProjection<'tcx>>),
+    Projection(Box<Projection<'tcx>>),
 }
 
 #[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, HashStable)]
@@ -1944,16 +1944,13 @@ impl_stable_hash_for!(struct Static<'tcx> {
     kind
 });
 
-/// The `Projection` data structure defines things of the form `B.x`
-/// or `*B` or `B[index]`. Note that it is parameterized because it is
-/// shared between `Constant` and `Place`. See the aliases
-/// `PlaceProjection` etc below.
+/// The `Projection` data structure defines things of the form `base.x`, `*b` or `b[index]`.
 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
          Hash, RustcEncodable, RustcDecodable, HashStable)]
-pub struct Projection<B, V, T> {
-    pub base: B,
-    pub elem: ProjectionElem<V, T>,
-}
+pub struct Projection<'tcx> {
+    pub base: Place<'tcx>,
+    pub elem: PlaceElem<'tcx>,
+ }
 
 #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord,
          Hash, RustcEncodable, RustcDecodable, HashStable)]
@@ -1998,10 +1995,6 @@ pub enum ProjectionElem<V, T> {
 
 /// Alias for projections as they appear in places, where the base is a place
 /// and the index is a local.
-pub type PlaceProjection<'tcx> = Projection<Place<'tcx>, Local, Ty<'tcx>>;
-
-/// Alias for projections as they appear in places, where the base is a place
-/// and the index is a local.
 pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
 
 // At least on 64 bit systems, `PlaceElem` should not be larger than two pointers.
@@ -2045,7 +2038,7 @@ impl<'tcx> Place<'tcx> {
     }
 
     pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
-        Place::Projection(Box::new(PlaceProjection { base: self, elem }))
+        Place::Projection(Box::new(Projection { base: self, elem }))
     }
 
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
@@ -2076,22 +2069,22 @@ impl<'tcx> Place<'tcx> {
     }
 
     /// Recursively "iterates" over place components, generating a `PlaceBase` and
-    /// `PlaceProjections` list and invoking `op` with a `PlaceProjectionsIter`.
+    /// `Projections` list and invoking `op` with a `ProjectionsIter`.
     pub fn iterate<R>(
         &self,
-        op: impl FnOnce(&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>) -> R,
+        op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
     ) -> R {
-        self.iterate2(&PlaceProjections::Empty, op)
+        self.iterate2(&Projections::Empty, op)
     }
 
     fn iterate2<R>(
         &self,
-        next: &PlaceProjections<'_, 'tcx>,
-        op: impl FnOnce(&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>) -> R,
+        next: &Projections<'_, 'tcx>,
+        op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
     ) -> R {
         match self {
             Place::Projection(interior) => interior.base.iterate2(
-                &PlaceProjections::List {
+                &Projections::List {
                     projection: interior,
                     next,
                 },
@@ -2111,26 +2104,26 @@ impl<'tcx> Place<'tcx> {
 /// N.B., this particular impl strategy is not the most obvious. It was
 /// chosen because it makes a measurable difference to NLL
 /// performance, as this code (`borrow_conflicts_with_place`) is somewhat hot.
-pub enum PlaceProjections<'p, 'tcx: 'p> {
+pub enum Projections<'p, 'tcx: 'p> {
     Empty,
 
     List {
-        projection: &'p PlaceProjection<'tcx>,
-        next: &'p PlaceProjections<'p, 'tcx>,
+        projection: &'p Projection<'tcx>,
+        next: &'p Projections<'p, 'tcx>,
     }
 }
 
-impl<'p, 'tcx> PlaceProjections<'p, 'tcx> {
-    fn iter(&self) -> PlaceProjectionsIter<'_, 'tcx> {
-        PlaceProjectionsIter { value: self }
+impl<'p, 'tcx> Projections<'p, 'tcx> {
+    fn iter(&self) -> ProjectionsIter<'_, 'tcx> {
+        ProjectionsIter { value: self }
     }
 }
 
-impl<'p, 'tcx> IntoIterator for &'p PlaceProjections<'p, 'tcx> {
-    type Item = &'p PlaceProjection<'tcx>;
-    type IntoIter = PlaceProjectionsIter<'p, 'tcx>;
+impl<'p, 'tcx> IntoIterator for &'p Projections<'p, 'tcx> {
+    type Item = &'p Projection<'tcx>;
+    type IntoIter = ProjectionsIter<'p, 'tcx>;
 
-    /// Converts a list of `PlaceProjection` components into an iterator;
+    /// Converts a list of `Projection` components into an iterator;
     /// this iterator yields up a never-ending stream of `Option<&Place>`.
     /// These begin with the "innermost" projection and then with each
     /// projection therefrom. So given a place like `a.b.c` it would
@@ -2144,21 +2137,21 @@ impl<'p, 'tcx> IntoIterator for &'p PlaceProjections<'p, 'tcx> {
     }
 }
 
-/// Iterator over components; see `PlaceProjections::iter` for more
+/// Iterator over components; see `Projections::iter` for more
 /// information.
 ///
 /// N.B., this is not a *true* Rust iterator -- the code above just
 /// manually invokes `next`. This is because we (sometimes) want to
 /// keep executing even after `None` has been returned.
-pub struct PlaceProjectionsIter<'p, 'tcx: 'p> {
-    pub value: &'p PlaceProjections<'p, 'tcx>,
+pub struct ProjectionsIter<'p, 'tcx: 'p> {
+    pub value: &'p Projections<'p, 'tcx>,
 }
 
-impl<'p, 'tcx> Iterator for PlaceProjectionsIter<'p, 'tcx> {
-    type Item = &'p PlaceProjection<'tcx>;
+impl<'p, 'tcx> Iterator for ProjectionsIter<'p, 'tcx> {
+    type Item = &'p Projection<'tcx>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        if let &PlaceProjections::List { projection, next } = self.value {
+        if let &Projections::List { projection, next } = self.value {
             self.value = next;
             Some(projection)
         } else {
@@ -2167,7 +2160,7 @@ impl<'p, 'tcx> Iterator for PlaceProjectionsIter<'p, 'tcx> {
     }
 }
 
-impl<'p, 'tcx> FusedIterator for PlaceProjectionsIter<'p, 'tcx> {}
+impl<'p, 'tcx> FusedIterator for ProjectionsIter<'p, 'tcx> {}
 
 impl<'tcx> Debug for Place<'tcx> {
     fn fmt(&self, fmt: &mut Formatter<'_>) -> fmt::Result {
@@ -2758,7 +2751,7 @@ impl<'tcx> UserTypeProjections {
 #[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
 pub struct UserTypeProjection {
     pub base: UserTypeAnnotationIndex,
-    pub projs: Vec<ProjectionElem<(), ()>>,
+    pub projs: Vec<ProjectionKind>,
 }
 
 impl Copy for ProjectionKind { }
@@ -3587,12 +3580,7 @@ impl<'tcx> TypeFoldable<'tcx> for Operand<'tcx> {
     }
 }
 
-impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<B, V, T>
-where
-    B: TypeFoldable<'tcx>,
-    V: TypeFoldable<'tcx>,
-    T: TypeFoldable<'tcx>,
-{
+impl<'tcx> TypeFoldable<'tcx> for Projection<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         use crate::mir::ProjectionElem::*;
 
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index f71a0d102e6..64ffd80e21e 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -152,7 +152,7 @@ macro_rules! make_mir_visitor {
             }
 
             fn visit_projection(&mut self,
-                                place: & $($mutability)? PlaceProjection<'tcx>,
+                                place: & $($mutability)? Projection<'tcx>,
                                 context: PlaceContext,
                                 location: Location) {
                 self.super_projection(place, context, location);
@@ -689,7 +689,7 @@ macro_rules! make_mir_visitor {
             }
 
             fn super_projection(&mut self,
-                                proj: & $($mutability)? PlaceProjection<'tcx>,
+                                proj: & $($mutability)? Projection<'tcx>,
                                 context: PlaceContext,
                                 location: Location) {
                 let Projection { base, elem } = proj;
diff --git a/src/librustc_mir/borrow_check/conflict_errors.rs b/src/librustc_mir/borrow_check/conflict_errors.rs
index b00a75bb569..4253962f144 100644
--- a/src/librustc_mir/borrow_check/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/conflict_errors.rs
@@ -2,7 +2,7 @@ use rustc::hir;
 use rustc::hir::def_id::DefId;
 use rustc::mir::{
     self, AggregateKind, BindingForm, BorrowKind, ClearCrossCrate, ConstraintCategory, Local,
-    LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, PlaceProjection,
+    LocalDecl, LocalKind, Location, Operand, Place, PlaceBase, Projection,
     ProjectionElem, Rvalue, Statement, StatementKind, TerminatorKind, VarBindingForm,
 };
 use rustc::ty::{self, Ty};
@@ -619,7 +619,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 // union being accessed and the field that was being accessed so we can check the
                 // second borrowed place for the same union and a access to a different field.
                 let mut current = first_borrowed_place;
-                while let Place::Projection(box PlaceProjection { base, elem }) = current {
+                while let Place::Projection(box Projection { base, elem }) = current {
                     match elem {
                         ProjectionElem::Field(field, _) if is_union(base) => {
                             return Some((base, field));
@@ -633,7 +633,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 // With the place of a union and a field access into it, we traverse the second
                 // borrowed place and look for a access to a different field of the same union.
                 let mut current = second_borrowed_place;
-                while let Place::Projection(box PlaceProjection { base, elem }) = current {
+                while let Place::Projection(box Projection { base, elem }) = current {
                     match elem {
                         ProjectionElem::Field(field, _) if {
                             is_union(base) && field != target_field && base == target_base
@@ -1495,7 +1495,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
             Place::Base(PlaceBase::Static(_)) => {
                 StorageDeadOrDrop::LocalStorageDead
             }
-            Place::Projection(box PlaceProjection { base, elem }) => {
+            Place::Projection(box Projection { base, elem }) => {
                 let base_access = self.classify_drop_access_kind(base);
                 match elem {
                     ProjectionElem::Deref => match base_access {
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index a7bad44c42c..549f3b90555 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -352,7 +352,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 ..
             } => {
                 let try_remove_deref = match move_from {
-                    Place::Projection(box PlaceProjection {
+                    Place::Projection(box Projection {
                         elem: ProjectionElem::Deref,
                         ..
                     }) => true,
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 4589e4ef036..ac44364aa69 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -2370,7 +2370,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
             "add_reborrow_constraint({:?}, {:?}, {:?})",
             location, borrow_region, borrowed_place
         );
-        while let Place::Projection(box PlaceProjection { base, elem }) = borrowed_place {
+        while let Place::Projection(box Projection { base, elem }) = borrowed_place {
             debug!("add_reborrow_constraint - iteration {:?}", borrowed_place);
 
             match *elem {
diff --git a/src/librustc_mir/borrow_check/places_conflict.rs b/src/librustc_mir/borrow_check/places_conflict.rs
index 1bf606109dc..c9e8d989478 100644
--- a/src/librustc_mir/borrow_check/places_conflict.rs
+++ b/src/librustc_mir/borrow_check/places_conflict.rs
@@ -3,7 +3,7 @@ use crate::borrow_check::Overlap;
 use crate::borrow_check::{Deep, Shallow, AccessDepth};
 use rustc::hir;
 use rustc::mir::{
-    BorrowKind, Mir, Place, PlaceBase, PlaceProjection, ProjectionElem, PlaceProjectionsIter,
+    BorrowKind, Mir, Place, PlaceBase, Projection, ProjectionElem, ProjectionsIter,
     StaticKind
 };
 use rustc::ty::{self, TyCtxt};
@@ -86,9 +86,9 @@ pub(super) fn borrow_conflicts_with_place<'gcx, 'tcx>(
 fn place_components_conflict<'gcx, 'tcx>(
     tcx: TyCtxt<'_, 'gcx, 'tcx>,
     mir: &Mir<'tcx>,
-    borrow_projections: (&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>),
+    borrow_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
     borrow_kind: BorrowKind,
-    access_projections: (&PlaceBase<'tcx>, PlaceProjectionsIter<'_, 'tcx>),
+    access_projections: (&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>),
     access: AccessDepth,
     bias: PlaceConflictBias,
 ) -> bool {
@@ -368,8 +368,8 @@ fn place_base_conflict<'a, 'gcx: 'tcx, 'tcx>(
 fn place_projection_conflict<'a, 'gcx: 'tcx, 'tcx>(
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     mir: &Mir<'tcx>,
-    pi1: &PlaceProjection<'tcx>,
-    pi2: &PlaceProjection<'tcx>,
+    pi1: &Projection<'tcx>,
+    pi2: &Projection<'tcx>,
     bias: PlaceConflictBias,
 ) -> Overlap {
     match (&pi1.elem, &pi2.elem) {
diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs
index aae4590a387..66ca4b4dc89 100644
--- a/src/librustc_mir/dataflow/drop_flag_effects.rs
+++ b/src/librustc_mir/dataflow/drop_flag_effects.rs
@@ -10,7 +10,7 @@ pub fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
                                         path: MovePathIndex,
                                         mut cond: F)
                                         -> Option<MovePathIndex>
-    where F: FnMut(&mir::PlaceProjection<'tcx>) -> bool
+    where F: FnMut(&mir::Projection<'tcx>) -> bool
 {
     let mut next_child = move_data.move_paths[path].first_child;
     while let Some(child_index) = next_child {
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 2471c01e3f3..7eb4428bf29 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -114,7 +114,7 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
 
     fn move_path_for_projection(&mut self,
                                 place: &Place<'tcx>,
-                                proj: &PlaceProjection<'tcx>)
+                                proj: &Projection<'tcx>)
                                 -> Result<MovePathIndex, MoveError<'tcx>>
     {
         let base = self.move_path_for(&proj.base)?;
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 12357cb10a9..dca28368393 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -161,7 +161,7 @@ trait Qualif {
 
     fn in_projection_structurally(
         cx: &ConstCx<'_, 'tcx>,
-        proj: &PlaceProjection<'tcx>,
+        proj: &Projection<'tcx>,
     ) -> bool {
         let base_qualif = Self::in_place(cx, &proj.base);
         let qualif = base_qualif && Self::mask_for_ty(
@@ -181,7 +181,7 @@ trait Qualif {
         }
     }
 
-    fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &PlaceProjection<'tcx>) -> bool {
+    fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &Projection<'tcx>) -> bool {
         Self::in_projection_structurally(cx, proj)
     }
 
@@ -387,7 +387,7 @@ impl Qualif for IsNotPromotable {
         }
     }
 
-    fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &PlaceProjection<'tcx>) -> bool {
+    fn in_projection(cx: &ConstCx<'_, 'tcx>, proj: &Projection<'tcx>) -> bool {
         match proj.elem {
             ProjectionElem::Deref |
             ProjectionElem::Downcast(..) => return true,
diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs
index 4eee0640d78..a2433ab838d 100644
--- a/src/librustc_mir/transform/uniform_array_move_out.rs
+++ b/src/librustc_mir/transform/uniform_array_move_out.rs
@@ -89,7 +89,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
     fn uniform(&mut self,
                location: Location,
                dst_place: &Place<'tcx>,
-               proj: &PlaceProjection<'tcx>,
+               proj: &Projection<'tcx>,
                item_ty: &'tcx ty::TyS<'tcx>,
                size: u32) {
         match proj.elem {
@@ -103,7 +103,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
                                           Place::Base(PlaceBase::Local(temp)),
                                           Rvalue::Use(
                                               Operand::Move(
-                                                  Place::Projection(box PlaceProjection{
+                                                  Place::Projection(box Projection{
                                                       base: proj.base.clone(),
                                                       elem: ProjectionElem::ConstantIndex{
                                                           offset: i,
@@ -133,7 +133,7 @@ impl<'a, 'tcx> UniformArrayMoveOutVisitor<'a, 'tcx> {
                                       dst_place.clone(),
                                       Rvalue::Use(
                                           Operand::Move(
-                                              Place::Projection(box PlaceProjection{
+                                              Place::Projection(box Projection{
                                                   base: proj.base.clone(),
                                                   elem: ProjectionElem::ConstantIndex{
                                                       offset: size - offset,
@@ -246,7 +246,7 @@ impl RestoreSubsliceArrayMoveOut {
                              dst_place.clone(),
                              Rvalue::Use(
                                  Operand::Move(
-                                     Place::Projection(box PlaceProjection{
+                                     Place::Projection(box Projection{
                                          base: opt_src_place.unwrap().clone(),
                                          elem: ProjectionElem::Subslice{
                                              from: min, to: size - max - 1}}))));
@@ -261,7 +261,7 @@ impl RestoreSubsliceArrayMoveOut {
                 let statement = &block.statements[location.statement_index];
                 if let StatementKind::Assign(
                     Place::Base(PlaceBase::Local(_)),
-                    box Rvalue::Use(Operand::Move(Place::Projection(box PlaceProjection{
+                    box Rvalue::Use(Operand::Move(Place::Projection(box Projection{
                         ref base, elem: ProjectionElem::ConstantIndex{
                             offset, min_length: _, from_end: false}})))) = statement.kind {
                     return Some((offset, base))