Skip to content

Commit e2387ad

Browse files
committed
Remember where a type was kept in MIR.
1 parent 1974b6b commit e2387ad

File tree

8 files changed

+46
-14
lines changed

8 files changed

+46
-14
lines changed

compiler/rustc_const_eval/src/transform/validate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,12 +372,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
372372
return;
373373
};
374374

375-
let Some(&f_ty) = layout.field_tys.get(local) else {
375+
let Some(f_ty) = layout.field_tys.get(local) else {
376376
self.fail(location, format!("Out of bounds local {:?} for {:?}", local, parent_ty));
377377
return;
378378
};
379379

380-
f_ty
380+
f_ty.ty
381381
} else {
382382
let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) else {
383383
fail_out_of_bounds(self, location);

compiler/rustc_middle/src/mir/query.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,20 @@ rustc_index::newtype_index! {
135135
pub struct GeneratorSavedLocal {}
136136
}
137137

138+
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
139+
pub struct GeneratorSavedTy<'tcx> {
140+
pub ty: Ty<'tcx>,
141+
/// Source info corresponding to the local in the original MIR body.
142+
pub source_info: SourceInfo,
143+
/// Whether the local was introduced as a raw pointer to a static.
144+
pub is_static_ptr: bool,
145+
}
146+
138147
/// The layout of generator state.
139148
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
140149
pub struct GeneratorLayout<'tcx> {
141150
/// The type of every local stored inside the generator.
142-
pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
151+
pub field_tys: IndexVec<GeneratorSavedLocal, GeneratorSavedTy<'tcx>>,
143152

144153
/// Which of the above fields are in each variant. Note that one field may
145154
/// be stored in multiple variants.

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -571,9 +571,9 @@ impl<'tcx> GeneratorSubsts<'tcx> {
571571
) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
572572
let layout = tcx.generator_layout(def_id).unwrap();
573573
layout.variant_fields.iter().map(move |variant| {
574-
variant
575-
.iter()
576-
.map(move |field| ty::EarlyBinder(layout.field_tys[*field]).subst(tcx, self.substs))
574+
variant.iter().map(move |field| {
575+
ty::EarlyBinder(layout.field_tys[*field].ty).subst(tcx, self.substs)
576+
})
577577
})
578578
}
579579

compiler/rustc_mir_transform/src/generator.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,15 @@ fn compute_layout<'tcx>(
916916
let mut tys = IndexVec::<GeneratorSavedLocal, _>::new();
917917
for (saved_local, local) in saved_locals.iter_enumerated() {
918918
locals.push(local);
919-
tys.push(body.local_decls[local].ty);
919+
let decl = &body.local_decls[local];
920+
let decl = GeneratorSavedTy {
921+
ty: decl.ty,
922+
source_info: decl.source_info,
923+
is_static_ptr: decl.internal
924+
&& decl.ty.is_unsafe_ptr()
925+
&& matches!(decl.local_info.as_deref(), Some(LocalInfo::StaticRef { .. })),
926+
};
927+
tys.push(decl);
920928
debug!("generator saved local {:?} => {:?}", saved_local, local);
921929
}
922930

@@ -947,7 +955,7 @@ fn compute_layout<'tcx>(
947955
// just use the first one here. That's fine; fields do not move
948956
// around inside generators, so it doesn't matter which variant
949957
// index we access them by.
950-
remap.entry(locals[saved_local]).or_insert((tys[saved_local], variant_index, idx));
958+
remap.entry(locals[saved_local]).or_insert((tys[saved_local].ty, variant_index, idx));
951959
}
952960
variant_fields.push(fields);
953961
variant_source_info.push(source_info_at_suspension_points[suspension_point_idx]);
@@ -957,6 +965,7 @@ fn compute_layout<'tcx>(
957965

958966
let layout =
959967
GeneratorLayout { field_tys: tys, variant_fields, variant_source_info, storage_conflicts };
968+
debug!(?layout);
960969

961970
(remap, layout, storage_liveness)
962971
}

compiler/rustc_mir_transform/src/inline.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -947,12 +947,12 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
947947
return;
948948
};
949949

950-
let Some(&f_ty) = layout.field_tys.get(local) else {
950+
let Some(f_ty) = layout.field_tys.get(local) else {
951951
self.validation = Err("malformed MIR");
952952
return;
953953
};
954954

955-
f_ty
955+
f_ty.ty
956956
} else {
957957
let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) else {
958958
self.validation = Err("malformed MIR");

compiler/rustc_ty_utils/src/layout.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ fn generator_layout<'tcx>(
643643

644644
let promoted_layouts = ineligible_locals
645645
.iter()
646-
.map(|local| subst_field(info.field_tys[local]))
646+
.map(|local| subst_field(info.field_tys[local].ty))
647647
.map(|ty| tcx.mk_maybe_uninit(ty))
648648
.map(|ty| cx.layout_of(ty));
649649
let prefix_layouts = substs
@@ -713,7 +713,7 @@ fn generator_layout<'tcx>(
713713
Assigned(_) => bug!("assignment does not match variant"),
714714
Ineligible(_) => false,
715715
})
716-
.map(|local| subst_field(info.field_tys[*local]));
716+
.map(|local| subst_field(info.field_tys[*local].ty));
717717

718718
let mut variant = univariant_uninterned(
719719
cx,

tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
// MIR for `main::{closure#0}` 0 generator_drop
22
/* generator_layout = GeneratorLayout {
33
field_tys: {
4-
_0: std::string::String,
4+
_0: GeneratorSavedTy {
5+
ty: std::string::String,
6+
source_info: SourceInfo {
7+
span: $DIR/generator_drop_cleanup.rs:11:13: 11:15 (#0),
8+
scope: scope[0],
9+
},
10+
is_static_ptr: false,
11+
},
512
},
613
variant_fields: {
714
Unresumed(0): [],

tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
// MIR for `main::{closure#0}` 0 generator_resume
22
/* generator_layout = GeneratorLayout {
33
field_tys: {
4-
_0: HasDrop,
4+
_0: GeneratorSavedTy {
5+
ty: HasDrop,
6+
source_info: SourceInfo {
7+
span: $DIR/generator_tiny.rs:20:13: 20:15 (#0),
8+
scope: scope[0],
9+
},
10+
is_static_ptr: false,
11+
},
512
},
613
variant_fields: {
714
Unresumed(0): [],

0 commit comments

Comments
 (0)