Skip to content

Commit bd5e63c

Browse files
arora-amanjenniferwillslogmosier
committed
Move hir::Place to librustc_middle/hir
Needed to support rust-lang/project-rfc-2229#7 This resembles the MIR equivalent located in `lbrustc_middle/mir`. Co-authored-by: Aman Arora <[email protected]> Co-authored-by: Jennifer Wills <[email protected]> Co-authored-by: Logan Mosier <[email protected]>
1 parent fe2c6a3 commit bd5e63c

File tree

6 files changed

+126
-120
lines changed

6 files changed

+126
-120
lines changed

src/librustc_middle/hir/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
pub mod exports;
66
pub mod map;
7+
pub mod place;
78

89
use crate::ich::StableHashingContext;
910
use crate::ty::query::Providers;

src/librustc_middle/hir/place.rs

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use crate::ty;
2+
use crate::ty::Ty;
3+
4+
use rustc_hir::HirId;
5+
6+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
7+
pub enum PlaceBase {
8+
/// A temporary variable
9+
Rvalue,
10+
/// A named `static` item
11+
StaticItem,
12+
/// A named local variable
13+
Local(HirId),
14+
/// An upvar referenced by closure env
15+
Upvar(ty::UpvarId),
16+
}
17+
18+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
19+
pub enum ProjectionKind {
20+
/// A dereference of a pointer, reference or `Box<T>` of the given type
21+
Deref,
22+
/// An index or a field
23+
Other,
24+
}
25+
26+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
27+
pub struct Projection<'tcx> {
28+
// Type after the projection is being applied.
29+
pub ty: Ty<'tcx>,
30+
31+
/// Defines the type of access
32+
pub kind: ProjectionKind,
33+
}
34+
35+
/// A `Place` represents how a value is located in memory.
36+
///
37+
/// This is an HIR version of `mir::Place`
38+
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
39+
pub struct Place<'tcx> {
40+
/// The type of the `PlaceBase`
41+
pub base_ty: Ty<'tcx>,
42+
/// The "outermost" place that holds this value.
43+
pub base: PlaceBase,
44+
/// How this place is derived from the base place.
45+
pub projections: Vec<Projection<'tcx>>,
46+
}
47+
48+
/// A `PlaceWithHirId` represents how a value is located in memory.
49+
///
50+
/// This is an HIR version of `mir::Place`
51+
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, HashStable)]
52+
pub struct PlaceWithHirId<'tcx> {
53+
/// `HirId` of the expression or pattern producing this value.
54+
pub hir_id: HirId,
55+
56+
/// Information about the `Place`
57+
pub place: Place<'tcx>,
58+
}
59+
60+
impl<'tcx> PlaceWithHirId<'tcx> {
61+
pub fn new(
62+
hir_id: HirId,
63+
base_ty: Ty<'tcx>,
64+
base: PlaceBase,
65+
projections: Vec<Projection<'tcx>>,
66+
) -> PlaceWithHirId<'tcx> {
67+
PlaceWithHirId {
68+
hir_id: hir_id,
69+
place: Place { base_ty: base_ty, base: base, projections: projections },
70+
}
71+
}
72+
}
73+
74+
impl<'tcx> Place<'tcx> {
75+
/// Returns an iterator of the types that have to be dereferenced to access
76+
/// the `Place`.
77+
///
78+
/// The types are in the reverse order that they are applied. So if
79+
/// `x: &*const u32` and the `Place` is `**x`, then the types returned are
80+
///`*const u32` then `&*const u32`.
81+
pub fn deref_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
82+
self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| {
83+
if ProjectionKind::Deref == proj.kind {
84+
Some(self.ty_before_projection(index))
85+
} else {
86+
None
87+
}
88+
})
89+
}
90+
91+
// Returns the type of this `Place` after all projections have been applied.
92+
pub fn ty(&self) -> Ty<'tcx> {
93+
self.projections.last().map_or_else(|| self.base_ty, |proj| proj.ty)
94+
}
95+
96+
// Returns the type of this `Place` immediately before `projection_index`th projection
97+
// is applied.
98+
pub fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> {
99+
assert!(projection_index < self.projections.len());
100+
if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty }
101+
}
102+
}

src/librustc_typeck/check/regionck.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
8282
use rustc_hir::PatKind;
8383
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
8484
use rustc_infer::infer::{self, RegionObligation, RegionckMode};
85+
use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId};
8586
use rustc_middle::ty::adjustment;
8687
use rustc_middle::ty::{self, Ty};
8788
use rustc_span::Span;
@@ -442,7 +443,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
442443
fn constrain_adjustments(
443444
&mut self,
444445
expr: &hir::Expr<'_>,
445-
) -> mc::McResult<mc::PlaceWithHirId<'tcx>> {
446+
) -> mc::McResult<PlaceWithHirId<'tcx>> {
446447
debug!("constrain_adjustments(expr={:?})", expr);
447448

448449
let mut place = self.with_mc(|mc| mc.cat_expr_unadjusted(expr))?;
@@ -483,10 +484,10 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
483484

484485
fn check_safety_of_rvalue_destructor_if_necessary(
485486
&mut self,
486-
place_with_id: &mc::PlaceWithHirId<'tcx>,
487+
place_with_id: &PlaceWithHirId<'tcx>,
487488
span: Span,
488489
) {
489-
if let mc::PlaceBase::Rvalue = place_with_id.place.base {
490+
if let PlaceBase::Rvalue = place_with_id.place.base {
490491
if place_with_id.place.projections.is_empty() {
491492
let typ = self.resolve_type(place_with_id.place.ty());
492493
let body_id = self.body_id;
@@ -573,7 +574,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
573574

574575
/// Link lifetimes of any ref bindings in `root_pat` to the pointers found
575576
/// in the discriminant, if needed.
576-
fn link_pattern(&self, discr_cmt: mc::PlaceWithHirId<'tcx>, root_pat: &hir::Pat<'_>) {
577+
fn link_pattern(&self, discr_cmt: PlaceWithHirId<'tcx>, root_pat: &hir::Pat<'_>) {
577578
debug!("link_pattern(discr_cmt={:?}, root_pat={:?})", discr_cmt, root_pat);
578579
ignore_err!(self.with_mc(|mc| {
579580
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> {
594595
fn link_autoref(
595596
&self,
596597
expr: &hir::Expr<'_>,
597-
expr_cmt: &mc::PlaceWithHirId<'tcx>,
598+
expr_cmt: &PlaceWithHirId<'tcx>,
598599
autoref: &adjustment::AutoBorrow<'tcx>,
599600
) {
600601
debug!("link_autoref(autoref={:?}, expr_cmt={:?})", autoref, expr_cmt);
@@ -615,7 +616,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
615616
span: Span,
616617
id: hir::HirId,
617618
mutbl: hir::Mutability,
618-
cmt_borrowed: &mc::PlaceWithHirId<'tcx>,
619+
cmt_borrowed: &PlaceWithHirId<'tcx>,
619620
) {
620621
debug!(
621622
"link_region_from_node_type(id={:?}, mutbl={:?}, cmt_borrowed={:?})",
@@ -638,7 +639,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
638639
span: Span,
639640
borrow_region: ty::Region<'tcx>,
640641
borrow_kind: ty::BorrowKind,
641-
borrow_place: &mc::PlaceWithHirId<'tcx>,
642+
borrow_place: &PlaceWithHirId<'tcx>,
642643
) {
643644
let origin = infer::DataBorrowed(borrow_place.place.ty(), span);
644645
self.type_must_outlive(origin, borrow_place.place.ty(), borrow_region);
@@ -659,7 +660,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
659660
_ => assert!(pointer_ty.is_box(), "unexpected built-in deref type {}", pointer_ty),
660661
}
661662
}
662-
if let mc::PlaceBase::Upvar(upvar_id) = borrow_place.place.base {
663+
if let PlaceBase::Upvar(upvar_id) = borrow_place.place.base {
663664
self.link_upvar_region(span, borrow_region, upvar_id);
664665
}
665666
}

src/librustc_typeck/check/upvar.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,13 @@
3333
use super::FnCtxt;
3434

3535
use crate::expr_use_visitor as euv;
36-
use crate::mem_categorization as mc;
37-
use crate::mem_categorization::PlaceBase;
3836
use rustc_data_structures::fx::FxIndexMap;
3937
use rustc_hir as hir;
4038
use rustc_hir::def_id::DefId;
4139
use rustc_hir::def_id::LocalDefId;
4240
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
4341
use rustc_infer::infer::UpvarRegion;
42+
use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId};
4443
use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts};
4544
use rustc_span::{Span, Symbol};
4645

@@ -270,7 +269,7 @@ struct InferBorrowKind<'a, 'tcx> {
270269
impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
271270
fn adjust_upvar_borrow_kind_for_consume(
272271
&mut self,
273-
place_with_id: &mc::PlaceWithHirId<'tcx>,
272+
place_with_id: &PlaceWithHirId<'tcx>,
274273
mode: euv::ConsumeMode,
275274
) {
276275
debug!(
@@ -309,7 +308,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
309308
/// Indicates that `place_with_id` is being directly mutated (e.g., assigned
310309
/// to). If the place is based on a by-ref upvar, this implies that
311310
/// the upvar must be borrowed using an `&mut` borrow.
312-
fn adjust_upvar_borrow_kind_for_mut(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>) {
311+
fn adjust_upvar_borrow_kind_for_mut(&mut self, place_with_id: &PlaceWithHirId<'tcx>) {
313312
debug!("adjust_upvar_borrow_kind_for_mut(place_with_id={:?})", place_with_id);
314313

315314
if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
@@ -334,7 +333,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
334333
}
335334
}
336335

337-
fn adjust_upvar_borrow_kind_for_unique(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>) {
336+
fn adjust_upvar_borrow_kind_for_unique(&mut self, place_with_id: &PlaceWithHirId<'tcx>) {
338337
debug!("adjust_upvar_borrow_kind_for_unique(place_with_id={:?})", place_with_id);
339338

340339
if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
@@ -464,12 +463,12 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
464463
}
465464

466465
impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
467-
fn consume(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, mode: euv::ConsumeMode) {
466+
fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, mode: euv::ConsumeMode) {
468467
debug!("consume(place_with_id={:?},mode={:?})", place_with_id, mode);
469468
self.adjust_upvar_borrow_kind_for_consume(place_with_id, mode);
470469
}
471470

472-
fn borrow(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, bk: ty::BorrowKind) {
471+
fn borrow(&mut self, place_with_id: &PlaceWithHirId<'tcx>, bk: ty::BorrowKind) {
473472
debug!("borrow(place_with_id={:?}, bk={:?})", place_with_id, bk);
474473

475474
match bk {
@@ -483,7 +482,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
483482
}
484483
}
485484

486-
fn mutate(&mut self, assignee_place: &mc::PlaceWithHirId<'tcx>) {
485+
fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>) {
487486
debug!("mutate(assignee_place={:?})", assignee_place);
488487

489488
self.adjust_upvar_borrow_kind_for_mut(assignee_place);

src/librustc_typeck/expr_use_visitor.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
pub use self::ConsumeMode::*;
66

77
// Export these here so that Clippy can use them.
8-
pub use mc::{PlaceBase, PlaceWithHirId, Projection};
8+
pub use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId, Projection};
99

1010
use rustc_hir as hir;
1111
use rustc_hir::def::Res;
@@ -25,13 +25,13 @@ use rustc_span::Span;
2525
pub trait Delegate<'tcx> {
2626
// The value found at `place` is either copied or moved, depending
2727
// on mode.
28-
fn consume(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, mode: ConsumeMode);
28+
fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, mode: ConsumeMode);
2929

3030
// The value found at `place` is being borrowed with kind `bk`.
31-
fn borrow(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, bk: ty::BorrowKind);
31+
fn borrow(&mut self, place_with_id: &PlaceWithHirId<'tcx>, bk: ty::BorrowKind);
3232

3333
// The path at `place_with_id` is being assigned to.
34-
fn mutate(&mut self, assignee_place: &mc::PlaceWithHirId<'tcx>);
34+
fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>);
3535
}
3636

3737
#[derive(Copy, Clone, PartialEq, Debug)]
@@ -459,7 +459,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
459459
fn walk_autoref(
460460
&mut self,
461461
expr: &hir::Expr<'_>,
462-
base_place: &mc::PlaceWithHirId<'tcx>,
462+
base_place: &PlaceWithHirId<'tcx>,
463463
autoref: &adjustment::AutoBorrow<'tcx>,
464464
) {
465465
debug!(
@@ -570,7 +570,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
570570
closure_hir_id: hir::HirId,
571571
closure_span: Span,
572572
var_id: hir::HirId,
573-
) -> mc::McResult<mc::PlaceWithHirId<'tcx>> {
573+
) -> mc::McResult<PlaceWithHirId<'tcx>> {
574574
// Create the place for the variable being borrowed, from the
575575
// perspective of the creator (parent) of the closure.
576576
let var_ty = self.mc.node_ty(var_id)?;

0 commit comments

Comments
 (0)