Skip to content

Commit dc67089

Browse files
committed
Auto merge of #65197 - spastorino:place-mut-visitor-adjusts2, r=<try>
Prepare `MutVisitor`s to handle interned projections The following are all the files where mir's `MutVisitor` is implemented. The `-` there stands for no changes, `visit_place` wasn't making any change on `Place`s. `x` stands for this file was changed to make `visit_place` do whatever it was doing with the base but avoid modifying the projection, instead just create a new one and assign to it. ``` [-] src/librustc_mir/transform/no_landing_pads.rs [x] src/librustc_mir/transform/promote_consts.rs [x] src/librustc_mir/transform/generator.rs [x] src/librustc_mir/transform/erase_regions.rs [-] src/librustc_mir/transform/instcombine.rs [x] src/librustc_mir/transform/inline.rs [x] src/librustc_mir/transform/simplify.rs [x] src/librustc_mir/util/def_use.rs [-] src/librustc_mir/transform/const_prop.rs [-] src/librustc_mir/transform/cleanup_post_borrowck.rs [x] src/librustc_mir/borrow_check/nll/renumber.rs [-] src/librustc_mir/transform/copy_prop.rs ``` There is some code repetition, just created the PR so we can start discussing it. /cc @oli-obk @nikomatsakis
2 parents d4f7f97 + cdf33d9 commit dc67089

File tree

8 files changed

+303
-122
lines changed

8 files changed

+303
-122
lines changed

src/librustc/mir/visit.rs

+136-77
Original file line numberDiff line numberDiff line change
@@ -158,22 +158,7 @@ macro_rules! make_mir_visitor {
158158
self.super_place_base(base, context, location);
159159
}
160160

161-
fn visit_projection(&mut self,
162-
base: & $($mutability)? PlaceBase<'tcx>,
163-
projection: & $($mutability)? [PlaceElem<'tcx>],
164-
context: PlaceContext,
165-
location: Location) {
166-
self.super_projection(base, projection, context, location);
167-
}
168-
169-
fn visit_projection_elem(&mut self,
170-
base: & $($mutability)? PlaceBase<'tcx>,
171-
proj_base: & $($mutability)? [PlaceElem<'tcx>],
172-
elem: & $($mutability)? PlaceElem<'tcx>,
173-
context: PlaceContext,
174-
location: Location) {
175-
self.super_projection_elem(base, proj_base, elem, context, location);
176-
}
161+
visit_place_fns!($($mutability)?);
177162

178163
fn visit_constant(&mut self,
179164
constant: & $($mutability)? Constant<'tcx>,
@@ -681,28 +666,6 @@ macro_rules! make_mir_visitor {
681666
);
682667
}
683668

684-
fn super_place(&mut self,
685-
place: & $($mutability)? Place<'tcx>,
686-
context: PlaceContext,
687-
location: Location) {
688-
let mut context = context;
689-
690-
if !place.projection.is_empty() {
691-
context = if context.is_mutating_use() {
692-
PlaceContext::MutatingUse(MutatingUseContext::Projection)
693-
} else {
694-
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
695-
};
696-
}
697-
698-
self.visit_place_base(& $($mutability)? place.base, context, location);
699-
700-
self.visit_projection(& $($mutability)? place.base,
701-
& $($mutability)? place.projection,
702-
context,
703-
location);
704-
}
705-
706669
fn super_place_base(&mut self,
707670
place_base: & $($mutability)? PlaceBase<'tcx>,
708671
context: PlaceContext,
@@ -717,45 +680,6 @@ macro_rules! make_mir_visitor {
717680
}
718681
}
719682

720-
fn super_projection(&mut self,
721-
base: & $($mutability)? PlaceBase<'tcx>,
722-
projection: & $($mutability)? [PlaceElem<'tcx>],
723-
context: PlaceContext,
724-
location: Location) {
725-
let mut cursor = projection;
726-
while let [proj_base @ .., elem] = cursor {
727-
cursor = proj_base;
728-
self.visit_projection_elem(base, cursor, elem, context, location);
729-
}
730-
}
731-
732-
fn super_projection_elem(&mut self,
733-
_base: & $($mutability)? PlaceBase<'tcx>,
734-
_proj_base: & $($mutability)? [PlaceElem<'tcx>],
735-
elem: & $($mutability)? PlaceElem<'tcx>,
736-
_context: PlaceContext,
737-
location: Location) {
738-
match elem {
739-
ProjectionElem::Field(_field, ty) => {
740-
self.visit_ty(ty, TyContext::Location(location));
741-
}
742-
ProjectionElem::Index(local) => {
743-
self.visit_local(
744-
local,
745-
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
746-
location
747-
);
748-
}
749-
ProjectionElem::Deref |
750-
ProjectionElem::Subslice { from: _, to: _ } |
751-
ProjectionElem::ConstantIndex { offset: _,
752-
min_length: _,
753-
from_end: _ } |
754-
ProjectionElem::Downcast(_, _) => {
755-
}
756-
}
757-
}
758-
759683
fn super_local_decl(&mut self,
760684
local: Local,
761685
local_decl: & $($mutability)? LocalDecl<'tcx>) {
@@ -858,6 +782,141 @@ macro_rules! make_mir_visitor {
858782
}
859783
}
860784

785+
macro_rules! visit_place_fns {
786+
(mut) => (
787+
fn super_place(
788+
&mut self,
789+
place: &mut Place<'tcx>,
790+
context: PlaceContext,
791+
location: Location,
792+
) {
793+
self.visit_place_base(&mut place.base, context, location);
794+
795+
if let Some(new_projection) = self.process_projection(&place.projection) {
796+
place.projection = new_projection;
797+
}
798+
}
799+
800+
fn process_projection(
801+
&mut self,
802+
projection: &'a [PlaceElem<'tcx>],
803+
) -> Option<Box<[PlaceElem<'tcx>]>> {
804+
let mut projection = Cow::Borrowed(projection);
805+
806+
for i in 0..projection.len() {
807+
if let Some(elem) = projection.get(i) {
808+
if let Cow::Owned(elem) = self.process_projection_elem(Cow::Borrowed(elem)) {
809+
let vec = projection.to_mut();
810+
vec[i] = elem;
811+
}
812+
}
813+
}
814+
815+
match projection {
816+
Cow::Borrowed(_) => None,
817+
Cow::Owned(vec) => Some(vec.into_boxed_slice()),
818+
}
819+
}
820+
821+
fn process_projection_elem(
822+
&mut self,
823+
elem: Cow<'a, PlaceElem<'tcx>>,
824+
) -> Cow<'a, PlaceElem<'tcx>> {
825+
elem
826+
}
827+
);
828+
829+
() => (
830+
fn visit_projection(
831+
&mut self,
832+
base: &PlaceBase<'tcx>,
833+
projection: &[PlaceElem<'tcx>],
834+
context: PlaceContext,
835+
location: Location,
836+
) {
837+
self.super_projection(base, projection, context, location);
838+
}
839+
840+
fn visit_projection_elem(
841+
&mut self,
842+
base: &PlaceBase<'tcx>,
843+
proj_base: &[PlaceElem<'tcx>],
844+
elem: &PlaceElem<'tcx>,
845+
context: PlaceContext,
846+
location: Location,
847+
) {
848+
self.super_projection_elem(base, proj_base, elem, context, location);
849+
}
850+
851+
fn super_place(
852+
&mut self,
853+
place: &Place<'tcx>,
854+
context: PlaceContext,
855+
location: Location,
856+
) {
857+
let mut context = context;
858+
859+
if !place.projection.is_empty() {
860+
context = if context.is_mutating_use() {
861+
PlaceContext::MutatingUse(MutatingUseContext::Projection)
862+
} else {
863+
PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
864+
};
865+
}
866+
867+
self.visit_place_base(&place.base, context, location);
868+
869+
self.visit_projection(&place.base,
870+
&place.projection,
871+
context,
872+
location);
873+
}
874+
875+
fn super_projection(
876+
&mut self,
877+
base: &PlaceBase<'tcx>,
878+
projection: &[PlaceElem<'tcx>],
879+
context: PlaceContext,
880+
location: Location,
881+
) {
882+
let mut cursor = projection;
883+
while let [proj_base @ .., elem] = cursor {
884+
cursor = proj_base;
885+
self.visit_projection_elem(base, cursor, elem, context, location);
886+
}
887+
}
888+
889+
fn super_projection_elem(
890+
&mut self,
891+
_base: &PlaceBase<'tcx>,
892+
_proj_base: &[PlaceElem<'tcx>],
893+
elem: &PlaceElem<'tcx>,
894+
_context: PlaceContext,
895+
location: Location,
896+
) {
897+
match elem {
898+
ProjectionElem::Field(_field, ty) => {
899+
self.visit_ty(ty, TyContext::Location(location));
900+
}
901+
ProjectionElem::Index(local) => {
902+
self.visit_local(
903+
local,
904+
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
905+
location
906+
);
907+
}
908+
ProjectionElem::Deref |
909+
ProjectionElem::Subslice { from: _, to: _ } |
910+
ProjectionElem::ConstantIndex { offset: _,
911+
min_length: _,
912+
from_end: _ } |
913+
ProjectionElem::Downcast(_, _) => {
914+
}
915+
}
916+
}
917+
);
918+
}
919+
861920
make_mir_visitor!(Visitor,);
862921
make_mir_visitor!(MutVisitor,mut);
863922

src/librustc_mir/borrow_check/nll/renumber.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
use rustc::ty::subst::SubstsRef;
22
use rustc::ty::{self, Ty, TypeFoldable};
3-
use rustc::mir::{Location, Body, Promoted};
3+
use rustc::mir::{Body, Location, PlaceElem, Promoted};
44
use rustc::mir::visit::{MutVisitor, TyContext};
55
use rustc::infer::{InferCtxt, NLLRegionVariableOrigin};
66
use rustc_index::vec::IndexVec;
7+
use std::borrow::Cow;
78

89
/// Replaces all free regions appearing in the MIR with fresh
910
/// inference variables, returning the number of variables created.
@@ -62,6 +63,18 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
6263
debug!("visit_ty: ty={:?}", ty);
6364
}
6465

66+
fn process_projection_elem(
67+
&mut self,
68+
elem: Cow<'b, PlaceElem<'tcx>>,
69+
) -> Cow<'b, PlaceElem<'tcx>> {
70+
match elem {
71+
Cow::Borrowed(PlaceElem::Field(field, ty)) => {
72+
Cow::Owned(PlaceElem::Field(*field, self.renumber_regions(ty)))
73+
}
74+
_ => elem,
75+
}
76+
}
77+
6578
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
6679
debug!("visit_substs(substs={:?}, location={:?})", substs, location);
6780

src/librustc_mir/transform/erase_regions.rs

+13-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use rustc::ty::{self, Ty, TyCtxt};
99
use rustc::mir::*;
1010
use rustc::mir::visit::{MutVisitor, TyContext};
1111
use crate::transform::{MirPass, MirSource};
12+
use std::borrow::Cow;
1213

1314
struct EraseRegionsVisitor<'tcx> {
1415
tcx: TyCtxt<'tcx>,
@@ -25,7 +26,6 @@ impl EraseRegionsVisitor<'tcx> {
2526
impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
2627
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
2728
*ty = self.tcx.erase_regions(ty);
28-
self.super_ty(ty);
2929
}
3030

3131
fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
@@ -39,6 +39,18 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
3939
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
4040
*substs = self.tcx.erase_regions(substs);
4141
}
42+
43+
fn process_projection_elem(
44+
&mut self,
45+
elem: Cow<'a, PlaceElem<'tcx>>,
46+
) -> Cow<'a, PlaceElem<'tcx>> {
47+
match elem {
48+
Cow::Borrowed(PlaceElem::Field(field, ty)) => {
49+
Cow::Owned(PlaceElem::Field(*field, self.tcx.erase_regions(ty)))
50+
}
51+
_ => elem,
52+
}
53+
}
4254
}
4355

4456
pub struct EraseRegions;

src/librustc_mir/transform/generator.rs

+45-7
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,24 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
8888
*local = self.to;
8989
}
9090
}
91+
92+
fn visit_place(&mut self,
93+
place: &mut Place<'tcx>,
94+
context: PlaceContext,
95+
location: Location) {
96+
self.visit_place_base(&mut place.base, context, location);
97+
98+
let new_projection: Vec<_> = place.projection.iter().map(|elem|
99+
match elem {
100+
PlaceElem::Index(local) if *local == self.from => {
101+
PlaceElem::Index(self.to)
102+
}
103+
_ => elem.clone(),
104+
}
105+
).collect();
106+
107+
place.projection = new_projection.into_boxed_slice();
108+
}
91109
}
92110

93111
struct DerefArgVisitor;
@@ -110,7 +128,13 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
110128
projection: Box::new([ProjectionElem::Deref]),
111129
});
112130
} else {
113-
self.super_place(place, context, location);
131+
self.visit_place_base(&mut place.base, context, location);
132+
133+
for elem in place.projection.iter() {
134+
if let PlaceElem::Index(local) = elem {
135+
assert_ne!(*local, self_arg());
136+
}
137+
}
114138
}
115139
}
116140
}
@@ -137,7 +161,13 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
137161
projection: Box::new([ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]),
138162
});
139163
} else {
140-
self.super_place(place, context, location);
164+
self.visit_place_base(&mut place.base, context, location);
165+
166+
for elem in place.projection.iter() {
167+
if let PlaceElem::Index(local) = elem {
168+
assert_ne!(*local, self_arg());
169+
}
170+
}
141171
}
142172
}
143173
}
@@ -247,17 +277,25 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
247277
assert_eq!(self.remap.get(local), None);
248278
}
249279

250-
fn visit_place(&mut self,
251-
place: &mut Place<'tcx>,
252-
context: PlaceContext,
253-
location: Location) {
280+
fn visit_place(
281+
&mut self,
282+
place: &mut Place<'tcx>,
283+
context: PlaceContext,
284+
location: Location,
285+
) {
254286
if let PlaceBase::Local(l) = place.base {
255287
// Replace an Local in the remap with a generator struct access
256288
if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) {
257289
replace_base(place, self.make_field(variant_index, idx, ty));
258290
}
259291
} else {
260-
self.super_place(place, context, location);
292+
self.visit_place_base(&mut place.base, context, location);
293+
294+
for elem in place.projection.iter() {
295+
if let PlaceElem::Index(local) = elem {
296+
assert_ne!(*local, self_arg());
297+
}
298+
}
261299
}
262300
}
263301

0 commit comments

Comments
 (0)