Skip to content

Commit 222d250

Browse files
authoredJul 17, 2020
Rollup merge of rust-lang#74424 - sexxi-goose:move_hir_place, r=nikomatsakis
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 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
2 parents eef22da + 50f3dbd commit 222d250

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

@@ -276,7 +275,7 @@ struct InferBorrowKind<'a, 'tcx> {
276275
impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
277276
fn adjust_upvar_borrow_kind_for_consume(
278277
&mut self,
279-
place_with_id: &mc::PlaceWithHirId<'tcx>,
278+
place_with_id: &PlaceWithHirId<'tcx>,
280279
mode: euv::ConsumeMode,
281280
) {
282281
debug!(
@@ -315,7 +314,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
315314
/// Indicates that `place_with_id` is being directly mutated (e.g., assigned
316315
/// to). If the place is based on a by-ref upvar, this implies that
317316
/// the upvar must be borrowed using an `&mut` borrow.
318-
fn adjust_upvar_borrow_kind_for_mut(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>) {
317+
fn adjust_upvar_borrow_kind_for_mut(&mut self, place_with_id: &PlaceWithHirId<'tcx>) {
319318
debug!("adjust_upvar_borrow_kind_for_mut(place_with_id={:?})", place_with_id);
320319

321320
if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
@@ -340,7 +339,7 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
340339
}
341340
}
342341

343-
fn adjust_upvar_borrow_kind_for_unique(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>) {
342+
fn adjust_upvar_borrow_kind_for_unique(&mut self, place_with_id: &PlaceWithHirId<'tcx>) {
344343
debug!("adjust_upvar_borrow_kind_for_unique(place_with_id={:?})", place_with_id);
345344

346345
if let PlaceBase::Upvar(upvar_id) = place_with_id.place.base {
@@ -470,12 +469,12 @@ impl<'a, 'tcx> InferBorrowKind<'a, 'tcx> {
470469
}
471470

472471
impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
473-
fn consume(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, mode: euv::ConsumeMode) {
472+
fn consume(&mut self, place_with_id: &PlaceWithHirId<'tcx>, mode: euv::ConsumeMode) {
474473
debug!("consume(place_with_id={:?},mode={:?})", place_with_id, mode);
475474
self.adjust_upvar_borrow_kind_for_consume(place_with_id, mode);
476475
}
477476

478-
fn borrow(&mut self, place_with_id: &mc::PlaceWithHirId<'tcx>, bk: ty::BorrowKind) {
477+
fn borrow(&mut self, place_with_id: &PlaceWithHirId<'tcx>, bk: ty::BorrowKind) {
479478
debug!("borrow(place_with_id={:?}, bk={:?})", place_with_id, bk);
480479

481480
match bk {
@@ -489,7 +488,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for InferBorrowKind<'a, 'tcx> {
489488
}
490489
}
491490

492-
fn mutate(&mut self, assignee_place: &mc::PlaceWithHirId<'tcx>) {
491+
fn mutate(&mut self, assignee_place: &PlaceWithHirId<'tcx>) {
493492
debug!("mutate(assignee_place={:?})", assignee_place);
494493

495494
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!(
@@ -575,7 +576,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
575576
closure_hir_id: hir::HirId,
576577
closure_span: Span,
577578
var_id: hir::HirId,
578-
) -> mc::McResult<mc::PlaceWithHirId<'tcx>> {
579+
) -> mc::McResult<PlaceWithHirId<'tcx>> {
579580
// Create the place for the variable being borrowed, from the
580581
// perspective of the creator (parent) of the closure.
581582
let var_ty = self.mc.node_ty(var_id)?;

‎src/librustc_typeck/mem_categorization.rs

+1-110
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
//! result of `*x'`, effectively, where `x'` is a `Categorization::Upvar` reference
4949
//! tied to `x`. The type of `x'` will be a borrowed pointer.
5050
51+
use rustc_middle::hir::place::*;
5152
use rustc_middle::ty::adjustment;
5253
use rustc_middle::ty::fold::TypeFoldable;
5354
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -64,116 +65,6 @@ use rustc_span::Span;
6465
use rustc_target::abi::VariantIdx;
6566
use rustc_trait_selection::infer::InferCtxtExt;
6667

67-
#[derive(Clone, Debug)]
68-
pub enum PlaceBase {
69-
/// A temporary variable
70-
Rvalue,
71-
/// A named `static` item
72-
StaticItem,
73-
/// A named local variable
74-
Local(hir::HirId),
75-
/// An upvar referenced by closure env
76-
Upvar(ty::UpvarId),
77-
}
78-
79-
#[derive(Clone, Debug, Eq, PartialEq)]
80-
pub enum ProjectionKind {
81-
/// A dereference of a pointer, reference or `Box<T>` of the given type
82-
Deref,
83-
84-
/// `B.F` where `B` is the base expression and `F` is
85-
/// the field. The field is identified by which variant
86-
/// it appears in along with a field index. The variant
87-
/// is used for enums.
88-
Field(u32, VariantIdx),
89-
90-
/// Some index like `B[x]`, where `B` is the base
91-
/// expression. We don't preserve the index `x` because
92-
/// we won't need it.
93-
Index,
94-
95-
/// A subslice covering a range of values like `B[x..y]`.
96-
Subslice,
97-
}
98-
99-
#[derive(Clone, Debug)]
100-
pub struct Projection<'tcx> {
101-
// Type after the projection is being applied.
102-
ty: Ty<'tcx>,
103-
104-
/// Defines the type of access
105-
kind: ProjectionKind,
106-
}
107-
108-
/// A `Place` represents how a value is located in memory.
109-
///
110-
/// This is an HIR version of `mir::Place`
111-
#[derive(Clone, Debug)]
112-
pub struct Place<'tcx> {
113-
/// The type of the `PlaceBase`
114-
pub base_ty: Ty<'tcx>,
115-
/// The "outermost" place that holds this value.
116-
pub base: PlaceBase,
117-
/// How this place is derived from the base place.
118-
pub projections: Vec<Projection<'tcx>>,
119-
}
120-
121-
/// A `PlaceWithHirId` represents how a value is located in memory.
122-
///
123-
/// This is an HIR version of `mir::Place`
124-
#[derive(Clone, Debug)]
125-
pub struct PlaceWithHirId<'tcx> {
126-
/// `HirId` of the expression or pattern producing this value.
127-
pub hir_id: hir::HirId,
128-
129-
/// Information about the `Place`
130-
pub place: Place<'tcx>,
131-
}
132-
133-
impl<'tcx> PlaceWithHirId<'tcx> {
134-
crate fn new(
135-
hir_id: hir::HirId,
136-
base_ty: Ty<'tcx>,
137-
base: PlaceBase,
138-
projections: Vec<Projection<'tcx>>,
139-
) -> PlaceWithHirId<'tcx> {
140-
PlaceWithHirId {
141-
hir_id: hir_id,
142-
place: Place { base_ty: base_ty, base: base, projections: projections },
143-
}
144-
}
145-
}
146-
147-
impl<'tcx> Place<'tcx> {
148-
/// Returns an iterator of the types that have to be dereferenced to access
149-
/// the `Place`.
150-
///
151-
/// The types are in the reverse order that they are applied. So if
152-
/// `x: &*const u32` and the `Place` is `**x`, then the types returned are
153-
///`*const u32` then `&*const u32`.
154-
crate fn deref_tys(&self) -> impl Iterator<Item = Ty<'tcx>> + '_ {
155-
self.projections.iter().enumerate().rev().filter_map(move |(index, proj)| {
156-
if ProjectionKind::Deref == proj.kind {
157-
Some(self.ty_before_projection(index))
158-
} else {
159-
None
160-
}
161-
})
162-
}
163-
164-
// Returns the type of this `Place` after all projections have been applied.
165-
pub fn ty(&self) -> Ty<'tcx> {
166-
self.projections.last().map_or_else(|| self.base_ty, |proj| proj.ty)
167-
}
168-
169-
// Returns the type of this `Place` immediately before `projection_index`th projection
170-
// is applied.
171-
crate fn ty_before_projection(&self, projection_index: usize) -> Ty<'tcx> {
172-
assert!(projection_index < self.projections.len());
173-
if projection_index == 0 { self.base_ty } else { self.projections[projection_index - 1].ty }
174-
}
175-
}
176-
17768
crate trait HirNode {
17869
fn hir_id(&self) -> hir::HirId;
17970
fn span(&self) -> Span;

0 commit comments

Comments
 (0)
Please sign in to comment.