about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/transform
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-07-07 15:08:27 +0000
committerbors <bors@rust-lang.org>2022-07-07 15:08:27 +0000
commit3e51277fe638dc0c8ceb6d1d3acc5aa247277c29 (patch)
tree154863a8b942fdd94d5122362deeea3f47d75a00 /compiler/rustc_const_eval/src/transform
parent20dd6930134d07a5ef90393a040a1594ac8d714c (diff)
parent6910d84bc4be42806bcc975d4089409f53438416 (diff)
downloadrust-3e51277fe638dc0c8ceb6d1d3acc5aa247277c29.tar.gz
rust-3e51277fe638dc0c8ceb6d1d3acc5aa247277c29.zip
Auto merge of #99014 - Dylan-DPC:rollup-n84y0jk, r=Dylan-DPC
Rollup of 8 pull requests

Successful merges:

 - #96856 (Fix ProjectionElem validation)
 - #97711 (Improve soundness of rustc_arena)
 - #98507 (Finishing touches for `#[expect]` (RFC 2383))
 - #98692 (rustdoc: Cleanup more FIXMEs)
 - #98901 (incr: cache dwarf objects in work products)
 - #98930 (Make MIR basic blocks field public)
 - #98973 (Remove (unused) inherent impl anchors)
 - #98981 ( Edit `rustc_mir_dataflow::framework` documentation )

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_const_eval/src/transform')
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs5
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs49
2 files changed, 46 insertions, 8 deletions
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index 6298fa7f062..12527a9b2ae 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -856,7 +856,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                     literal: ConstantKind::from_const(_const, tcx),
                 }))
             };
-            let (blocks, local_decls) = self.source.basic_blocks_and_local_decls_mut();
+            let blocks = self.source.basic_blocks.as_mut();
+            let local_decls = &mut self.source.local_decls;
             let loc = candidate.location;
             let statement = &mut blocks[loc.block].statements[loc.statement_index];
             match statement.kind {
@@ -865,7 +866,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                     Rvalue::Ref(ref mut region, borrow_kind, ref mut place),
                 )) => {
                     // Use the underlying local for this (necessarily interior) borrow.
-                    let ty = local_decls.local_decls()[place.local].ty;
+                    let ty = local_decls[place.local].ty;
                     let span = statement.source_info.span;
 
                     let ref_ty = tcx.mk_ref(
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 7b9c6329d32..56ecc553528 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -12,6 +12,7 @@ use rustc_middle::mir::{
     Statement, StatementKind, Terminator, TerminatorKind, UnOp, START_BLOCK,
 };
 use rustc_middle::ty::fold::BottomUpFolder;
+use rustc_middle::ty::subst::Subst;
 use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeFoldable, TypeVisitable};
 use rustc_mir_dataflow::impls::MaybeStorageLive;
 use rustc_mir_dataflow::storage::always_live_locals;
@@ -275,7 +276,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     }
                 };
 
-                match parent_ty.ty.kind() {
+                let kind = match parent_ty.ty.kind() {
+                    &ty::Opaque(def_id, substs) => {
+                        self.tcx.bound_type_of(def_id).subst(self.tcx, substs).kind()
+                    }
+                    kind => kind,
+                };
+
+                match kind {
                     ty::Tuple(fields) => {
                         let Some(f_ty) = fields.get(f.as_usize()) else {
                             fail_out_of_bounds(self, location);
@@ -299,12 +307,39 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         };
                         check_equal(self, location, f_ty);
                     }
-                    ty::Generator(_, substs, _) => {
-                        let substs = substs.as_generator();
-                        let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
-                            fail_out_of_bounds(self, location);
-                            return;
+                    &ty::Generator(def_id, substs, _) => {
+                        let f_ty = if let Some(var) = parent_ty.variant_index {
+                            let gen_body = if def_id == self.body.source.def_id() {
+                                self.body
+                            } else {
+                                self.tcx.optimized_mir(def_id)
+                            };
+
+                            let Some(layout) = gen_body.generator_layout() else {
+                                self.fail(location, format!("No generator layout for {:?}", parent_ty));
+                                return;
+                            };
+
+                            let Some(&local) = layout.variant_fields[var].get(f) else {
+                                fail_out_of_bounds(self, location);
+                                return;
+                            };
+
+                            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
+                        } else {
+                            let Some(f_ty) = substs.as_generator().prefix_tys().nth(f.index()) else {
+                                fail_out_of_bounds(self, location);
+                                return;
+                            };
+
+                            f_ty
                         };
+
                         check_equal(self, location, f_ty);
                     }
                     _ => {
@@ -328,6 +363,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
         {
             self.fail(location, format!("{:?}, has deref at the wrong place", place));
         }
+
+        self.super_place(place, cntxt, location);
     }
 
     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {