Skip to content

Commit 15dbe65

Browse files
committed
Split out debuginfo from type info in MIR GeneratorLayout
1 parent f7c2f24 commit 15dbe65

File tree

5 files changed

+59
-16
lines changed

5 files changed

+59
-16
lines changed

src/librustc/mir/mod.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -2994,10 +2994,29 @@ pub struct UnsafetyCheckResult {
29942994
pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>,
29952995
}
29962996

2997+
newtype_index! {
2998+
pub struct GeneratorField {
2999+
derive [HashStable]
3000+
DEBUG_FORMAT = "_{}",
3001+
}
3002+
}
3003+
29973004
/// The layout of generator state
29983005
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
29993006
pub struct GeneratorLayout<'tcx> {
3000-
pub variant_fields: IndexVec<VariantIdx, IndexVec<Field, LocalDecl<'tcx>>>,
3007+
/// The type of every local stored inside the generator.
3008+
pub field_tys: IndexVec<GeneratorField, Ty<'tcx>>,
3009+
3010+
/// Which of the above fields are in each variant. Note that one field may
3011+
/// be stored in multiple variants.
3012+
pub variant_fields: IndexVec<VariantIdx, IndexVec<Field, GeneratorField>>,
3013+
3014+
/// Names and scopes of all the stored generator locals.
3015+
/// NOTE(tmandry) This is *strictly* a temporary hack for codegen
3016+
/// debuginfo generation, and will be removed at some point.
3017+
/// Do **NOT** use it for anything else, local information should not be
3018+
/// in the MIR, please rely on local crate HIR or other side-channels.
3019+
pub __local_debuginfo_codegen_only_do_not_use: IndexVec<GeneratorField, LocalDecl<'tcx>>,
30013020
}
30023021

30033022
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
@@ -3186,7 +3205,9 @@ BraceStructTypeFoldableImpl! {
31863205

31873206
BraceStructTypeFoldableImpl! {
31883207
impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> {
3189-
variant_fields
3208+
field_tys,
3209+
variant_fields,
3210+
__local_debuginfo_codegen_only_do_not_use,
31903211
}
31913212
}
31923213

@@ -3561,6 +3582,15 @@ impl<'tcx> TypeFoldable<'tcx> for Field {
35613582
}
35623583
}
35633584

3585+
impl<'tcx> TypeFoldable<'tcx> for GeneratorField {
3586+
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> Self {
3587+
*self
3588+
}
3589+
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
3590+
false
3591+
}
3592+
}
3593+
35643594
impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
35653595
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
35663596
Constant {

src/librustc/ty/sty.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> {
483483
#[inline]
484484
pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Range<VariantIdx> {
485485
// FIXME requires optimized MIR
486-
let num_variants = self.state_tys(def_id, tcx).count();
486+
let num_variants = tcx.generator_layout(def_id).variant_fields.len();
487487
(VariantIdx::new(0)..VariantIdx::new(num_variants))
488488
}
489489

@@ -541,9 +541,12 @@ impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> {
541541
pub fn state_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
542542
impl Iterator<Item=impl Iterator<Item=Ty<'tcx>> + Captures<'gcx> + 'a>
543543
{
544-
tcx.generator_layout(def_id)
545-
.variant_fields.iter()
546-
.map(move |v| v.iter().map(move |d| d.ty.subst(tcx, self.substs)))
544+
let layout = tcx.generator_layout(def_id);
545+
layout.variant_fields.iter().map(move |variant| {
546+
variant.iter().map(move |field| {
547+
layout.field_tys[*field].subst(tcx, self.substs)
548+
})
549+
})
547550
}
548551

549552
/// This is the types of the fields of a generator which are not stored in a

src/librustc_codegen_llvm/debuginfo/metadata.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1597,8 +1597,9 @@ impl<'tcx> VariantInfo<'tcx> {
15971597
VariantInfo::Adt(variant) if variant.ctor_kind != CtorKind::Fn =>
15981598
Some(variant.fields[i].ident.to_string()),
15991599
VariantInfo::Generator(_, generator_layout, variant_index) => {
1600-
let variant_decls = &generator_layout.variant_fields[*variant_index];
1601-
variant_decls[i.into()].name.map(|name| name.to_string())
1600+
let field = generator_layout.variant_fields[*variant_index][i.into()];
1601+
let decl = &generator_layout.__local_debuginfo_codegen_only_do_not_use[field];
1602+
decl.name.map(|name| name.to_string())
16021603
}
16031604
_ => None,
16041605
};

src/librustc_codegen_ssa/mir/mod.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -663,12 +663,14 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
663663
generator_layout.variant_fields.iter()
664664
.zip(state_tys)
665665
.enumerate()
666-
.flat_map(move |(variant_idx, (decls, tys))| {
666+
.flat_map(move |(variant_idx, (fields, tys))| {
667667
let variant_idx = Some(VariantIdx::from(variant_idx));
668-
decls.iter()
668+
fields.iter()
669669
.zip(tys)
670670
.enumerate()
671-
.filter_map(move |(i, (decl, ty))| {
671+
.filter_map(move |(i, (field, ty))| {
672+
let decl = &generator_layout.
673+
__local_debuginfo_codegen_only_do_not_use[*field];
672674
if let Some(name) = decl.name {
673675
let ty = fx.monomorphize(&ty);
674676
let (var_scope, var_span) = fx.debug_loc(mir::SourceInfo {

src/librustc_mir/transform/generator.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -555,15 +555,22 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
555555

556556
// Create a map from local indices to generator struct indices.
557557
// We also create a vector of the LocalDecls of these locals.
558-
let (remap, vars) = live_decls.enumerate().map(|(idx, (local, var))| {
559-
((local, (var.ty, variant_index, idx)), var)
560-
}).unzip();
558+
let mut remap = FxHashMap::default();
559+
let mut decls = IndexVec::new();
560+
for (idx, (local, var)) in live_decls.enumerate() {
561+
remap.insert(local, (var.ty, variant_index, idx));
562+
decls.push(var);
563+
}
564+
let field_tys = decls.iter().map(|field| field.ty).collect::<IndexVec<GeneratorField, _>>();
561565

562566
// Put every var in each variant, for now.
567+
let all_vars = (0..field_tys.len()).map(GeneratorField::from).collect();
563568
let empty_variants = iter::repeat(IndexVec::new()).take(3);
564-
let state_variants = iter::repeat(vars).take(suspending_blocks.count());
569+
let state_variants = iter::repeat(all_vars).take(suspending_blocks.count());
565570
let layout = GeneratorLayout {
566-
variant_fields: empty_variants.chain(state_variants).collect()
571+
field_tys,
572+
variant_fields: empty_variants.chain(state_variants).collect(),
573+
__local_debuginfo_codegen_only_do_not_use: decls,
567574
};
568575

569576
(remap, layout, storage_liveness)

0 commit comments

Comments
 (0)