Skip to content

Commit ff41359

Browse files
committed
address review
1 parent dc93a28 commit ff41359

File tree

4 files changed

+60
-91
lines changed

4 files changed

+60
-91
lines changed

compiler/rustc_middle/src/mir/syntax.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,13 @@ pub struct Place<'tcx> {
875875
pub projection: &'tcx List<PlaceElem<'tcx>>,
876876
}
877877

878+
/// The different kinds of projections that can be used in the projection of a `Place`.
879+
///
880+
/// `T1` is the generic type for a field projection. For an actual projection on a `Place`
881+
/// this parameter will always be `Ty`, but the field type can be unavailable when
882+
/// building (by using `PlaceBuilder`) places that correspond to upvars.
883+
/// `T2` is the generic type for an `OpaqueCast` (is generic since it's abstracted over
884+
/// in dataflow analysis, see `AbstractElem`).
878885
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
879886
#[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
880887
pub enum ProjectionElem<V, T1, T2> {
@@ -942,7 +949,7 @@ pub enum ProjectionElem<V, T1, T2> {
942949
/// and the index is a local.
943950
pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>, Ty<'tcx>>;
944951

945-
/// Alias for projections that appear in `PlaceBuilder::UpVar`, for which
952+
/// Alias for projections that appear in `PlaceBuilder::Upvar`, for which
946953
/// we cannot provide any field types.
947954
pub type UpvarProjectionElem<'tcx> = ProjectionElem<Local, (), Ty<'tcx>>;
948955

compiler/rustc_mir_build/src/build/expr/as_place.rs

+48-85
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub(in crate::build) enum PlaceBuilder<'tcx> {
3333
/// Denotes the start of a `Place`.
3434
///
3535
/// We use `PlaceElem` since this has all `Field` types available.
36-
Local(Local, Vec<PlaceElem<'tcx>>),
36+
Local { local: Local, projection: Vec<PlaceElem<'tcx>> },
3737

3838
/// When building place for an expression within a closure, the place might start off a
3939
/// captured path. When `capture_disjoint_fields` is enabled, we might not know the capture
@@ -67,11 +67,11 @@ pub(in crate::build) enum PlaceBuilder<'tcx> {
6767
///
6868
/// Note: in contrast to `PlaceBuilder::Local` we have not yet determined all `Field` types
6969
/// and will only do so once converting to `PlaceBuilder::Local`.
70-
UpVar(UpVar, Vec<UpvarProjectionElem<'tcx>>),
70+
Upvar { upvar: Upvar, projection: Vec<UpvarProjectionElem<'tcx>> },
7171
}
7272

7373
#[derive(Copy, Clone, Debug, PartialEq)]
74-
pub(crate) struct UpVar {
74+
pub(crate) struct Upvar {
7575
var_hir_id: LocalVarId,
7676
closure_def_id: LocalDefId,
7777
}
@@ -222,36 +222,7 @@ fn to_upvars_resolved_place_builder<'tcx>(
222222
upvar_projection,
223223
);
224224

225-
debug_assert!({
226-
let builder = upvar_resolved_place_builder.clone();
227-
let mut valid_conversion = true;
228-
match builder {
229-
PlaceBuilder::Local(_, projections) => {
230-
for proj in projections.iter() {
231-
match proj {
232-
ProjectionElem::Field(_, field_ty) => {
233-
if matches!(field_ty.kind(), ty::Infer(..)) {
234-
debug!(
235-
"field ty should have been converted for projection {:?} in PlaceBuilder {:?}",
236-
proj,
237-
upvar_resolved_place_builder.clone()
238-
);
239-
240-
valid_conversion = false;
241-
break;
242-
}
243-
}
244-
_ => {}
245-
}
246-
}
247-
}
248-
PlaceBuilder::UpVar(..) => {
249-
unreachable!()
250-
}
251-
}
252-
253-
valid_conversion
254-
});
225+
assert!(matches!(upvar_resolved_place_builder, PlaceBuilder::Local { .. }));
255226

256227
Some(upvar_resolved_place_builder)
257228
}
@@ -269,9 +240,9 @@ fn strip_prefix<'a, 'tcx>(
269240
) -> impl Iterator<Item = UpvarProjectionElem<'tcx>> + 'a {
270241
let mut iter = projections
271242
.iter()
243+
.copied()
272244
// Filter out opaque casts, they are unnecessary in the prefix.
273-
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..)))
274-
.map(|elem| *elem);
245+
.filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(..)));
275246
for projection in prefix_projections {
276247
debug!(?projection, ?projection.ty);
277248

@@ -305,8 +276,8 @@ impl<'tcx> PlaceBuilder<'tcx> {
305276
pub(in crate::build) fn try_to_place(&self, cx: &Builder<'_, 'tcx>) -> Option<Place<'tcx>> {
306277
let resolved = self.resolve_upvar(cx);
307278
let builder = resolved.as_ref().unwrap_or(self);
308-
let PlaceBuilder::Local(local, projection) = builder else { return None };
309-
let projection = cx.tcx.intern_place_elems(&projection);
279+
let PlaceBuilder::Local{local, ref projection} = builder else { return None };
280+
let projection = cx.tcx.intern_place_elems(projection);
310281
Some(Place { local: *local, projection })
311282
}
312283

@@ -324,40 +295,31 @@ impl<'tcx> PlaceBuilder<'tcx> {
324295
&self,
325296
cx: &Builder<'_, 'tcx>,
326297
) -> Option<PlaceBuilder<'tcx>> {
327-
let PlaceBuilder::UpVar( UpVar {var_hir_id, closure_def_id }, projection) = self else {
298+
let PlaceBuilder::Upvar{ upvar: Upvar {var_hir_id, closure_def_id }, projection} = self else {
328299
return None;
329300
};
330301

331302
to_upvars_resolved_place_builder(cx, *var_hir_id, *closure_def_id, &projection)
332303
}
333304

334-
pub(crate) fn get_local_projection(&self) -> &[PlaceElem<'tcx>] {
335-
match self {
336-
Self::Local(_, projection) => projection,
337-
Self::UpVar(..) => {
338-
bug!("get_local_projection_mut can only be called on PlaceBuilder::Local")
339-
}
340-
}
341-
}
342-
343305
#[instrument(skip(cx), level = "debug")]
344306
pub(crate) fn field(self, cx: &Builder<'_, 'tcx>, f: Field) -> Self {
345-
let field_ty = match self.clone() {
346-
PlaceBuilder::Local(local, projection) => {
347-
let base_place = PlaceBuilder::Local(local, projection);
307+
match self.clone() {
308+
PlaceBuilder::Local { local, projection } => {
309+
let base_place = PlaceBuilder::Local { local, projection };
348310
let PlaceTy { ty, variant_index } =
349311
base_place.to_place(cx).ty(&cx.local_decls, cx.tcx);
350312
let base_ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
351313

352-
PlaceBuilder::compute_field_ty(cx, f, base_ty, variant_index)
314+
let field_ty = PlaceBuilder::compute_field_ty(cx, f, base_ty, variant_index);
315+
316+
self.project(ProjectionElem::Field(f, field_ty))
353317
}
354-
PlaceBuilder::UpVar(..) => {
355-
let dummy_ty = cx.tcx.mk_ty_infer(ty::FreshTy(0));
356-
dummy_ty
318+
PlaceBuilder::Upvar { upvar, mut projection } => {
319+
projection.push(ProjectionElem::Field(f, ()));
320+
PlaceBuilder::Upvar { upvar, projection }
357321
}
358-
};
359-
360-
self.project(ProjectionElem::Field(f, field_ty))
322+
}
361323
}
362324

363325
pub(crate) fn deref(self) -> Self {
@@ -375,13 +337,13 @@ impl<'tcx> PlaceBuilder<'tcx> {
375337
#[instrument(level = "debug")]
376338
pub(crate) fn project(self, elem: PlaceElem<'tcx>) -> Self {
377339
let result = match self {
378-
PlaceBuilder::Local(local, mut proj) => {
379-
proj.push(elem);
380-
PlaceBuilder::Local(local, proj)
340+
PlaceBuilder::Local { local, mut projection } => {
341+
projection.push(elem);
342+
PlaceBuilder::Local { local, projection }
381343
}
382-
PlaceBuilder::UpVar(upvar, mut proj) => {
383-
proj.push(elem.into());
384-
PlaceBuilder::UpVar(upvar, proj)
344+
PlaceBuilder::Upvar { upvar, mut projection } => {
345+
projection.push(elem.into());
346+
PlaceBuilder::Upvar { upvar, projection }
385347
}
386348
};
387349

@@ -392,14 +354,14 @@ impl<'tcx> PlaceBuilder<'tcx> {
392354
/// Same as `.clone().project(..)` but more efficient
393355
pub(crate) fn clone_project(&self, elem: PlaceElem<'tcx>) -> Self {
394356
match self {
395-
PlaceBuilder::Local(local, proj) => PlaceBuilder::Local(
396-
*local,
397-
Vec::from_iter(proj.iter().copied().chain([elem.into()])),
398-
),
399-
PlaceBuilder::UpVar(upvar, proj) => PlaceBuilder::UpVar(
400-
*upvar,
401-
Vec::from_iter(proj.iter().copied().chain([elem.into()])),
402-
),
357+
PlaceBuilder::Local { local, projection } => PlaceBuilder::Local {
358+
local: *local,
359+
projection: Vec::from_iter(projection.iter().copied().chain([elem.into()])),
360+
},
361+
PlaceBuilder::Upvar { upvar, projection } => PlaceBuilder::Upvar {
362+
upvar: *upvar,
363+
projection: Vec::from_iter(projection.iter().copied().chain([elem.into()])),
364+
},
403365
}
404366
}
405367

@@ -463,7 +425,11 @@ impl<'tcx> PlaceBuilder<'tcx> {
463425
f_ty
464426
} else {
465427
let Some(f_ty) = substs.as_generator().prefix_tys().nth(field.index()) else {
466-
bug!("expected to take index {:?} in {:?}", field.index(), substs.as_generator().prefix_tys().collect::<Vec<_>>());
428+
bug!(
429+
"expected to take index {:?} in {:?}",
430+
field.index(),
431+
substs.as_generator().prefix_tys().collect::<Vec<_>>()
432+
);
467433
};
468434

469435
f_ty
@@ -475,7 +441,7 @@ impl<'tcx> PlaceBuilder<'tcx> {
475441
cx.tcx.normalize_erasing_regions(cx.param_env, field_ty)
476442
}
477443

478-
/// Creates a `PlaceBuilder::Local` from a `PlaceBuilder::UpVar` whose upvars
444+
/// Creates a `PlaceBuilder::Local` from a `PlaceBuilder::Upvar` whose upvars
479445
/// are resolved. This function takes two kinds of projections: `local_projection`
480446
/// contains the projections of the captured upvar and `upvar_projection` the
481447
/// projections that are applied to the captured upvar. The main purpose of this
@@ -516,19 +482,19 @@ impl<'tcx> PlaceBuilder<'tcx> {
516482
}
517483
}
518484

519-
PlaceBuilder::Local(local, local_projection)
485+
PlaceBuilder::Local { local, projection: local_projection }
520486
}
521487
}
522488

523489
impl<'tcx> From<Local> for PlaceBuilder<'tcx> {
524490
fn from(local: Local) -> Self {
525-
Self::Local(local, Vec::new())
491+
Self::Local { local, projection: Vec::new() }
526492
}
527493
}
528494

529495
impl<'tcx> From<Place<'tcx>> for PlaceBuilder<'tcx> {
530496
fn from(p: Place<'tcx>) -> Self {
531-
Self::Local(p.local, p.projection.to_vec())
497+
Self::Local { local: p.local, projection: p.projection.to_vec() }
532498
}
533499
}
534500

@@ -564,13 +530,7 @@ fn project_ty<'tcx>(
564530
(ty, None)
565531
}
566532
ProjectionElem::Downcast(_, variant_idx) => (ty, Some(variant_idx)),
567-
ProjectionElem::Field(_, ty) => {
568-
if matches!(ty.kind(), ty::Infer(..)) {
569-
bug!("Field ty should have been resolved");
570-
}
571-
572-
(ty, None)
573-
}
533+
ProjectionElem::Field(_, ty) => (ty, None),
574534
ProjectionElem::OpaqueCast(..) => bug!("didn't expect OpaqueCast"),
575535
}
576536
}
@@ -836,15 +796,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
836796
}
837797

838798
/// Lower a captured upvar. Note we might not know the actual capture index,
839-
/// so we create a place starting from `UpVar`, which will be resolved
799+
/// so we create a place starting from `Upvar`, which will be resolved
840800
/// once all projections that allow us to identify a capture have been applied.
841801
fn lower_captured_upvar(
842802
&mut self,
843803
block: BasicBlock,
844804
closure_def_id: LocalDefId,
845805
var_hir_id: LocalVarId,
846806
) -> BlockAnd<PlaceBuilder<'tcx>> {
847-
block.and(PlaceBuilder::UpVar(UpVar { var_hir_id, closure_def_id }, vec![]))
807+
block.and(PlaceBuilder::Upvar {
808+
upvar: Upvar { var_hir_id, closure_def_id },
809+
projection: vec![],
810+
})
848811
}
849812

850813
/// Lower an index expression

compiler/rustc_mir_build/src/build/expr/as_rvalue.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -654,11 +654,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
654654
// We are capturing a path that starts off a local variable in the parent.
655655
// The mutability of the current capture is same as the mutability
656656
// of the local declaration in the parent.
657-
PlaceBuilder::Local(local, _) => this.local_decls[local].mutability,
657+
PlaceBuilder::Local { local, .. } => this.local_decls[local].mutability,
658658
// Parent is a closure and we are capturing a path that is captured
659659
// by the parent itself. The mutability of the current capture
660660
// is same as that of the capture in the parent closure.
661-
PlaceBuilder::UpVar(..) => {
661+
PlaceBuilder::Upvar { .. } => {
662662
let enclosing_upvars_resolved = arg_place_builder.to_place(this);
663663

664664
match enclosing_upvars_resolved.as_ref() {

compiler/rustc_mir_build/src/build/matches/util.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,8 @@ impl<'pat, 'tcx> MatchPair<'pat, 'tcx> {
108108
// Only add the OpaqueCast projection if the given place is an opaque type and the
109109
// expected type from the pattern is not.
110110
let may_need_cast = match place {
111-
PlaceBuilder::Local(local, _) => {
112-
let ty =
113-
Place::ty_from(local, place.get_local_projection(), &cx.local_decls, cx.tcx).ty;
111+
PlaceBuilder::Local { local, ref projection } => {
112+
let ty = Place::ty_from(local, projection, &cx.local_decls, cx.tcx).ty;
114113
ty != pattern.ty && ty.has_opaque_types()
115114
}
116115
_ => true,

0 commit comments

Comments
 (0)