about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTyler Mandry <tmandry@gmail.com>2019-05-03 16:03:05 -0700
committerTyler Mandry <tmandry@gmail.com>2019-05-03 16:03:05 -0700
commit15dbe652ffa260fda162be3fa8e7aa075884c412 (patch)
tree290288e68dad20465fb2f3737d1368c31e458c6c /src
parentf7c2f2475a0adc2bf025a7a845fee61ff1468350 (diff)
downloadrust-15dbe652ffa260fda162be3fa8e7aa075884c412.tar.gz
rust-15dbe652ffa260fda162be3fa8e7aa075884c412.zip
Split out debuginfo from type info in MIR GeneratorLayout
Diffstat (limited to 'src')
-rw-r--r--src/librustc/mir/mod.rs34
-rw-r--r--src/librustc/ty/sty.rs11
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs5
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs8
-rw-r--r--src/librustc_mir/transform/generator.rs17
5 files changed, 59 insertions, 16 deletions
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index ca1c30def7a..9c71e694f4c 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -2994,10 +2994,29 @@ pub struct UnsafetyCheckResult {
     pub unsafe_blocks: Lrc<[(hir::HirId, bool)]>,
 }
 
+newtype_index! {
+    pub struct GeneratorField {
+        derive [HashStable]
+        DEBUG_FORMAT = "_{}",
+    }
+}
+
 /// The layout of generator state
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
 pub struct GeneratorLayout<'tcx> {
-    pub variant_fields: IndexVec<VariantIdx, IndexVec<Field, LocalDecl<'tcx>>>,
+    /// The type of every local stored inside the generator.
+    pub field_tys: IndexVec<GeneratorField, Ty<'tcx>>,
+
+    /// Which of the above fields are in each variant. Note that one field may
+    /// be stored in multiple variants.
+    pub variant_fields: IndexVec<VariantIdx, IndexVec<Field, GeneratorField>>,
+
+    /// Names and scopes of all the stored generator locals.
+    /// NOTE(tmandry) This is *strictly* a temporary hack for codegen
+    /// debuginfo generation, and will be removed at some point.
+    /// Do **NOT** use it for anything else, local information should not be
+    /// in the MIR, please rely on local crate HIR or other side-channels.
+    pub __local_debuginfo_codegen_only_do_not_use: IndexVec<GeneratorField, LocalDecl<'tcx>>,
 }
 
 #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)]
@@ -3186,7 +3205,9 @@ BraceStructTypeFoldableImpl! {
 
 BraceStructTypeFoldableImpl! {
     impl<'tcx> TypeFoldable<'tcx> for GeneratorLayout<'tcx> {
-        variant_fields
+        field_tys,
+        variant_fields,
+        __local_debuginfo_codegen_only_do_not_use,
     }
 }
 
@@ -3561,6 +3582,15 @@ impl<'tcx> TypeFoldable<'tcx> for Field {
     }
 }
 
+impl<'tcx> TypeFoldable<'tcx> for GeneratorField {
+    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _: &mut F) -> Self {
+        *self
+    }
+    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, _: &mut V) -> bool {
+        false
+    }
+}
+
 impl<'tcx> TypeFoldable<'tcx> for Constant<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         Constant {
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 331c54d1d46..a41209496bd 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -483,7 +483,7 @@ impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> {
     #[inline]
     pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> Range<VariantIdx> {
         // FIXME requires optimized MIR
-        let num_variants = self.state_tys(def_id, tcx).count();
+        let num_variants = tcx.generator_layout(def_id).variant_fields.len();
         (VariantIdx::new(0)..VariantIdx::new(num_variants))
     }
 
@@ -541,9 +541,12 @@ impl<'a, 'gcx, 'tcx> GeneratorSubsts<'tcx> {
     pub fn state_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
         impl Iterator<Item=impl Iterator<Item=Ty<'tcx>> + Captures<'gcx> + 'a>
     {
-        tcx.generator_layout(def_id)
-            .variant_fields.iter()
-            .map(move |v| v.iter().map(move |d| d.ty.subst(tcx, self.substs)))
+        let layout = tcx.generator_layout(def_id);
+        layout.variant_fields.iter().map(move |variant| {
+            variant.iter().map(move |field| {
+                layout.field_tys[*field].subst(tcx, self.substs)
+            })
+        })
     }
 
     /// This is the types of the fields of a generator which are not stored in a
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index b09fe827b24..5b18e821982 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -1597,8 +1597,9 @@ impl<'tcx> VariantInfo<'tcx> {
             VariantInfo::Adt(variant) if variant.ctor_kind != CtorKind::Fn =>
                 Some(variant.fields[i].ident.to_string()),
             VariantInfo::Generator(_, generator_layout, variant_index) => {
-                let variant_decls = &generator_layout.variant_fields[*variant_index];
-                variant_decls[i.into()].name.map(|name| name.to_string())
+                let field = generator_layout.variant_fields[*variant_index][i.into()];
+                let decl = &generator_layout.__local_debuginfo_codegen_only_do_not_use[field];
+                decl.name.map(|name| name.to_string())
             }
             _ => None,
         };
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index d524ec05462..fcf099235aa 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -663,12 +663,14 @@ fn arg_local_refs<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
                     generator_layout.variant_fields.iter()
                         .zip(state_tys)
                         .enumerate()
-                        .flat_map(move |(variant_idx, (decls, tys))| {
+                        .flat_map(move |(variant_idx, (fields, tys))| {
                             let variant_idx = Some(VariantIdx::from(variant_idx));
-                            decls.iter()
+                            fields.iter()
                                 .zip(tys)
                                 .enumerate()
-                                .filter_map(move |(i, (decl, ty))| {
+                                .filter_map(move |(i, (field, ty))| {
+                                    let decl = &generator_layout.
+                                        __local_debuginfo_codegen_only_do_not_use[*field];
                                     if let Some(name) = decl.name {
                                         let ty = fx.monomorphize(&ty);
                                         let (var_scope, var_span) = fx.debug_loc(mir::SourceInfo {
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index d9496c8c20a..77bf789d2dd 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -555,15 +555,22 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     // Create a map from local indices to generator struct indices.
     // We also create a vector of the LocalDecls of these locals.
-    let (remap, vars) = live_decls.enumerate().map(|(idx, (local, var))| {
-        ((local, (var.ty, variant_index, idx)), var)
-    }).unzip();
+    let mut remap = FxHashMap::default();
+    let mut decls = IndexVec::new();
+    for (idx, (local, var)) in live_decls.enumerate() {
+        remap.insert(local, (var.ty, variant_index, idx));
+        decls.push(var);
+    }
+    let field_tys = decls.iter().map(|field| field.ty).collect::<IndexVec<GeneratorField, _>>();
 
     // Put every var in each variant, for now.
+    let all_vars = (0..field_tys.len()).map(GeneratorField::from).collect();
     let empty_variants = iter::repeat(IndexVec::new()).take(3);
-    let state_variants = iter::repeat(vars).take(suspending_blocks.count());
+    let state_variants = iter::repeat(all_vars).take(suspending_blocks.count());
     let layout = GeneratorLayout {
-        variant_fields: empty_variants.chain(state_variants).collect()
+        field_tys,
+        variant_fields: empty_variants.chain(state_variants).collect(),
+        __local_debuginfo_codegen_only_do_not_use: decls,
     };
 
     (remap, layout, storage_liveness)