pub mod exports;
pub mod map;
+pub mod place;
use crate::ich::StableHashingContext;
use crate::ty::query::Providers;
--- /dev/null
+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 }
+ }
+}
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;
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))?;
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;
/// 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 }| {
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);
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={:?})",
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);
_ => 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);
}
}
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};
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!(
/// 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 {
}
}
- 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 {
}
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 {
}
}
- 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);
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;
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;
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)]
&*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);
}
fn walk_autoref(
&mut self,
expr: &hir::Expr<'_>,
- base_place: &mc::PlaceWithHirId<'tcx>,
+ base_place: &PlaceWithHirId<'tcx>,
autoref: &adjustment::AutoBorrow<'tcx>,
) {
debug!(
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)?;
//! 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};
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;