diff options
| author | DrMeepster <19316085+DrMeepster@users.noreply.github.com> | 2022-05-13 21:53:03 -0700 |
|---|---|---|
| committer | DrMeepster <19316085+DrMeepster@users.noreply.github.com> | 2022-06-15 18:38:26 -0700 |
| commit | cb417881a9341e3258a3b1fa4a14c0717e226d61 (patch) | |
| tree | 11a4d98ee39821864826411ccf9a90b3c92d4753 /compiler/rustc_const_eval/src | |
| parent | 3e9d3d917a988973d9c657a257029a9bd850f6dc (diff) | |
| download | rust-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.rs | 114 |
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); } |
