about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs4
-rw-r--r--compiler/rustc_middle/src/mir/query.rs11
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs6
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs13
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs4
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs4
-rw-r--r--tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir9
-rw-r--r--tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir9
8 files changed, 46 insertions, 14 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 3f83d40755a..fab92f6f6f3 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -372,12 +372,12 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                                 return;
                             };
 
-                            let Some(&f_ty) = layout.field_tys.get(local) else {
+                            let Some(f_ty) = layout.field_tys.get(local) else {
                                 self.fail(location, format!("Out of bounds local {:?} for {:?}", local, parent_ty));
                                 return;
                             };
 
-                            f_ty
+                            f_ty.ty
                         } else {
                             let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) else {
                                 fail_out_of_bounds(self, location);
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index a8a4532223c..ebeefa86277 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -135,11 +135,20 @@ rustc_index::newtype_index! {
     pub struct GeneratorSavedLocal {}
 }
 
+#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
+pub struct GeneratorSavedTy<'tcx> {
+    pub ty: Ty<'tcx>,
+    /// Source info corresponding to the local in the original MIR body.
+    pub source_info: SourceInfo,
+    /// Whether the local was introduced as a raw pointer to a static.
+    pub is_static_ptr: bool,
+}
+
 /// The layout of generator state.
 #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
 pub struct GeneratorLayout<'tcx> {
     /// The type of every local stored inside the generator.
-    pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
+    pub field_tys: IndexVec<GeneratorSavedLocal, GeneratorSavedTy<'tcx>>,
 
     /// Which of the above fields are in each variant. Note that one field may
     /// be stored in multiple variants.
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index eba65e34023..f97d2e753a3 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -571,9 +571,9 @@ impl<'tcx> GeneratorSubsts<'tcx> {
     ) -> impl Iterator<Item = impl Iterator<Item = Ty<'tcx>> + Captures<'tcx>> {
         let layout = tcx.generator_layout(def_id).unwrap();
         layout.variant_fields.iter().map(move |variant| {
-            variant
-                .iter()
-                .map(move |field| ty::EarlyBinder(layout.field_tys[*field]).subst(tcx, self.substs))
+            variant.iter().map(move |field| {
+                ty::EarlyBinder(layout.field_tys[*field].ty).subst(tcx, self.substs)
+            })
         })
     }
 
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 39c61a34afc..e94eaeaaa2b 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -916,7 +916,15 @@ fn compute_layout<'tcx>(
     let mut tys = IndexVec::<GeneratorSavedLocal, _>::new();
     for (saved_local, local) in saved_locals.iter_enumerated() {
         locals.push(local);
-        tys.push(body.local_decls[local].ty);
+        let decl = &body.local_decls[local];
+        let decl = GeneratorSavedTy {
+            ty: decl.ty,
+            source_info: decl.source_info,
+            is_static_ptr: decl.internal
+                && decl.ty.is_unsafe_ptr()
+                && matches!(decl.local_info.as_deref(), Some(LocalInfo::StaticRef { .. })),
+        };
+        tys.push(decl);
         debug!("generator saved local {:?} => {:?}", saved_local, local);
     }
 
@@ -947,7 +955,7 @@ fn compute_layout<'tcx>(
             // just use the first one here. That's fine; fields do not move
             // around inside generators, so it doesn't matter which variant
             // index we access them by.
-            remap.entry(locals[saved_local]).or_insert((tys[saved_local], variant_index, idx));
+            remap.entry(locals[saved_local]).or_insert((tys[saved_local].ty, variant_index, idx));
         }
         variant_fields.push(fields);
         variant_source_info.push(source_info_at_suspension_points[suspension_point_idx]);
@@ -957,6 +965,7 @@ fn compute_layout<'tcx>(
 
     let layout =
         GeneratorLayout { field_tys: tys, variant_fields, variant_source_info, storage_conflicts };
+    debug!(?layout);
 
     (remap, layout, storage_liveness)
 }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 69627fc5cb2..84640b703c8 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -947,12 +947,12 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
                             return;
                         };
 
-                        let Some(&f_ty) = layout.field_tys.get(local) else {
+                        let Some(f_ty) = layout.field_tys.get(local) else {
                             self.validation = Err("malformed MIR");
                             return;
                         };
 
-                        f_ty
+                        f_ty.ty
                     } else {
                         let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) else {
                             self.validation = Err("malformed MIR");
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 44c8569baa9..378cd5a99ed 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -643,7 +643,7 @@ fn generator_layout<'tcx>(
 
     let promoted_layouts = ineligible_locals
         .iter()
-        .map(|local| subst_field(info.field_tys[local]))
+        .map(|local| subst_field(info.field_tys[local].ty))
         .map(|ty| tcx.mk_maybe_uninit(ty))
         .map(|ty| cx.layout_of(ty));
     let prefix_layouts = substs
@@ -713,7 +713,7 @@ fn generator_layout<'tcx>(
                     Assigned(_) => bug!("assignment does not match variant"),
                     Ineligible(_) => false,
                 })
-                .map(|local| subst_field(info.field_tys[*local]));
+                .map(|local| subst_field(info.field_tys[*local].ty));
 
             let mut variant = univariant_uninterned(
                 cx,
diff --git a/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
index a8e090020c3..862dfc90062 100644
--- a/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
+++ b/tests/mir-opt/generator_drop_cleanup.main-{closure#0}.generator_drop.0.mir
@@ -1,7 +1,14 @@
 // MIR for `main::{closure#0}` 0 generator_drop
 /* generator_layout = GeneratorLayout {
     field_tys: {
-        _0: std::string::String,
+        _0: GeneratorSavedTy {
+            ty: std::string::String,
+            source_info: SourceInfo {
+                span: $DIR/generator_drop_cleanup.rs:11:13: 11:15 (#0),
+                scope: scope[0],
+            },
+            is_static_ptr: false,
+        },
     },
     variant_fields: {
         Unresumed(0): [],
diff --git a/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir b/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
index b3d3c768a5d..0d262f75c1a 100644
--- a/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
+++ b/tests/mir-opt/generator_tiny.main-{closure#0}.generator_resume.0.mir
@@ -1,7 +1,14 @@
 // MIR for `main::{closure#0}` 0 generator_resume
 /* generator_layout = GeneratorLayout {
     field_tys: {
-        _0: HasDrop,
+        _0: GeneratorSavedTy {
+            ty: HasDrop,
+            source_info: SourceInfo {
+                span: $DIR/generator_tiny.rs:20:13: 20:15 (#0),
+                scope: scope[0],
+            },
+            is_static_ptr: false,
+        },
     },
     variant_fields: {
         Unresumed(0): [],