Skip to content

Commit 50f3dbd

Browse files
arora-amanjenniferwillslogmosier
committed
Move hir::Place to librustc_middle/hir
Needed to support rust-lang/project-rfc-2229#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 dependcy. This resembles the MIR equivalent of `Place` located in `lbrustc_middle/mir`. Co-authored-by: Aman Arora <me@aman-arora.com> Co-authored-by: Jennifer Wills <wills.jenniferg@gmail.com> Co-authored-by: Logan Mosier <logmosier@gmail.com>
1 parent 5c9e5df commit 50f3dbd

File tree

6 files changed

+141
-133
lines changed

6 files changed

+141
-133
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

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

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

+8-7
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
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;
1212
use rustc_hir::def_id::LocalDefId;
1313
use rustc_hir::PatKind;
1414
use rustc_index::vec::Idx;
1515
use rustc_infer::infer::InferCtxt;
16+
use rustc_middle::hir::place::ProjectionKind;
1617
use rustc_middle::ty::{self, adjustment, TyCtxt};
1718
use rustc_target::abi::VariantIdx;
1819

@@ -27,13 +28,13 @@ use rustc_span::Span;
2728
pub trait Delegate<'tcx> {
2829
// The value found at `place` is either copied or moved, depending
2930
// on mode.
30-
fn consume(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, mode: ConsumeMode);
31+
fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, mode: ConsumeMode);
3132

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

3536
// The path at `place_with_id` is being assigned to.
36-
fn mutate(&mut self, assignee_place: &mc::PlaceWithHirId<'tcx>);
37+
fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>);
3738
}
3839

3940
#[derive(Copy, Clone, PartialEq, Debug)]
@@ -398,7 +399,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
398399
&*with_expr,
399400
with_place.clone(),
400401
with_field.ty(self.tcx(), substs),
401-
mc::ProjectionKind::Field(f_index as u32, VariantIdx::new(0)),
402+
ProjectionKind::Field(f_index as u32, VariantIdx::new(0)),
402403
);
403404
self.delegate_consume(&field_place);
404405
}
@@ -462,7 +463,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
462463
fn walk_autoref(
463464
&mut self,
464465
expr: &hir::Expr<'_>,
465-
base_place: &mc::PlaceWithHirId<'tcx>,
466+
base_place: &PlaceWithHirId<'tcx>,
466467
autoref: &adjustment::AutoBorrow<'tcx>,
467468
) {
468469
debug!(
@@ -573,7 +574,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
573574
closure_hir_id: hir::HirId,
574575
closure_span: Span,
575576
var_id: hir::HirId,
576-
) -> mc::McResult<mc::PlaceWithHirId<'tcx>> {
577+
) -> mc::McResult<PlaceWithHirId<'tcx>> {
577578
// Create the place for the variable being borrowed, from the
578579
// perspective of the creator (parent) of the closure.
579580
let var_ty = self.mc.node_ty(var_id)?;

0 commit comments

Comments
 (0)