Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move hir::Place to librustc_middle/hir #74424

Merged
merged 1 commit into from
Jul 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/librustc_middle/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

pub mod exports;
pub mod map;
pub mod place;

use crate::ich::StableHashingContext;
use crate::ty::query::Providers;
Expand Down
115 changes: 115 additions & 0 deletions src/librustc_middle/hir/place.rs
Original file line number Diff line number Diff line change
@@ -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.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc string fix

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.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc string fix

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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doc string fix

/// 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 }
}
}
17 changes: 9 additions & 8 deletions src/librustc_typeck/check/regionck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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))?;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 }| {
Expand All @@ -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);
Expand All @@ -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={:?})",
Expand All @@ -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);
Expand All @@ -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);
}
}
Expand Down
15 changes: 7 additions & 8 deletions src/librustc_typeck/check/upvar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -270,7 +269,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!(
Expand Down Expand Up @@ -309,7 +308,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 {
Expand All @@ -334,7 +333,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 {
Expand Down Expand Up @@ -464,12 +463,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 {
Expand All @@ -483,7 +482,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);
Expand Down
15 changes: 8 additions & 7 deletions src/librustc_typeck/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
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::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;

Expand All @@ -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)]
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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!(
Expand Down Expand Up @@ -573,7 +574,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)?;
Expand Down
Loading