about summary refs log tree commit diff
diff options
context:
space:
mode:
authorManish Goregaokar <manishsmail@gmail.com>2020-07-17 14:09:26 -0700
committerGitHub <noreply@github.com>2020-07-17 14:09:26 -0700
commit222d2508375a363be7a4f6ded3c9bd7be0803d19 (patch)
tree24ab5e17a9ba90e90965d10de9314e4821fc5cea
parenteef22dae7e0ccbf484f1fef3989759fc75b6dddb (diff)
parent50f3dbd1214fb9e582b845a364fc4746622e96a0 (diff)
downloadrust-222d2508375a363be7a4f6ded3c9bd7be0803d19.tar.gz
rust-222d2508375a363be7a4f6ded3c9bd7be0803d19.zip
Rollup merge of #74424 - sexxi-goose:move_hir_place, r=nikomatsakis
Move hir::Place to librustc_middle/hir

Needed to support https://github.com/rust-lang/project-rfc-2229/issues/7

Currently rustc_typeck depends on rustc_middle for definition TypeckTables, etc.
For supporting project-rfc-2229#7, rustc_middle would've to depend on
rustc_typeck for Place -- introducing a circular dependency.

This resembles the MIR equivalent of `Place` located in `lbrustc_middle/mir`.

Separate PR for this move will make the actual PR for using Places to represent captures cleaner/more focused.

r? @nikomatsakis  @matthewjasper
-rw-r--r--src/librustc_middle/hir/mod.rs1
-rw-r--r--src/librustc_middle/hir/place.rs115
-rw-r--r--src/librustc_typeck/check/regionck.rs17
-rw-r--r--src/librustc_typeck/check/upvar.rs15
-rw-r--r--src/librustc_typeck/expr_use_visitor.rs15
-rw-r--r--src/librustc_typeck/mem_categorization.rs111
6 files changed, 141 insertions, 133 deletions
diff --git a/src/librustc_middle/hir/mod.rs b/src/librustc_middle/hir/mod.rs
index 485f9b7ce8a..b014f3c8eb7 100644
--- a/src/librustc_middle/hir/mod.rs
+++ b/src/librustc_middle/hir/mod.rs
@@ -4,6 +4,7 @@
 
 pub mod exports;
 pub mod map;
+pub mod place;
 
 use crate::ich::StableHashingContext;
 use crate::ty::query::Providers;
diff --git a/src/librustc_middle/hir/place.rs b/src/librustc_middle/hir/place.rs
new file mode 100644
index 00000000000..d85165bcccf
--- /dev/null
+++ b/src/librustc_middle/hir/place.rs
@@ -0,0 +1,115 @@
+use crate::ty;
+use crate::ty::Ty;
+
+use rustc_hir::HirId;
+use rustc_target::abi::VariantIdx;
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+pub enum PlaceBase {
+    /// A temporary variable
+    Rvalue,
+    /// A named `static` item
+    StaticItem,
+    /// A named local variable
+    Local(HirId),
+    /// An upvar referenced by closure env
+    Upvar(ty::UpvarId),
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+pub enum ProjectionKind {
+    /// A dereference of a pointer, reference or `Box<T>` of the given type
+    Deref,
+
+    /// `B.F` where `B` is the base expression and `F` is
+    /// the field. The field is identified by which variant
+    /// it appears in along with a field index. The variant
+    /// is used for enums.
+    Field(u32, VariantIdx),
+
+    /// Some index like `B[x]`, where `B` is the base
+    /// expression. We don't preserve the index `x` because
+    /// we won't need it.
+    Index,
+
+    /// A subslice covering a range of values like `B[x..y]`.
+    Subslice,
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+pub struct Projection<'tcx> {
+    /// Type after the projection is being applied.
+    pub ty: Ty<'tcx>,
+
+    /// Defines the type of access
+    pub kind: ProjectionKind,
+}
+
+/// A `Place` represents how a value is located in memory.
+///
+/// This is an HIR version of `mir::Place`
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+pub struct Place<'tcx> {
+    /// The type of the `PlaceBase`
+    pub base_ty: Ty<'tcx>,
+    /// The "outermost" place that holds this value.
+    pub base: PlaceBase,
+    /// How this place is derived from the base place.
+    pub projections: Vec<Projection<'tcx>>,
+}
+
+/// A `PlaceWithHirId` represents how a value is located in memory.
+///
+/// This is an HIR version of `mir::Place`
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
+pub struct PlaceWithHirId<'tcx> {
+    /// `HirId` of the expression or pattern producing this value.
+    pub hir_id: HirId,
+
+    /// Information about the `Place`
+    pub place: Place<'tcx>,
+}
+
+impl<'tcx> PlaceWithHirId<'tcx> {
+    pub fn new(
+        hir_id: HirId,
+        base_ty: Ty<'tcx>,
+        base: PlaceBase,
+        projections: Vec<Projection<'tcx>>,
+    ) -> PlaceWithHirId<'tcx> {
+        PlaceWithHirId {
+            hir_id: hir_id,
+            place: Place { base_ty: base_ty, base: base, projections: projections },
+        }
+    }
+}
+
+impl<'tcx> Place<'tcx> {
+    /// Returns an iterator of the types that have to be dereferenced to access
+    /// the `Place`.
+    ///
+    /// The types are in the reverse order that they are applied. So if
+    /// `x: &*const u32` and the `Place` is `**x`, then the types returned are
+    ///`*const u32` then `&*const u32`.
+    pub fn deref_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
+        self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| {
+            if ProjectionKind::Deref == proj.kind {
+                Some(self.ty_before_projection(index))
+            } else {
+                None
+            }
+        })
+    }
+
+    /// Returns the type of this `Place` after all projections have been applied.
+    pub fn ty(&self) -> Ty<'tcx> {
+        self.projections.last().map_or_else(|| self.base_ty, |proj| proj.ty)
+    }
+
+    /// Returns the type of this `Place` immediately before `projection_index`th projection
+    /// is applied.
+    pub fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> {
+        assert!(projection_index < self.projections.len());
+        if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty }
+    }
+}
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index d8d904a15f3..b72152d1911 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -82,6 +82,7 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::PatKind;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{self, RegionObligation, RegionckMode};
+use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId};
 use rustc_middle::ty::adjustment;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::Span;
@@ -442,7 +443,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     fn constrain_adjustments(
         &mut self,
         expr: &hir::Expr<'_>,
-    ) -> mc::McResult<mc::PlaceWithHirId<'tcx>> {
+    ) -> mc::McResult<PlaceWithHirId<'tcx>> {
         debug!("constrain_adjustments(expr={:?})", expr);
 
         let mut place = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?;
@@ -483,10 +484,10 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
 
     fn check_safety_of_rvalue_destructor_if_necessary(
         &mut self,
-        place_with_id: &mc::PlaceWithHirId<'tcx>,
+        place_with_id: &PlaceWithHirId<'tcx>,
         span: Span,
     ) {
-        if let mc::PlaceBase::Rvalue = place_with_id.place.base {
+        if let PlaceBase::Rvalue = place_with_id.place.base {
             if place_with_id.place.projections.is_empty() {
                 let typ = self.resolve_type(place_with_id.place.ty());
                 let body_id = self.body_id;
@@ -573,7 +574,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
 
     /// Link lifetimes of any ref bindings in `root_pat` to the pointers found
     /// in the discriminant, if needed.
-    fn link_pattern(&self, discr_cmt: mc::PlaceWithHirId<'tcx>, root_pat: &hir::Pat<'_>) {
+    fn link_pattern(&self, discr_cmt: PlaceWithHirId<'tcx>, root_pat: &hir::Pat<'_>) {
         debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", discr_cmt, root_pat);
         ignore_err!(self.with_mc(|mc| {
             mc.cat_pattern(discr_cmt, root_pat, |sub_cmt, hir::Pat { kind, span, hir_id }| {
@@ -594,7 +595,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
     fn link_autoref(
         &self,
         expr: &hir::Expr<'_>,
-        expr_cmt: &mc::PlaceWithHirId<'tcx>,
+        expr_cmt: &PlaceWithHirId<'tcx>,
         autoref: &adjustment::AutoBorrow<'tcx>,
     ) {
         debug!("link_autoref(autoref={:?}, expr_cmt={:?})", autoref, expr_cmt);
@@ -615,7 +616,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         span: Span,
         id: hir::HirId,
         mutbl: hir::Mutability,
-        cmt_borrowed: &mc::PlaceWithHirId<'tcx>,
+        cmt_borrowed: &PlaceWithHirId<'tcx>,
     ) {
         debug!(
             "link_region_from_node_type(id={:?}, mutbl={:?}, cmt_borrowed={:?})",
@@ -638,7 +639,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         span: Span,
         borrow_region: ty::Region<'tcx>,
         borrow_kind: ty::BorrowKind,
-        borrow_place: &mc::PlaceWithHirId<'tcx>,
+        borrow_place: &PlaceWithHirId<'tcx>,
     ) {
         let origin = infer::DataBorrowed(borrow_place.place.ty(), span);
         self.type_must_outlive(origin, borrow_place.place.ty(), borrow_region);
@@ -659,7 +660,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
                 _ => assert!(pointer_ty.is_box(), "unexpected built-in deref type {}", pointer_ty),
             }
         }
-        if let mc::PlaceBase::Upvar(upvar_id) = borrow_place.place.base {
+        if let PlaceBase::Upvar(upvar_id) = borrow_place.place.base {
             self.link_upvar_region(span, borrow_region, upvar_id);
         }
     }
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index ffaf9ef7c9f..030c0ab668a 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -33,14 +33,13 @@
 use super::FnCtxt;
 
 use crate::expr_use_visitor as euv;
-use crate::mem_categorization as mc;
-use crate::mem_categorization::PlaceBase;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_infer::infer::UpvarRegion;
+use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId};
 use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts};
 use rustc_span::{Span, Symbol};
 
@@ -276,7 +275,7 @@ struct InferBorrowKind<'a, 'tcx> {
 impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
     fn adjust_upvar_borrow_kind_for_consume(
         &mut self,
-        place_with_id: &mc::PlaceWithHirId<'tcx>,
+        place_with_id: &PlaceWithHirId<'tcx>,
         mode: euv::ConsumeMode,
     ) {
         debug!(
@@ -315,7 +314,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
     /// Indicates that `place_with_id` is being directly mutated (e.g., assigned
     /// to). If the place is based on a by-ref upvar, this implies that
     /// the upvar must be borrowed using an `&mut` borrow.
-    fn adjust_upvar_borrow_kind_for_mut(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>) {
+    fn adjust_upvar_borrow_kind_for_mut(&mut self, place_with_id: &PlaceWithHirId<'tcx>) {
         debug!("adjust_upvar_borrow_kind_for_mut(place_with_id={:?})", place_with_id);
 
         if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
@@ -340,7 +339,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
         }
     }
 
-    fn adjust_upvar_borrow_kind_for_unique(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>) {
+    fn adjust_upvar_borrow_kind_for_unique(&mut self, place_with_id: &PlaceWithHirId<'tcx>) {
         debug!("adjust_upvar_borrow_kind_for_unique(place_with_id={:?})", place_with_id);
 
         if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
@@ -470,12 +469,12 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
-    fn consume(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, mode: euv::ConsumeMode) {
+    fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, mode: euv::ConsumeMode) {
         debug!("consume(place_with_id={:?},mode={:?})", place_with_id, mode);
         self.adjust_upvar_borrow_kind_for_consume(place_with_id, mode);
     }
 
-    fn borrow(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, bk: ty::BorrowKind) {
+    fn borrow(&mut self, place_with_id: &PlaceWithHirId<'tcx>, bk: ty::BorrowKind) {
         debug!("borrow(place_with_id={:?}, bk={:?})", place_with_id, bk);
 
         match bk {
@@ -489,7 +488,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
         }
     }
 
-    fn mutate(&mut self, assignee_place: &mc::PlaceWithHirId<'tcx>) {
+    fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>) {
         debug!("mutate(assignee_place={:?})", assignee_place);
 
         self.adjust_upvar_borrow_kind_for_mut(assignee_place);
diff --git a/src/librustc_typeck/expr_use_visitor.rs b/src/librustc_typeck/expr_use_visitor.rs
index e5bd34ff148..d1b386c9d4d 100644
--- a/src/librustc_typeck/expr_use_visitor.rs
+++ b/src/librustc_typeck/expr_use_visitor.rs
@@ -5,7 +5,7 @@
 pub use self::ConsumeMode::*;
 
 // Export these here so that Clippy can use them.
-pub use mc::{PlaceBase, PlaceWithHirId, Projection};
+pub use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId, Projection};
 
 use rustc_hir as hir;
 use rustc_hir::def::Res;
@@ -13,6 +13,7 @@ use rustc_hir::def_id::LocalDefId;
 use rustc_hir::PatKind;
 use rustc_index::vec::Idx;
 use rustc_infer::infer::InferCtxt;
+use rustc_middle::hir::place::ProjectionKind;
 use rustc_middle::ty::{self, adjustment, TyCtxt};
 use rustc_target::abi::VariantIdx;
 
@@ -27,13 +28,13 @@ use rustc_span::Span;
 pub trait Delegate<'tcx> {
     // The value found at `place` is either copied or moved, depending
     // on mode.
-    fn consume(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, mode: ConsumeMode);
+    fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, mode: ConsumeMode);
 
     // The value found at `place` is being borrowed with kind `bk`.
-    fn borrow(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, bk: ty::BorrowKind);
+    fn borrow(&mut self, place_with_id: &PlaceWithHirId<'tcx>, bk: ty::BorrowKind);
 
     // The path at `place_with_id` is being assigned to.
-    fn mutate(&mut self, assignee_place: &mc::PlaceWithHirId<'tcx>);
+    fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>);
 }
 
 #[derive(Copy, Clone, PartialEq, Debug)]
@@ -398,7 +399,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
                             &*with_expr,
                             with_place.clone(),
                             with_field.ty(self.tcx(), substs),
-                            mc::ProjectionKind::Field(f_index as u32, VariantIdx::new(0)),
+                            ProjectionKind::Field(f_index as u32, VariantIdx::new(0)),
                         );
                         self.delegate_consume(&field_place);
                     }
@@ -462,7 +463,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
     fn walk_autoref(
         &mut self,
         expr: &hir::Expr<'_>,
-        base_place: &mc::PlaceWithHirId<'tcx>,
+        base_place: &PlaceWithHirId<'tcx>,
         autoref: &adjustment::AutoBorrow<'tcx>,
     ) {
         debug!(
@@ -575,7 +576,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
         closure_hir_id: hir::HirId,
         closure_span: Span,
         var_id: hir::HirId,
-    ) -> mc::McResult<mc::PlaceWithHirId<'tcx>> {
+    ) -> mc::McResult<PlaceWithHirId<'tcx>> {
         // Create the place for the variable being borrowed, from the
         // perspective of the creator (parent) of the closure.
         let var_ty = self.mc.node_ty(var_id)?;
diff --git a/src/librustc_typeck/mem_categorization.rs b/src/librustc_typeck/mem_categorization.rs
index 2d7ae14d7d5..afc7cb346eb 100644
--- a/src/librustc_typeck/mem_categorization.rs
+++ b/src/librustc_typeck/mem_categorization.rs
@@ -48,6 +48,7 @@
 //! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
 //! tied to `x`. The type of `x'` will be a borrowed pointer.
 
+use rustc_middle::hir::place::*;
 use rustc_middle::ty::adjustment;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -64,116 +65,6 @@ use rustc_span::Span;
 use rustc_target::abi::VariantIdx;
 use rustc_trait_selection::infer::InferCtxtExt;
 
-#[derive(Clone, Debug)]
-pub enum PlaceBase {
-    /// A temporary variable
-    Rvalue,
-    /// A named `static` item
-    StaticItem,
-    /// A named local variable
-    Local(hir::HirId),
-    /// An upvar referenced by closure env
-    Upvar(ty::UpvarId),
-}
-
-#[derive(Clone, Debug, Eq, PartialEq)]
-pub enum ProjectionKind {
-    /// A dereference of a pointer, reference or `Box<T>` of the given type
-    Deref,
-
-    /// `B.F` where `B` is the base expression and `F` is
-    /// the field. The field is identified by which variant
-    /// it appears in along with a field index. The variant
-    /// is used for enums.
-    Field(u32, VariantIdx),
-
-    /// Some index like `B[x]`, where `B` is the base
-    /// expression. We don't preserve the index `x` because
-    /// we won't need it.
-    Index,
-
-    /// A subslice covering a range of values like `B[x..y]`.
-    Subslice,
-}
-
-#[derive(Clone, Debug)]
-pub struct Projection<'tcx> {
-    // Type after the projection is being applied.
-    ty: Ty<'tcx>,
-
-    /// Defines the type of access
-    kind: ProjectionKind,
-}
-
-/// A `Place` represents how a value is located in memory.
-///
-/// This is an HIR version of `mir::Place`
-#[derive(Clone, Debug)]
-pub struct Place<'tcx> {
-    /// The type of the `PlaceBase`
-    pub base_ty: Ty<'tcx>,
-    /// The "outermost" place that holds this value.
-    pub base: PlaceBase,
-    /// How this place is derived from the base place.
-    pub projections: Vec<Projection<'tcx>>,
-}
-
-/// A `PlaceWithHirId` represents how a value is located in memory.
-///
-/// This is an HIR version of `mir::Place`
-#[derive(Clone, Debug)]
-pub struct PlaceWithHirId<'tcx> {
-    /// `HirId` of the expression or pattern producing this value.
-    pub hir_id: hir::HirId,
-
-    /// Information about the `Place`
-    pub place: Place<'tcx>,
-}
-
-impl<'tcx> PlaceWithHirId<'tcx> {
-    crate fn new(
-        hir_id: hir::HirId,
-        base_ty: Ty<'tcx>,
-        base: PlaceBase,
-        projections: Vec<Projection<'tcx>>,
-    ) -> PlaceWithHirId<'tcx> {
-        PlaceWithHirId {
-            hir_id: hir_id,
-            place: Place { base_ty: base_ty, base: base, projections: projections },
-        }
-    }
-}
-
-impl<'tcx> Place<'tcx> {
-    /// Returns an iterator of the types that have to be dereferenced to access
-    /// the `Place`.
-    ///
-    /// The types are in the reverse order that they are applied. So if
-    /// `x: &*const u32` and the `Place` is `**x`, then the types returned are
-    ///`*const u32` then `&*const u32`.
-    crate fn deref_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
-        self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| {
-            if ProjectionKind::Deref == proj.kind {
-                Some(self.ty_before_projection(index))
-            } else {
-                None
-            }
-        })
-    }
-
-    // Returns the type of this `Place` after all projections have been applied.
-    pub fn ty(&self) -> Ty<'tcx> {
-        self.projections.last().map_or_else(|| self.base_ty, |proj| proj.ty)
-    }
-
-    // Returns the type of this `Place` immediately before `projection_index`th projection
-    // is applied.
-    crate fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> {
-        assert!(projection_index < self.projections.len());
-        if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty }
-    }
-}
-
 crate trait HirNode {
     fn hir_id(&self) -> hir::HirId;
     fn span(&self) -> Span;