diff options
Diffstat (limited to 'compiler/rustc_const_eval/src')
| -rw-r--r-- | compiler/rustc_const_eval/src/interpret/step.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/validate.rs | 23 |
2 files changed, 12 insertions, 13 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs index 8c34d05042b..b6993d939c5 100644 --- a/compiler/rustc_const_eval/src/interpret/step.rs +++ b/compiler/rustc_const_eval/src/interpret/step.rs @@ -275,7 +275,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { mir::NullOp::SizeOf => layout.size.bytes(), mir::NullOp::AlignOf => layout.align.abi.bytes(), mir::NullOp::OffsetOf(fields) => { - layout.offset_of_subfield(self, fields.iter().map(|f| f.index())).bytes() + layout.offset_of_subfield(self, fields.iter()).bytes() } }; self.write_scalar(Scalar::from_target_usize(val, self), &dest)?; diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index b70a342aa15..4d71f763667 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -1056,16 +1056,23 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } } - Rvalue::NullaryOp(NullOp::OffsetOf(fields), container) => { + Rvalue::NullaryOp(NullOp::OffsetOf(indices), container) => { let fail_out_of_bounds = |this: &mut Self, location, field, ty| { this.fail(location, format!("Out of bounds field {field:?} for {ty:?}")); }; let mut current_ty = *container; - for field in fields.iter() { + for (variant, field) in indices.iter() { match current_ty.kind() { ty::Tuple(fields) => { + if variant != FIRST_VARIANT { + self.fail( + location, + format!("tried to get variant {variant:?} of tuple"), + ); + return; + } let Some(&f_ty) = fields.get(field.as_usize()) else { fail_out_of_bounds(self, location, field, current_ty); return; @@ -1074,15 +1081,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); } ty::Adt(adt_def, args) => { - if adt_def.is_enum() { - self.fail( - location, - format!("Cannot get field offset from enum {current_ty:?}"), - ); - return; - } - - let Some(field) = adt_def.non_enum_variant().fields.get(field) else { + let Some(field) = adt_def.variant(variant).fields.get(field) else { fail_out_of_bounds(self, location, field, current_ty); return; }; @@ -1093,7 +1092,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { _ => { self.fail( location, - format!("Cannot get field offset from non-adt type {current_ty:?}"), + format!("Cannot get offset ({variant:?}, {field:?}) from type {current_ty:?}"), ); return; } |
