Skip to content

Commit 53ba12c

Browse files
authored
Rollup merge of rust-lang#65197 - spastorino:place-mut-visitor-adjusts2, r=oli-obk
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 13e47c8 + 4834996 commit 53ba12c

File tree

8 files changed

+301
-122
lines changed

8 files changed

+301
-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 Some(elem) = self.process_projection_elem(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: &PlaceElem<'tcx>,
824+
) -> Option<PlaceElem<'tcx>> {
825+
None
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

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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;
@@ -62,6 +62,21 @@ impl<'a, 'tcx> MutVisitor<'tcx> for NLLVisitor<'a, 'tcx> {
6262
debug!("visit_ty: ty={:?}", ty);
6363
}
6464

65+
fn process_projection_elem(
66+
&mut self,
67+
elem: &PlaceElem<'tcx>,
68+
) -> Option<PlaceElem<'tcx>> {
69+
if let PlaceElem::Field(field, ty) = elem {
70+
let new_ty = self.renumber_regions(ty);
71+
72+
if new_ty != *ty {
73+
return Some(PlaceElem::Field(*field, new_ty));
74+
}
75+
}
76+
77+
None
78+
}
79+
6580
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, location: Location) {
6681
debug!("visit_substs(substs={:?}, location={:?})", substs, location);
6782

src/librustc_mir/transform/erase_regions.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ impl EraseRegionsVisitor<'tcx> {
2525
impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
2626
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
2727
*ty = self.tcx.erase_regions(ty);
28-
self.super_ty(ty);
2928
}
3029

3130
fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
@@ -39,6 +38,21 @@ impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
3938
fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
4039
*substs = self.tcx.erase_regions(substs);
4140
}
41+
42+
fn process_projection_elem(
43+
&mut self,
44+
elem: &PlaceElem<'tcx>,
45+
) -> Option<PlaceElem<'tcx>> {
46+
if let PlaceElem::Field(field, ty) = elem {
47+
let new_ty = self.tcx.erase_regions(ty);
48+
49+
if new_ty != *ty {
50+
return Some(PlaceElem::Field(*field, new_ty));
51+
}
52+
}
53+
54+
None
55+
}
4256
}
4357

4458
pub struct EraseRegions;

src/librustc_mir/transform/generator.rs

+39-7
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,18 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
8888
*local = self.to;
8989
}
9090
}
91+
92+
fn process_projection_elem(
93+
&mut self,
94+
elem: &PlaceElem<'tcx>,
95+
) -> Option<PlaceElem<'tcx>> {
96+
match elem {
97+
PlaceElem::Index(local) if *local == self.from => {
98+
Some(PlaceElem::Index(self.to))
99+
}
100+
_ => None,
101+
}
102+
}
91103
}
92104

93105
struct DerefArgVisitor;
@@ -110,7 +122,13 @@ impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
110122
projection: Box::new([ProjectionElem::Deref]),
111123
});
112124
} else {
113-
self.super_place(place, context, location);
125+
self.visit_place_base(&mut place.base, context, location);
126+
127+
for elem in place.projection.iter() {
128+
if let PlaceElem::Index(local) = elem {
129+
assert_ne!(*local, self_arg());
130+
}
131+
}
114132
}
115133
}
116134
}
@@ -137,7 +155,13 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
137155
projection: Box::new([ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]),
138156
});
139157
} else {
140-
self.super_place(place, context, location);
158+
self.visit_place_base(&mut place.base, context, location);
159+
160+
for elem in place.projection.iter() {
161+
if let PlaceElem::Index(local) = elem {
162+
assert_ne!(*local, self_arg());
163+
}
164+
}
141165
}
142166
}
143167
}
@@ -247,17 +271,25 @@ impl MutVisitor<'tcx> for TransformVisitor<'tcx> {
247271
assert_eq!(self.remap.get(local), None);
248272
}
249273

250-
fn visit_place(&mut self,
251-
place: &mut Place<'tcx>,
252-
context: PlaceContext,
253-
location: Location) {
274+
fn visit_place(
275+
&mut self,
276+
place: &mut Place<'tcx>,
277+
context: PlaceContext,
278+
location: Location,
279+
) {
254280
if let PlaceBase::Local(l) = place.base {
255281
// Replace an Local in the remap with a generator struct access
256282
if let Some(&(ty, variant_index, idx)) = self.remap.get(&l) {
257283
replace_base(place, self.make_field(variant_index, idx, ty));
258284
}
259285
} else {
260-
self.super_place(place, context, location);
286+
self.visit_place_base(&mut place.base, context, location);
287+
288+
for elem in place.projection.iter() {
289+
if let PlaceElem::Index(local) = elem {
290+
assert_ne!(*local, self_arg());
291+
}
292+
}
261293
}
262294
}
263295

0 commit comments

Comments
 (0)