rustc_target: TyAndLayout::field
should never error.
This commit is contained in:
parent
87d1fb747f
commit
8e6d126b7d
10 changed files with 77 additions and 77 deletions
|
@ -160,12 +160,10 @@ impl<'tcx> DebugContext<'tcx> {
|
||||||
|
|
||||||
for (field_idx, field_def) in variant.fields.iter().enumerate() {
|
for (field_idx, field_def) in variant.fields.iter().enumerate() {
|
||||||
let field_offset = layout.fields.offset(field_idx);
|
let field_offset = layout.fields.offset(field_idx);
|
||||||
let field_layout = layout
|
let field_layout = layout.field(
|
||||||
.field(
|
&layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() },
|
||||||
&layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() },
|
field_idx,
|
||||||
field_idx,
|
);
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let field_type = self.dwarf_ty(field_layout.ty);
|
let field_type = self.dwarf_ty(field_layout.ty);
|
||||||
|
|
||||||
|
|
|
@ -789,7 +789,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true).unwrap() {
|
if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true) {
|
||||||
with_no_trimmed_paths(|| crate::base::codegen_panic(
|
with_no_trimmed_paths(|| crate::base::codegen_panic(
|
||||||
fx,
|
fx,
|
||||||
&format!("attempted to zero-initialize type `{}`, which is invalid", T),
|
&format!("attempted to zero-initialize type `{}`, which is invalid", T),
|
||||||
|
@ -798,7 +798,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false).unwrap() {
|
if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false) {
|
||||||
with_no_trimmed_paths(|| crate::base::codegen_panic(
|
with_no_trimmed_paths(|| crate::base::codegen_panic(
|
||||||
fx,
|
fx,
|
||||||
&format!("attempted to leave type `{}` uninitialized, which is invalid", T),
|
&format!("attempted to leave type `{}` uninitialized, which is invalid", T),
|
||||||
|
|
|
@ -472,10 +472,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
let layout = bx.layout_of(ty);
|
let layout = bx.layout_of(ty);
|
||||||
let do_panic = match intrinsic {
|
let do_panic = match intrinsic {
|
||||||
Inhabited => layout.abi.is_uninhabited(),
|
Inhabited => layout.abi.is_uninhabited(),
|
||||||
// We unwrap as the error type is `!`.
|
ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true),
|
||||||
ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true).unwrap(),
|
UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false),
|
||||||
// We unwrap as the error type is `!`.
|
|
||||||
UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false).unwrap(),
|
|
||||||
};
|
};
|
||||||
if do_panic {
|
if do_panic {
|
||||||
let msg_str = with_no_trimmed_paths(|| {
|
let msg_str = with_no_trimmed_paths(|| {
|
||||||
|
|
|
@ -1788,22 +1788,18 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||||
let field_info: Vec<_> = flds
|
let field_info: Vec<_> = flds
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, &name)| match layout.field(self, i) {
|
.map(|(i, &name)| {
|
||||||
Err(err) => {
|
let field_layout = layout.field(self, i);
|
||||||
bug!("no layout found for field {}: `{:?}`", name, err);
|
let offset = layout.fields.offset(i);
|
||||||
|
let field_end = offset + field_layout.size;
|
||||||
|
if min_size < field_end {
|
||||||
|
min_size = field_end;
|
||||||
}
|
}
|
||||||
Ok(field_layout) => {
|
FieldInfo {
|
||||||
let offset = layout.fields.offset(i);
|
name: name.to_string(),
|
||||||
let field_end = offset + field_layout.size;
|
offset: offset.bytes(),
|
||||||
if min_size < field_end {
|
size: field_layout.size.bytes(),
|
||||||
min_size = field_end;
|
align: field_layout.align.abi.bytes(),
|
||||||
}
|
|
||||||
FieldInfo {
|
|
||||||
name: name.to_string(),
|
|
||||||
offset: offset.bytes(),
|
|
||||||
size: field_layout.size.bytes(),
|
|
||||||
align: field_layout.align.abi.bytes(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -2146,30 +2142,24 @@ where
|
||||||
TyAndLayout { ty: this.ty, layout }
|
TyAndLayout { ty: this.ty, layout }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout {
|
fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> TyAndLayout<'tcx> {
|
||||||
enum TyMaybeWithLayout<'tcx, C: LayoutOf<'tcx>> {
|
enum TyMaybeWithLayout<'tcx> {
|
||||||
Ty(C::Ty),
|
Ty(Ty<'tcx>),
|
||||||
TyAndLayout(C::TyAndLayout),
|
TyAndLayout(TyAndLayout<'tcx>),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_and_layout_kind<
|
fn field_ty_or_layout(
|
||||||
C: LayoutOf<'tcx, Ty = Ty<'tcx>> + HasTyCtxt<'tcx> + HasParamEnv<'tcx>,
|
|
||||||
>(
|
|
||||||
this: TyAndLayout<'tcx>,
|
this: TyAndLayout<'tcx>,
|
||||||
cx: &C,
|
cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>),
|
||||||
i: usize,
|
i: usize,
|
||||||
ty: C::Ty,
|
) -> TyMaybeWithLayout<'tcx> {
|
||||||
) -> TyMaybeWithLayout<'tcx, C> {
|
|
||||||
let tcx = cx.tcx();
|
let tcx = cx.tcx();
|
||||||
let tag_layout = |tag: &Scalar| -> C::TyAndLayout {
|
let tag_layout = |tag: &Scalar| -> TyAndLayout<'tcx> {
|
||||||
let layout = Layout::scalar(cx, tag.clone());
|
let layout = Layout::scalar(cx, tag.clone());
|
||||||
MaybeResult::from(Ok(TyAndLayout {
|
TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx) }
|
||||||
layout: tcx.intern_layout(layout),
|
|
||||||
ty: tag.value.to_ty(tcx),
|
|
||||||
}))
|
|
||||||
};
|
};
|
||||||
|
|
||||||
match *ty.kind() {
|
match *this.ty.kind() {
|
||||||
ty::Bool
|
ty::Bool
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Int(_)
|
| ty::Int(_)
|
||||||
|
@ -2180,7 +2170,7 @@ where
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::GeneratorWitness(..)
|
||||||
| ty::Foreign(..)
|
| ty::Foreign(..)
|
||||||
| ty::Dynamic(..) => bug!("TyAndLayout::field_type({:?}): not applicable", this),
|
| ty::Dynamic(..) => bug!("TyAndLayout::field({:?}): not applicable", this),
|
||||||
|
|
||||||
// Potentially-fat pointers.
|
// Potentially-fat pointers.
|
||||||
ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
|
ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
|
||||||
|
@ -2192,17 +2182,19 @@ where
|
||||||
// as the `Abi` or `FieldsShape` is checked by users.
|
// as the `Abi` or `FieldsShape` is checked by users.
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
let nil = tcx.mk_unit();
|
let nil = tcx.mk_unit();
|
||||||
let ptr_ty = if ty.is_unsafe_ptr() {
|
let unit_ptr_ty = if this.ty.is_unsafe_ptr() {
|
||||||
tcx.mk_mut_ptr(nil)
|
tcx.mk_mut_ptr(nil)
|
||||||
} else {
|
} else {
|
||||||
tcx.mk_mut_ref(tcx.lifetimes.re_static, nil)
|
tcx.mk_mut_ref(tcx.lifetimes.re_static, nil)
|
||||||
};
|
};
|
||||||
return TyMaybeWithLayout::TyAndLayout(MaybeResult::from(
|
|
||||||
cx.layout_of(ptr_ty).to_result().map(|mut ptr_layout| {
|
// NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing
|
||||||
ptr_layout.ty = ty;
|
// the `Result` should always work because the type is
|
||||||
ptr_layout
|
// always either `*mut ()` or `&'static mut ()`.
|
||||||
}),
|
return TyMaybeWithLayout::TyAndLayout(TyAndLayout {
|
||||||
));
|
ty: this.ty,
|
||||||
|
..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
|
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
|
||||||
|
@ -2226,7 +2218,7 @@ where
|
||||||
])
|
])
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
_ => bug!("TyAndLayout::field_type({:?}): not applicable", this),
|
_ => bug!("TyAndLayout::field({:?}): not applicable", this),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2235,9 +2227,11 @@ where
|
||||||
ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
|
ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
|
||||||
|
|
||||||
// Tuples, generators and closures.
|
// Tuples, generators and closures.
|
||||||
ty::Closure(_, ref substs) => {
|
ty::Closure(_, ref substs) => field_ty_or_layout(
|
||||||
ty_and_layout_kind(this, cx, i, substs.as_closure().tupled_upvars_ty())
|
TyAndLayout { ty: substs.as_closure().tupled_upvars_ty(), ..this },
|
||||||
}
|
cx,
|
||||||
|
i,
|
||||||
|
),
|
||||||
|
|
||||||
ty::Generator(def_id, ref substs, _) => match this.variants {
|
ty::Generator(def_id, ref substs, _) => match this.variants {
|
||||||
Variants::Single { index } => TyMaybeWithLayout::Ty(
|
Variants::Single { index } => TyMaybeWithLayout::Ty(
|
||||||
|
@ -2280,14 +2274,25 @@ where
|
||||||
| ty::Opaque(..)
|
| ty::Opaque(..)
|
||||||
| ty::Param(_)
|
| ty::Param(_)
|
||||||
| ty::Infer(_)
|
| ty::Infer(_)
|
||||||
| ty::Error(_) => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty),
|
| ty::Error(_) => bug!("TyAndLayout::field: unexpected type `{}`", this.ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.layout_of(match ty_and_layout_kind(this, cx, i, this.ty) {
|
match field_ty_or_layout(this, cx, i) {
|
||||||
TyMaybeWithLayout::Ty(result) => result,
|
TyMaybeWithLayout::Ty(field_ty) => {
|
||||||
TyMaybeWithLayout::TyAndLayout(result) => return result,
|
cx.tcx().layout_of(cx.param_env().and(field_ty)).unwrap_or_else(|e| {
|
||||||
})
|
bug!(
|
||||||
|
"failed to get layout for `{}`: {},\n\
|
||||||
|
despite it being a field (#{}) of an existing layout: {:#?}",
|
||||||
|
field_ty,
|
||||||
|
e,
|
||||||
|
i,
|
||||||
|
this
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
TyMaybeWithLayout::TyAndLayout(field_layout) => field_layout,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_and_layout_pointee_info_at(
|
fn ty_and_layout_pointee_info_at(
|
||||||
|
|
|
@ -340,7 +340,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Example: `Arc<T>` -> `Arc<Trait>`
|
// Example: `Arc<T>` -> `Arc<Trait>`
|
||||||
// here we need to increase the size of every &T thin ptr field to a fat ptr
|
// here we need to increase the size of every &T thin ptr field to a fat ptr
|
||||||
for i in 0..src.layout.fields.count() {
|
for i in 0..src.layout.fields.count() {
|
||||||
let cast_ty_field = cast_ty.field(self, i)?;
|
let cast_ty_field = cast_ty.field(self, i);
|
||||||
if cast_ty_field.is_zst() {
|
if cast_ty_field.is_zst() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -592,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// Recurse to get the size of the dynamically sized field (must be
|
// Recurse to get the size of the dynamically sized field (must be
|
||||||
// the last field). Can't have foreign types here, how would we
|
// the last field). Can't have foreign types here, how would we
|
||||||
// adjust alignment and size for them?
|
// adjust alignment and size for them?
|
||||||
let field = layout.field(self, layout.fields.count() - 1)?;
|
let field = layout.field(self, layout.fields.count() - 1);
|
||||||
let (unsized_size, unsized_align) =
|
let (unsized_size, unsized_align) =
|
||||||
match self.size_and_align_of(metadata, &field)? {
|
match self.size_and_align_of(metadata, &field)? {
|
||||||
Some(size_and_align) => size_and_align,
|
Some(size_and_align) => size_and_align,
|
||||||
|
@ -645,7 +645,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
ty::Slice(_) | ty::Str => {
|
ty::Slice(_) | ty::Str => {
|
||||||
let len = metadata.unwrap_meta().to_machine_usize(self)?;
|
let len = metadata.unwrap_meta().to_machine_usize(self)?;
|
||||||
let elem = layout.field(self, 0)?;
|
let elem = layout.field(self, 0);
|
||||||
|
|
||||||
// Make sure the slice is not too big.
|
// Make sure the slice is not too big.
|
||||||
let size = elem.size.checked_mul(len, self).ok_or_else(|| {
|
let size = elem.size.checked_mul(len, self).ok_or_else(|| {
|
||||||
|
|
|
@ -364,7 +364,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
Err(value) => value,
|
Err(value) => value,
|
||||||
};
|
};
|
||||||
|
|
||||||
let field_layout = op.layout.field(self, field)?;
|
let field_layout = op.layout.field(self, field);
|
||||||
if field_layout.is_zst() {
|
if field_layout.is_zst() {
|
||||||
let immediate = Scalar::ZST.into();
|
let immediate = Scalar::ZST.into();
|
||||||
return Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout });
|
return Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout });
|
||||||
|
|
|
@ -355,7 +355,7 @@ where
|
||||||
field: usize,
|
field: usize,
|
||||||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
|
||||||
let offset = base.layout.fields.offset(field);
|
let offset = base.layout.fields.offset(field);
|
||||||
let field_layout = base.layout.field(self, field)?;
|
let field_layout = base.layout.field(self, field);
|
||||||
|
|
||||||
// Offset may need adjustment for unsized fields.
|
// Offset may need adjustment for unsized fields.
|
||||||
let (meta, offset) = if field_layout.is_unsized() {
|
let (meta, offset) = if field_layout.is_unsized() {
|
||||||
|
@ -405,7 +405,7 @@ where
|
||||||
}
|
}
|
||||||
let offset = stride * index; // `Size` multiplication
|
let offset = stride * index; // `Size` multiplication
|
||||||
// All fields have the same layout.
|
// All fields have the same layout.
|
||||||
let field_layout = base.layout.field(self, 0)?;
|
let field_layout = base.layout.field(self, 0);
|
||||||
|
|
||||||
assert!(!field_layout.is_unsized());
|
assert!(!field_layout.is_unsized());
|
||||||
base.offset(offset, MemPlaceMeta::None, field_layout, self)
|
base.offset(offset, MemPlaceMeta::None, field_layout, self)
|
||||||
|
@ -430,7 +430,7 @@ where
|
||||||
FieldsShape::Array { stride, .. } => stride,
|
FieldsShape::Array { stride, .. } => stride,
|
||||||
_ => span_bug!(self.cur_span(), "mplace_array_fields: expected an array layout"),
|
_ => span_bug!(self.cur_span(), "mplace_array_fields: expected an array layout"),
|
||||||
};
|
};
|
||||||
let layout = base.layout.field(self, 0)?;
|
let layout = base.layout.field(self, 0);
|
||||||
let dl = &self.tcx.data_layout;
|
let dl = &self.tcx.data_layout;
|
||||||
// `Size` multiplication
|
// `Size` multiplication
|
||||||
Ok((0..len).map(move |i| base.offset(stride * i, MemPlaceMeta::None, layout, dl)))
|
Ok((0..len).map(move |i| base.offset(stride * i, MemPlaceMeta::None, layout, dl)))
|
||||||
|
|
|
@ -461,7 +461,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
// a thin pointer.
|
// a thin pointer.
|
||||||
assert!(receiver_place.layout.is_unsized());
|
assert!(receiver_place.layout.is_unsized());
|
||||||
let receiver_ptr_ty = self.tcx.mk_mut_ptr(receiver_place.layout.ty);
|
let receiver_ptr_ty = self.tcx.mk_mut_ptr(receiver_place.layout.ty);
|
||||||
let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0)?;
|
let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0);
|
||||||
// Adjust receiver argument.
|
// Adjust receiver argument.
|
||||||
args[0] = OpTy::from(ImmTy::from_immediate(
|
args[0] = OpTy::from(ImmTy::from_immediate(
|
||||||
Scalar::from_maybe_pointer(receiver_place.ptr, self).into(),
|
Scalar::from_maybe_pointer(receiver_place.ptr, self).into(),
|
||||||
|
|
|
@ -1244,7 +1244,7 @@ pub trait TyAbiInterface<'a, C: LayoutOf<'a, Ty = Self>>: Sized {
|
||||||
cx: &C,
|
cx: &C,
|
||||||
variant_index: VariantIdx,
|
variant_index: VariantIdx,
|
||||||
) -> TyAndLayout<'a, Self>;
|
) -> TyAndLayout<'a, Self>;
|
||||||
fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> C::TyAndLayout;
|
fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>;
|
||||||
fn ty_and_layout_pointee_info_at(
|
fn ty_and_layout_pointee_info_at(
|
||||||
this: TyAndLayout<'a, Self>,
|
this: TyAndLayout<'a, Self>,
|
||||||
cx: &C,
|
cx: &C,
|
||||||
|
@ -1261,7 +1261,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
||||||
Ty::ty_and_layout_for_variant(self, cx, variant_index)
|
Ty::ty_and_layout_for_variant(self, cx, variant_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn field<C>(self, cx: &C, i: usize) -> C::TyAndLayout
|
pub fn field<C>(self, cx: &C, i: usize) -> Self
|
||||||
where
|
where
|
||||||
Ty: TyAbiInterface<'a, C>,
|
Ty: TyAbiInterface<'a, C>,
|
||||||
C: LayoutOf<'a, Ty = Ty>,
|
C: LayoutOf<'a, Ty = Ty>,
|
||||||
|
@ -1302,11 +1302,11 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
||||||
/// FIXME: Once we removed all the conservatism, we could alternatively
|
/// FIXME: Once we removed all the conservatism, we could alternatively
|
||||||
/// create an all-0/all-undef constant and run the const value validator to see if
|
/// create an all-0/all-undef constant and run the const value validator to see if
|
||||||
/// this is a valid value for the given type.
|
/// this is a valid value for the given type.
|
||||||
pub fn might_permit_raw_init<C, E>(self, cx: &C, zero: bool) -> Result<bool, E>
|
pub fn might_permit_raw_init<C>(self, cx: &C, zero: bool) -> bool
|
||||||
where
|
where
|
||||||
Self: Copy,
|
Self: Copy,
|
||||||
Ty: TyAbiInterface<'a, C>,
|
Ty: TyAbiInterface<'a, C>,
|
||||||
C: LayoutOf<'a, Ty = Ty, TyAndLayout: MaybeResult<Self, Error = E>> + HasDataLayout,
|
C: LayoutOf<'a, Ty = Ty> + HasDataLayout,
|
||||||
{
|
{
|
||||||
let scalar_allows_raw_init = move |s: &Scalar| -> bool {
|
let scalar_allows_raw_init = move |s: &Scalar| -> bool {
|
||||||
if zero {
|
if zero {
|
||||||
|
@ -1331,7 +1331,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
||||||
};
|
};
|
||||||
if !valid {
|
if !valid {
|
||||||
// This is definitely not okay.
|
// This is definitely not okay.
|
||||||
return Ok(false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we have not found an error yet, we need to recursively descend into fields.
|
// If we have not found an error yet, we need to recursively descend into fields.
|
||||||
|
@ -1342,16 +1342,15 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
|
||||||
}
|
}
|
||||||
FieldsShape::Arbitrary { offsets, .. } => {
|
FieldsShape::Arbitrary { offsets, .. } => {
|
||||||
for idx in 0..offsets.len() {
|
for idx in 0..offsets.len() {
|
||||||
let field = self.field(cx, idx).to_result()?;
|
if !self.field(cx, idx).might_permit_raw_init(cx, zero) {
|
||||||
if !field.might_permit_raw_init(cx, zero)? {
|
|
||||||
// We found a field that is unhappy with this kind of initialization.
|
// We found a field that is unhappy with this kind of initialization.
|
||||||
return Ok(false);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(#66151): For now, we are conservative and do not check `self.variants`.
|
// FIXME(#66151): For now, we are conservative and do not check `self.variants`.
|
||||||
Ok(true)
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue