about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src
diff options
context:
space:
mode:
authorDrMeepster <19316085+DrMeepster@users.noreply.github.com>2022-05-13 21:53:03 -0700
committerDrMeepster <19316085+DrMeepster@users.noreply.github.com>2022-06-15 18:38:26 -0700
commitcb417881a9341e3258a3b1fa4a14c0717e226d61 (patch)
tree11a4d98ee39821864826411ccf9a90b3c92d4753 /compiler/rustc_const_eval/src
parent3e9d3d917a988973d9c657a257029a9bd850f6dc (diff)
downloadrust-cb417881a9341e3258a3b1fa4a14c0717e226d61.tar.gz
rust-cb417881a9341e3258a3b1fa4a14c0717e226d61.zip
remove box derefs from codgen
Diffstat (limited to 'compiler/rustc_const_eval/src')
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs114
1 files changed, 64 insertions, 50 deletions
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 3f54d864297..66d66ea9510 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -240,65 +240,79 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
         context: PlaceContext,
         location: Location,
     ) {
-        if let ProjectionElem::Index(index) = elem {
-            let index_ty = self.body.local_decls[index].ty;
-            if index_ty != self.tcx.types.usize {
-                self.fail(location, format!("bad index ({:?} != usize)", index_ty))
+        match elem {
+            ProjectionElem::Index(index) => {
+                let index_ty = self.body.local_decls[index].ty;
+                if index_ty != self.tcx.types.usize {
+                    self.fail(location, format!("bad index ({:?} != usize)", index_ty))
+                }
             }
-        }
-        if let ProjectionElem::Field(f, ty) = elem {
-            let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
-            let parent_ty = parent.ty(&self.body.local_decls, self.tcx);
-            let fail_out_of_bounds = |this: &Self, location| {
-                this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
-            };
-            let check_equal = |this: &Self, location, f_ty| {
-                if !this.mir_assign_valid_types(ty, f_ty) {
-                    this.fail(
+            ProjectionElem::Deref if self.mir_phase >= MirPhase::GeneratorsLowered => {
+                let base_ty = Place::ty_from(local, proj_base, &self.body.local_decls, self.tcx).ty;
+
+                if base_ty.is_box() {
+                    self.fail(
+                        location,
+                        format!("{:?} dereferenced after ElaborateBoxDerefs", base_ty),
+                    )
+                }
+            }
+            ProjectionElem::Field(f, ty) => {
+                let parent = Place { local, projection: self.tcx.intern_place_elems(proj_base) };
+                let parent_ty = parent.ty(&self.body.local_decls, self.tcx);
+                let fail_out_of_bounds = |this: &Self, location| {
+                    this.fail(location, format!("Out of bounds field {:?} for {:?}", f, parent_ty));
+                };
+                let check_equal = |this: &Self, location, f_ty| {
+                    if !this.mir_assign_valid_types(ty, f_ty) {
+                        this.fail(
                         location,
                         format!(
                             "Field projection `{:?}.{:?}` specified type `{:?}`, but actual type is {:?}",
                             parent, f, ty, f_ty
                         )
                     )
-                }
-            };
-            match parent_ty.ty.kind() {
-                ty::Tuple(fields) => {
-                    let Some(f_ty) = fields.get(f.as_usize()) else {
-                        fail_out_of_bounds(self, location);
-                        return;
-                    };
-                    check_equal(self, location, *f_ty);
-                }
-                ty::Adt(adt_def, substs) => {
-                    let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0));
-                    let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else {
-                        fail_out_of_bounds(self, location);
-                        return;
-                    };
-                    check_equal(self, location, field.ty(self.tcx, substs));
-                }
-                ty::Closure(_, substs) => {
-                    let substs = substs.as_closure();
-                    let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
-                        fail_out_of_bounds(self, location);
-                        return;
-                    };
-                    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;
-                    };
-                    check_equal(self, location, f_ty);
-                }
-                _ => {
-                    self.fail(location, format!("{:?} does not have fields", parent_ty.ty));
+                    }
+                };
+
+                match parent_ty.ty.kind() {
+                    ty::Tuple(fields) => {
+                        let Some(f_ty) = fields.get(f.as_usize()) else {
+                            fail_out_of_bounds(self, location);
+                            return;
+                        };
+                        check_equal(self, location, *f_ty);
+                    }
+                    ty::Adt(adt_def, substs) => {
+                        let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0));
+                        let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else {
+                            fail_out_of_bounds(self, location);
+                            return;
+                        };
+                        check_equal(self, location, field.ty(self.tcx, substs));
+                    }
+                    ty::Closure(_, substs) => {
+                        let substs = substs.as_closure();
+                        let Some(f_ty) = substs.upvar_tys().nth(f.as_usize()) else {
+                            fail_out_of_bounds(self, location);
+                            return;
+                        };
+                        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;
+                        };
+                        check_equal(self, location, f_ty);
+                    }
+                    _ => {
+                        self.fail(location, format!("{:?} does not have fields", parent_ty.ty));
+                    }
                 }
             }
+            _ => {}
         }
         self.super_projection_elem(local, proj_base, elem, context, location);
     }