Skip to content

Commit a6946a8

Browse files
committed
Auto merge of #63420 - spastorino:place2_5, r=oli-obk
[Place 2.0] Convert Place's projection to a boxed slice This is still work in progress, it's not compiling right now I need to review a bit more to see what's going on but wanted to open the PR to start discussing it. r? @oli-obk
2 parents 3287a65 + 28db2c9 commit a6946a8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1590
-1776
lines changed

src/librustc/mir/mod.rs

+91-217
Large diffs are not rendered by default.

src/librustc/mir/tcx.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -121,21 +121,16 @@ BraceStructTypeFoldableImpl! {
121121
impl<'tcx> Place<'tcx> {
122122
pub fn ty_from<D>(
123123
base: &PlaceBase<'tcx>,
124-
projection: &Option<Box<Projection<'tcx>>>,
124+
projection: &[PlaceElem<'tcx>],
125125
local_decls: &D,
126126
tcx: TyCtxt<'tcx>
127127
) -> PlaceTy<'tcx>
128128
where D: HasLocalDecls<'tcx>
129129
{
130-
Place::iterate_over(base, projection, |place_base, place_projections| {
131-
let mut place_ty = place_base.ty(local_decls);
132-
133-
for proj in place_projections {
134-
place_ty = place_ty.projection_ty(tcx, &proj.elem);
135-
}
136-
137-
place_ty
138-
})
130+
projection.iter().fold(
131+
base.ty(local_decls),
132+
|place_ty, elem| place_ty.projection_ty(tcx, elem)
133+
)
139134
}
140135

141136
pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx>

src/librustc/mir/visit.rs

+39-33
Original file line numberDiff line numberDiff line change
@@ -152,18 +152,18 @@ macro_rules! make_mir_visitor {
152152
}
153153

154154
fn visit_place_base(&mut self,
155-
place_base: & $($mutability)? PlaceBase<'tcx>,
155+
base: & $($mutability)? PlaceBase<'tcx>,
156156
context: PlaceContext,
157157
location: Location) {
158-
self.super_place_base(place_base, context, location);
158+
self.super_place_base(base, context, location);
159159
}
160160

161161
fn visit_projection(&mut self,
162-
place_base: & $($mutability)? PlaceBase<'tcx>,
163-
place: & $($mutability)? Projection<'tcx>,
162+
base: & $($mutability)? PlaceBase<'tcx>,
163+
projection: & $($mutability)? [PlaceElem<'tcx>],
164164
context: PlaceContext,
165165
location: Location) {
166-
self.super_projection(place_base, place, context, location);
166+
self.super_projection(base, projection, context, location);
167167
}
168168

169169
fn visit_constant(&mut self,
@@ -344,7 +344,9 @@ macro_rules! make_mir_visitor {
344344

345345
self.visit_source_info(source_info);
346346
match kind {
347-
StatementKind::Assign(place, rvalue) => {
347+
StatementKind::Assign(
348+
box(ref $($mutability)? place, ref $($mutability)? rvalue)
349+
) => {
348350
self.visit_assign(place, rvalue, location);
349351
}
350352
StatementKind::FakeRead(_, place) => {
@@ -391,7 +393,10 @@ macro_rules! make_mir_visitor {
391393
StatementKind::Retag(kind, place) => {
392394
self.visit_retag(kind, place, location);
393395
}
394-
StatementKind::AscribeUserType(place, variance, user_ty) => {
396+
StatementKind::AscribeUserType(
397+
box(ref $($mutability)? place, ref $($mutability)? user_ty),
398+
variance
399+
) => {
395400
self.visit_ascribe_user_ty(place, variance, user_ty, location);
396401
}
397402
StatementKind::Nop => {}
@@ -685,7 +690,7 @@ macro_rules! make_mir_visitor {
685690
location: Location) {
686691
let mut context = context;
687692

688-
if place.projection.is_some() {
693+
if !place.projection.is_empty() {
689694
context = if context.is_mutating_use() {
690695
PlaceContext::MutatingUse(MutatingUseContext::Projection)
691696
} else {
@@ -695,9 +700,10 @@ macro_rules! make_mir_visitor {
695700

696701
self.visit_place_base(& $($mutability)? place.base, context, location);
697702

698-
if let Some(box proj) = & $($mutability)? place.projection {
699-
self.visit_projection(& $($mutability)? place.base, proj, context, location);
700-
}
703+
self.visit_projection(& $($mutability)? place.base,
704+
& $($mutability)? place.projection,
705+
context,
706+
location);
701707
}
702708

703709
fn super_place_base(&mut self,
@@ -715,31 +721,31 @@ macro_rules! make_mir_visitor {
715721
}
716722

717723
fn super_projection(&mut self,
718-
place_base: & $($mutability)? PlaceBase<'tcx>,
719-
proj: & $($mutability)? Projection<'tcx>,
724+
base: & $($mutability)? PlaceBase<'tcx>,
725+
projection: & $($mutability)? [PlaceElem<'tcx>],
720726
context: PlaceContext,
721727
location: Location) {
722-
if let Some(box proj_base) = & $($mutability)? proj.base {
723-
self.visit_projection(place_base, proj_base, context, location);
724-
}
728+
if let [proj_base @ .., elem] = projection {
729+
self.visit_projection(base, proj_base, context, location);
725730

726-
match & $($mutability)? proj.elem {
727-
ProjectionElem::Field(_field, ty) => {
728-
self.visit_ty(ty, TyContext::Location(location));
729-
}
730-
ProjectionElem::Index(local) => {
731-
self.visit_local(
732-
local,
733-
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
734-
location
735-
);
736-
}
737-
ProjectionElem::Deref |
738-
ProjectionElem::Subslice { from: _, to: _ } |
739-
ProjectionElem::ConstantIndex { offset: _,
740-
min_length: _,
741-
from_end: _ } |
742-
ProjectionElem::Downcast(_, _) => {
731+
match elem {
732+
ProjectionElem::Field(_field, ty) => {
733+
self.visit_ty(ty, TyContext::Location(location));
734+
}
735+
ProjectionElem::Index(local) => {
736+
self.visit_local(
737+
local,
738+
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
739+
location
740+
);
741+
}
742+
ProjectionElem::Deref |
743+
ProjectionElem::Subslice { from: _, to: _ } |
744+
ProjectionElem::ConstantIndex { offset: _,
745+
min_length: _,
746+
from_end: _ } |
747+
ProjectionElem::Downcast(_, _) => {
748+
}
743749
}
744750
}
745751
}

src/librustc_codegen_ssa/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![feature(box_syntax)]
55
#![feature(core_intrinsics)]
66
#![feature(libc)]
7+
#![feature(slice_patterns)]
78
#![feature(stmt_expr_attributes)]
89
#![feature(try_blocks)]
910
#![feature(in_band_lifetimes)]

src/librustc_codegen_ssa/mir/analyze.rs

+10-13
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
105105
) {
106106
let cx = self.fx.cx;
107107

108-
if let Some(proj) = place_ref.projection {
108+
if let [proj_base @ .., elem] = place_ref.projection {
109109
// Allow uses of projections that are ZSTs or from scalar fields.
110110
let is_consume = match context {
111111
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy) |
@@ -114,12 +114,12 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
114114
};
115115
if is_consume {
116116
let base_ty =
117-
mir::Place::ty_from(place_ref.base, &proj.base, self.fx.mir, cx.tcx());
117+
mir::Place::ty_from(place_ref.base, proj_base, self.fx.mir, cx.tcx());
118118
let base_ty = self.fx.monomorphize(&base_ty);
119119

120120
// ZSTs don't require any actual memory access.
121121
let elem_ty = base_ty
122-
.projection_ty(cx.tcx(), &proj.elem)
122+
.projection_ty(cx.tcx(), elem)
123123
.ty;
124124
let elem_ty = self.fx.monomorphize(&elem_ty);
125125
let span = if let mir::PlaceBase::Local(index) = place_ref.base {
@@ -131,7 +131,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
131131
return;
132132
}
133133

134-
if let mir::ProjectionElem::Field(..) = proj.elem {
134+
if let mir::ProjectionElem::Field(..) = elem {
135135
let layout = cx.spanned_layout_of(base_ty.ty, span);
136136
if cx.is_backend_immediate(layout) || cx.is_backend_scalar_pair(layout) {
137137
// Recurse with the same context, instead of `Projection`,
@@ -140,7 +140,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
140140
self.process_place(
141141
&mir::PlaceRef {
142142
base: place_ref.base,
143-
projection: &proj.base,
143+
projection: proj_base,
144144
},
145145
context,
146146
location,
@@ -151,11 +151,11 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
151151
}
152152

153153
// A deref projection only reads the pointer, never needs the place.
154-
if let mir::ProjectionElem::Deref = proj.elem {
154+
if let mir::ProjectionElem::Deref = elem {
155155
self.process_place(
156156
&mir::PlaceRef {
157157
base: place_ref.base,
158-
projection: &proj.base,
158+
projection: proj_base,
159159
},
160160
PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy),
161161
location
@@ -168,7 +168,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
168168
// visit_place API
169169
let mut context = context;
170170

171-
if place_ref.projection.is_some() {
171+
if !place_ref.projection.is_empty() {
172172
context = if context.is_mutating_use() {
173173
PlaceContext::MutatingUse(MutatingUseContext::Projection)
174174
} else {
@@ -177,10 +177,7 @@ impl<Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
177177
}
178178

179179
self.visit_place_base(place_ref.base, context, location);
180-
181-
if let Some(box proj) = place_ref.projection {
182-
self.visit_projection(place_ref.base, proj, context, location);
183-
}
180+
self.visit_projection(place_ref.base, place_ref.projection, context, location);
184181
}
185182

186183
}
@@ -196,7 +193,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
196193

197194
if let mir::Place {
198195
base: mir::PlaceBase::Local(index),
199-
projection: None,
196+
projection: box [],
200197
} = *place {
201198
self.assign(index, location);
202199
let decl_span = self.fx.mir.local_decls[index].source_info.span;

src/librustc_codegen_ssa/mir/block.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
253253

254254
PassMode::Direct(_) | PassMode::Pair(..) => {
255255
let op =
256-
self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE.as_ref());
256+
self.codegen_consume(&mut bx, &mir::Place::return_place().as_ref());
257257
if let Ref(llval, _, align) = op.val {
258258
bx.load(llval, align)
259259
} else {
@@ -612,7 +612,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
612612
ty,
613613
def_id: _,
614614
}),
615-
projection: None,
615+
projection: box [],
616616
}
617617
) |
618618
mir::Operand::Move(
@@ -622,7 +622,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
622622
ty,
623623
def_id: _,
624624
}),
625-
projection: None,
625+
projection: box [],
626626
}
627627
) => {
628628
let param_env = ty::ParamEnv::reveal_all();
@@ -1105,7 +1105,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11051105
}
11061106
let dest = if let mir::Place {
11071107
base: mir::PlaceBase::Local(index),
1108-
projection: None,
1108+
projection: box [],
11091109
} = *dest {
11101110
match self.locals[index] {
11111111
LocalRef::Place(dest) => dest,
@@ -1166,7 +1166,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
11661166
) {
11671167
if let mir::Place {
11681168
base: mir::PlaceBase::Local(index),
1169-
projection: None,
1169+
projection: box [],
11701170
} = *dst {
11711171
match self.locals[index] {
11721172
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),

src/librustc_codegen_ssa/mir/operand.rs

+33-35
Original file line numberDiff line numberDiff line change
@@ -384,47 +384,45 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
384384
) -> Option<OperandRef<'tcx, Bx::Value>> {
385385
debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref);
386386

387-
place_ref.iterate(|place_base, place_projection| {
388-
if let mir::PlaceBase::Local(index) = place_base {
389-
match self.locals[*index] {
390-
LocalRef::Operand(Some(mut o)) => {
391-
// Moves out of scalar and scalar pair fields are trivial.
392-
for proj in place_projection {
393-
match proj.elem {
394-
mir::ProjectionElem::Field(ref f, _) => {
395-
o = o.extract_field(bx, f.index());
396-
}
397-
mir::ProjectionElem::Index(_) |
398-
mir::ProjectionElem::ConstantIndex { .. } => {
399-
// ZSTs don't require any actual memory access.
400-
// FIXME(eddyb) deduplicate this with the identical
401-
// checks in `codegen_consume` and `extract_field`.
402-
let elem = o.layout.field(bx.cx(), 0);
403-
if elem.is_zst() {
404-
o = OperandRef::new_zst(bx, elem);
405-
} else {
406-
return None;
407-
}
387+
if let mir::PlaceBase::Local(index) = place_ref.base {
388+
match self.locals[*index] {
389+
LocalRef::Operand(Some(mut o)) => {
390+
// Moves out of scalar and scalar pair fields are trivial.
391+
for elem in place_ref.projection.iter() {
392+
match elem {
393+
mir::ProjectionElem::Field(ref f, _) => {
394+
o = o.extract_field(bx, f.index());
395+
}
396+
mir::ProjectionElem::Index(_) |
397+
mir::ProjectionElem::ConstantIndex { .. } => {
398+
// ZSTs don't require any actual memory access.
399+
// FIXME(eddyb) deduplicate this with the identical
400+
// checks in `codegen_consume` and `extract_field`.
401+
let elem = o.layout.field(bx.cx(), 0);
402+
if elem.is_zst() {
403+
o = OperandRef::new_zst(bx, elem);
404+
} else {
405+
return None;
408406
}
409-
_ => return None,
410407
}
408+
_ => return None,
411409
}
412-
413-
Some(o)
414-
}
415-
LocalRef::Operand(None) => {
416-
bug!("use of {:?} before def", place_ref);
417-
}
418-
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
419-
// watch out for locals that do not have an
420-
// alloca; they are handled somewhat differently
421-
None
422410
}
411+
412+
Some(o)
413+
}
414+
LocalRef::Operand(None) => {
415+
bug!("use of {:?} before def", place_ref);
416+
}
417+
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
418+
// watch out for locals that do not have an
419+
// alloca; they are handled somewhat differently
420+
None
423421
}
424-
} else {
425-
None
426422
}
427-
})
423+
} else {
424+
None
425+
}
428426
}
429427

430428
pub fn codegen_consume(

0 commit comments

Comments
 (0)