mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
assert that unexpectedly unsized fields are sized in the param env
This commit is contained in:
parent
697450151c
commit
3db930a463
@ -36,12 +36,14 @@ enum NicheBias {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum LayoutCalculatorError {
|
pub enum LayoutCalculatorError<F> {
|
||||||
/// An unsized type was found in a location where a sized type was expected.
|
/// An unsized type was found in a location where a sized type was expected.
|
||||||
///
|
///
|
||||||
/// This is not always a compile error, for example if there is a `[T]: Sized`
|
/// This is not always a compile error, for example if there is a `[T]: Sized`
|
||||||
/// bound in a where clause.
|
/// bound in a where clause.
|
||||||
UnexpectedUnsized,
|
///
|
||||||
|
/// Contains the field that was unexpectedly unsized.
|
||||||
|
UnexpectedUnsized(F),
|
||||||
|
|
||||||
/// A type was too large for the target platform.
|
/// A type was too large for the target platform.
|
||||||
SizeOverflow,
|
SizeOverflow,
|
||||||
@ -50,8 +52,8 @@ pub enum LayoutCalculatorError {
|
|||||||
EmptyUnion,
|
EmptyUnion,
|
||||||
}
|
}
|
||||||
|
|
||||||
type LayoutCalculatorResult<FieldIdx, VariantIdx> =
|
type LayoutCalculatorResult<FieldIdx, VariantIdx, F> =
|
||||||
Result<LayoutS<FieldIdx, VariantIdx>, LayoutCalculatorError>;
|
Result<LayoutS<FieldIdx, VariantIdx>, LayoutCalculatorError<F>>;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct LayoutCalculator<Cx> {
|
pub struct LayoutCalculator<Cx> {
|
||||||
@ -100,13 +102,13 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
'a,
|
'a,
|
||||||
FieldIdx: Idx,
|
FieldIdx: Idx,
|
||||||
VariantIdx: Idx,
|
VariantIdx: Idx,
|
||||||
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
fields: &IndexSlice<FieldIdx, F>,
|
fields: &IndexSlice<FieldIdx, F>,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
kind: StructKind,
|
kind: StructKind,
|
||||||
) -> LayoutCalculatorResult<FieldIdx, VariantIdx> {
|
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
|
||||||
let dl = self.cx.data_layout();
|
let dl = self.cx.data_layout();
|
||||||
let layout = self.univariant_biased(fields, repr, kind, NicheBias::Start);
|
let layout = self.univariant_biased(fields, repr, kind, NicheBias::Start);
|
||||||
// Enums prefer niches close to the beginning or the end of the variants so that other
|
// Enums prefer niches close to the beginning or the end of the variants so that other
|
||||||
@ -191,7 +193,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
'a,
|
'a,
|
||||||
FieldIdx: Idx,
|
FieldIdx: Idx,
|
||||||
VariantIdx: Idx,
|
VariantIdx: Idx,
|
||||||
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
@ -203,7 +205,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
||||||
dont_niche_optimize_enum: bool,
|
dont_niche_optimize_enum: bool,
|
||||||
always_sized: bool,
|
always_sized: bool,
|
||||||
) -> LayoutCalculatorResult<FieldIdx, VariantIdx> {
|
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
|
||||||
let (present_first, present_second) = {
|
let (present_first, present_second) = {
|
||||||
let mut present_variants = variants
|
let mut present_variants = variants
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
@ -254,12 +256,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
'a,
|
'a,
|
||||||
FieldIdx: Idx,
|
FieldIdx: Idx,
|
||||||
VariantIdx: Idx,
|
VariantIdx: Idx,
|
||||||
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
||||||
) -> LayoutCalculatorResult<FieldIdx, VariantIdx> {
|
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
|
||||||
let dl = self.cx.data_layout();
|
let dl = self.cx.data_layout();
|
||||||
let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
let mut align = if repr.pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
||||||
let mut max_repr_align = repr.align;
|
let mut max_repr_align = repr.align;
|
||||||
@ -279,7 +281,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
let only_variant = &variants[only_variant_idx];
|
let only_variant = &variants[only_variant_idx];
|
||||||
for field in only_variant {
|
for field in only_variant {
|
||||||
if field.is_unsized() {
|
if field.is_unsized() {
|
||||||
return Err(LayoutCalculatorError::UnexpectedUnsized);
|
return Err(LayoutCalculatorError::UnexpectedUnsized(*field));
|
||||||
}
|
}
|
||||||
|
|
||||||
align = align.max(field.align);
|
align = align.max(field.align);
|
||||||
@ -359,7 +361,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// single-variant enums are just structs, if you think about it
|
/// single-variant enums are just structs, if you think about it
|
||||||
fn layout_of_struct<'a, FieldIdx: Idx, VariantIdx: Idx, F>(
|
fn layout_of_struct<
|
||||||
|
'a,
|
||||||
|
FieldIdx: Idx,
|
||||||
|
VariantIdx: Idx,
|
||||||
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
|
||||||
|
>(
|
||||||
&self,
|
&self,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
||||||
@ -368,10 +375,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
scalar_valid_range: (Bound<u128>, Bound<u128>),
|
scalar_valid_range: (Bound<u128>, Bound<u128>),
|
||||||
always_sized: bool,
|
always_sized: bool,
|
||||||
present_first: VariantIdx,
|
present_first: VariantIdx,
|
||||||
) -> LayoutCalculatorResult<FieldIdx, VariantIdx>
|
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
|
||||||
where
|
|
||||||
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
|
||||||
{
|
|
||||||
// Struct, or univariant enum equivalent to a struct.
|
// Struct, or univariant enum equivalent to a struct.
|
||||||
// (Typechecking will reject discriminant-sizing attrs.)
|
// (Typechecking will reject discriminant-sizing attrs.)
|
||||||
|
|
||||||
@ -457,17 +461,19 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
Ok(st)
|
Ok(st)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout_of_enum<'a, FieldIdx: Idx, VariantIdx: Idx, F>(
|
fn layout_of_enum<
|
||||||
|
'a,
|
||||||
|
FieldIdx: Idx,
|
||||||
|
VariantIdx: Idx,
|
||||||
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
|
||||||
|
>(
|
||||||
&self,
|
&self,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
||||||
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
|
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
|
||||||
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
||||||
dont_niche_optimize_enum: bool,
|
dont_niche_optimize_enum: bool,
|
||||||
) -> LayoutCalculatorResult<FieldIdx, VariantIdx>
|
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
|
||||||
where
|
|
||||||
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
|
||||||
{
|
|
||||||
// Until we've decided whether to use the tagged or
|
// Until we've decided whether to use the tagged or
|
||||||
// niche filling LayoutS, we don't want to intern the
|
// niche filling LayoutS, we don't want to intern the
|
||||||
// variant layouts, so we can't store them in the
|
// variant layouts, so we can't store them in the
|
||||||
@ -972,14 +978,14 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
'a,
|
'a,
|
||||||
FieldIdx: Idx,
|
FieldIdx: Idx,
|
||||||
VariantIdx: Idx,
|
VariantIdx: Idx,
|
||||||
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug,
|
F: Deref<Target = &'a LayoutS<FieldIdx, VariantIdx>> + fmt::Debug + Copy,
|
||||||
>(
|
>(
|
||||||
&self,
|
&self,
|
||||||
fields: &IndexSlice<FieldIdx, F>,
|
fields: &IndexSlice<FieldIdx, F>,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
kind: StructKind,
|
kind: StructKind,
|
||||||
niche_bias: NicheBias,
|
niche_bias: NicheBias,
|
||||||
) -> LayoutCalculatorResult<FieldIdx, VariantIdx> {
|
) -> LayoutCalculatorResult<FieldIdx, VariantIdx, F> {
|
||||||
let dl = self.cx.data_layout();
|
let dl = self.cx.data_layout();
|
||||||
let pack = repr.pack;
|
let pack = repr.pack;
|
||||||
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
let mut align = if pack.is_some() { dl.i8_align } else { dl.aggregate_align };
|
||||||
@ -1124,7 +1130,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
// field 5 with offset 0 puts 0 in offsets[5].
|
// field 5 with offset 0 puts 0 in offsets[5].
|
||||||
// At the bottom of this function, we invert `inverse_memory_index` to
|
// At the bottom of this function, we invert `inverse_memory_index` to
|
||||||
// produce `memory_index` (see `invert_mapping`).
|
// produce `memory_index` (see `invert_mapping`).
|
||||||
let mut sized = true;
|
let mut unsized_field = None::<&F>;
|
||||||
let mut offsets = IndexVec::from_elem(Size::ZERO, fields);
|
let mut offsets = IndexVec::from_elem(Size::ZERO, fields);
|
||||||
let mut offset = Size::ZERO;
|
let mut offset = Size::ZERO;
|
||||||
let mut largest_niche = None;
|
let mut largest_niche = None;
|
||||||
@ -1137,12 +1143,12 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
}
|
}
|
||||||
for &i in &inverse_memory_index {
|
for &i in &inverse_memory_index {
|
||||||
let field = &fields[i];
|
let field = &fields[i];
|
||||||
if !sized {
|
if let Some(unsized_field) = unsized_field {
|
||||||
return Err(LayoutCalculatorError::UnexpectedUnsized);
|
return Err(LayoutCalculatorError::UnexpectedUnsized(*unsized_field));
|
||||||
}
|
}
|
||||||
|
|
||||||
if field.is_unsized() {
|
if field.is_unsized() {
|
||||||
sized = false;
|
unsized_field = Some(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invariant: offset < dl.obj_size_bound() <= 1<<61
|
// Invariant: offset < dl.obj_size_bound() <= 1<<61
|
||||||
@ -1206,6 +1212,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||||||
return Err(LayoutCalculatorError::SizeOverflow);
|
return Err(LayoutCalculatorError::SizeOverflow);
|
||||||
}
|
}
|
||||||
let mut layout_of_single_non_zst_field = None;
|
let mut layout_of_single_non_zst_field = None;
|
||||||
|
let sized = unsized_field.is_none();
|
||||||
let mut abi = Abi::Aggregate { sized };
|
let mut abi = Abi::Aggregate { sized };
|
||||||
|
|
||||||
let optimize_abi = !repr.inhibit_newtype_abi_optimization();
|
let optimize_abi = !repr.inhibit_newtype_abi_optimization();
|
||||||
|
@ -20,7 +20,7 @@ pub struct IndexSlice<I: Idx, T> {
|
|||||||
|
|
||||||
impl<I: Idx, T> IndexSlice<I, T> {
|
impl<I: Idx, T> IndexSlice<I, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn empty() -> &'static Self {
|
pub const fn empty<'a>() -> &'a Self {
|
||||||
Self::from_raw(&[])
|
Self::from_raw(&[])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,19 +86,21 @@ fn error<'tcx>(cx: &LayoutCx<'tcx>, err: LayoutError<'tcx>) -> &'tcx LayoutError
|
|||||||
fn map_error<'tcx>(
|
fn map_error<'tcx>(
|
||||||
cx: &LayoutCx<'tcx>,
|
cx: &LayoutCx<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
err: LayoutCalculatorError,
|
err: LayoutCalculatorError<TyAndLayout<'tcx>>,
|
||||||
) -> &'tcx LayoutError<'tcx> {
|
) -> &'tcx LayoutError<'tcx> {
|
||||||
let err = match err {
|
let err = match err {
|
||||||
LayoutCalculatorError::SizeOverflow => {
|
LayoutCalculatorError::SizeOverflow => {
|
||||||
// This is sometimes not a compile error in `check` builds.
|
// This is sometimes not a compile error in `check` builds.
|
||||||
|
// See `tests/ui/limits/huge-enum.rs` for an example.
|
||||||
LayoutError::SizeOverflow(ty)
|
LayoutError::SizeOverflow(ty)
|
||||||
}
|
}
|
||||||
LayoutCalculatorError::UnexpectedUnsized => {
|
LayoutCalculatorError::UnexpectedUnsized(field) => {
|
||||||
// This is sometimes not a compile error if there are trivially false where
|
// This is sometimes not a compile error if there are trivially false where clauses.
|
||||||
// clauses, but it is always a compiler error in the empty environment.
|
// See `tests/ui/layout/trivial-bounds-sized.rs` for an example.
|
||||||
if cx.param_env.caller_bounds().is_empty() {
|
assert!(field.layout.is_unsized(), "invalid layout error {err:#?}");
|
||||||
|
if !field.ty.is_sized(cx.tcx(), cx.param_env) {
|
||||||
cx.tcx().dcx().delayed_bug(format!(
|
cx.tcx().dcx().delayed_bug(format!(
|
||||||
"encountered unexpected unsized field in layout of {ty:?}"
|
"encountered unexpected unsized field in layout of {ty:?}: {field:#?}"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
LayoutError::Unknown(ty)
|
LayoutError::Unknown(ty)
|
||||||
@ -115,7 +117,7 @@ fn map_error<'tcx>(
|
|||||||
fn univariant_uninterned<'tcx>(
|
fn univariant_uninterned<'tcx>(
|
||||||
cx: &LayoutCx<'tcx>,
|
cx: &LayoutCx<'tcx>,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
fields: &IndexSlice<FieldIdx, Layout<'_>>,
|
fields: &IndexSlice<FieldIdx, TyAndLayout<'tcx>>,
|
||||||
repr: &ReprOptions,
|
repr: &ReprOptions,
|
||||||
kind: StructKind,
|
kind: StructKind,
|
||||||
) -> Result<LayoutS<FieldIdx, VariantIdx>, &'tcx LayoutError<'tcx>> {
|
) -> Result<LayoutS<FieldIdx, VariantIdx>, &'tcx LayoutError<'tcx>> {
|
||||||
@ -148,9 +150,10 @@ fn layout_of_uncached<'tcx>(
|
|||||||
};
|
};
|
||||||
let scalar = |value: Primitive| tcx.mk_layout(LayoutS::scalar(cx, scalar_unit(value)));
|
let scalar = |value: Primitive| tcx.mk_layout(LayoutS::scalar(cx, scalar_unit(value)));
|
||||||
|
|
||||||
let univariant = |fields: &IndexSlice<FieldIdx, Layout<'_>>, repr: &ReprOptions, kind| {
|
let univariant =
|
||||||
Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, repr, kind)?))
|
|fields: &IndexSlice<FieldIdx, TyAndLayout<'tcx>>, repr: &ReprOptions, kind| {
|
||||||
};
|
Ok(tcx.mk_layout(univariant_uninterned(cx, ty, fields, repr, kind)?))
|
||||||
|
};
|
||||||
debug_assert!(!ty.has_non_region_infer());
|
debug_assert!(!ty.has_non_region_infer());
|
||||||
|
|
||||||
Ok(match *ty.kind() {
|
Ok(match *ty.kind() {
|
||||||
@ -388,9 +391,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
ty::Closure(_, args) => {
|
ty::Closure(_, args) => {
|
||||||
let tys = args.as_closure().upvar_tys();
|
let tys = args.as_closure().upvar_tys();
|
||||||
univariant(
|
univariant(
|
||||||
&tys.iter()
|
&tys.iter().map(|ty| cx.layout_of(ty)).try_collect::<IndexVec<_, _>>()?,
|
||||||
.map(|ty| Ok(cx.layout_of(ty)?.layout))
|
|
||||||
.try_collect::<IndexVec<_, _>>()?,
|
|
||||||
&ReprOptions::default(),
|
&ReprOptions::default(),
|
||||||
StructKind::AlwaysSized,
|
StructKind::AlwaysSized,
|
||||||
)?
|
)?
|
||||||
@ -399,9 +400,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
ty::CoroutineClosure(_, args) => {
|
ty::CoroutineClosure(_, args) => {
|
||||||
let tys = args.as_coroutine_closure().upvar_tys();
|
let tys = args.as_coroutine_closure().upvar_tys();
|
||||||
univariant(
|
univariant(
|
||||||
&tys.iter()
|
&tys.iter().map(|ty| cx.layout_of(ty)).try_collect::<IndexVec<_, _>>()?,
|
||||||
.map(|ty| Ok(cx.layout_of(ty)?.layout))
|
|
||||||
.try_collect::<IndexVec<_, _>>()?,
|
|
||||||
&ReprOptions::default(),
|
&ReprOptions::default(),
|
||||||
StructKind::AlwaysSized,
|
StructKind::AlwaysSized,
|
||||||
)?
|
)?
|
||||||
@ -412,7 +411,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
|
if tys.len() == 0 { StructKind::AlwaysSized } else { StructKind::MaybeUnsized };
|
||||||
|
|
||||||
univariant(
|
univariant(
|
||||||
&tys.iter().map(|k| Ok(cx.layout_of(k)?.layout)).try_collect::<IndexVec<_, _>>()?,
|
&tys.iter().map(|k| cx.layout_of(k)).try_collect::<IndexVec<_, _>>()?,
|
||||||
&ReprOptions::default(),
|
&ReprOptions::default(),
|
||||||
kind,
|
kind,
|
||||||
)?
|
)?
|
||||||
@ -552,7 +551,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
.map(|v| {
|
.map(|v| {
|
||||||
v.fields
|
v.fields
|
||||||
.iter()
|
.iter()
|
||||||
.map(|field| Ok(cx.layout_of(field.ty(tcx, args))?.layout))
|
.map(|field| cx.layout_of(field.ty(tcx, args)))
|
||||||
.try_collect::<IndexVec<_, _>>()
|
.try_collect::<IndexVec<_, _>>()
|
||||||
})
|
})
|
||||||
.try_collect::<IndexVec<VariantIdx, _>>()?;
|
.try_collect::<IndexVec<VariantIdx, _>>()?;
|
||||||
@ -651,7 +650,7 @@ fn layout_of_uncached<'tcx>(
|
|||||||
{
|
{
|
||||||
let mut variants = variants;
|
let mut variants = variants;
|
||||||
let tail_replacement = cx.layout_of(Ty::new_slice(tcx, tcx.types.u8)).unwrap();
|
let tail_replacement = cx.layout_of(Ty::new_slice(tcx, tcx.types.u8)).unwrap();
|
||||||
*variants[FIRST_VARIANT].raw.last_mut().unwrap() = tail_replacement.layout;
|
*variants[FIRST_VARIANT].raw.last_mut().unwrap() = tail_replacement;
|
||||||
|
|
||||||
let Ok(unsized_layout) = cx.calc.layout_of_struct_or_enum(
|
let Ok(unsized_layout) = cx.calc.layout_of_struct_or_enum(
|
||||||
&def.repr(),
|
&def.repr(),
|
||||||
@ -859,21 +858,24 @@ fn coroutine_layout<'tcx>(
|
|||||||
let max_discr = (info.variant_fields.len() - 1) as u128;
|
let max_discr = (info.variant_fields.len() - 1) as u128;
|
||||||
let discr_int = Integer::fit_unsigned(max_discr);
|
let discr_int = Integer::fit_unsigned(max_discr);
|
||||||
let tag = Scalar::Initialized {
|
let tag = Scalar::Initialized {
|
||||||
value: Primitive::Int(discr_int, false),
|
value: Primitive::Int(discr_int, /* signed = */ false),
|
||||||
valid_range: WrappingRange { start: 0, end: max_discr },
|
valid_range: WrappingRange { start: 0, end: max_discr },
|
||||||
};
|
};
|
||||||
let tag_layout = tcx.mk_layout(LayoutS::scalar(cx, tag));
|
let tag_layout = TyAndLayout {
|
||||||
|
ty: discr_int.to_ty(tcx, /* signed = */ false),
|
||||||
|
layout: tcx.mk_layout(LayoutS::scalar(cx, tag)),
|
||||||
|
};
|
||||||
|
|
||||||
let promoted_layouts = ineligible_locals.iter().map(|local| {
|
let promoted_layouts = ineligible_locals.iter().map(|local| {
|
||||||
let field_ty = instantiate_field(info.field_tys[local].ty);
|
let field_ty = instantiate_field(info.field_tys[local].ty);
|
||||||
let uninit_ty = Ty::new_maybe_uninit(tcx, field_ty);
|
let uninit_ty = Ty::new_maybe_uninit(tcx, field_ty);
|
||||||
Ok(cx.spanned_layout_of(uninit_ty, info.field_tys[local].source_info.span)?.layout)
|
cx.spanned_layout_of(uninit_ty, info.field_tys[local].source_info.span)
|
||||||
});
|
});
|
||||||
let prefix_layouts = args
|
let prefix_layouts = args
|
||||||
.as_coroutine()
|
.as_coroutine()
|
||||||
.prefix_tys()
|
.prefix_tys()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| Ok(cx.layout_of(ty)?.layout))
|
.map(|ty| cx.layout_of(ty))
|
||||||
.chain(iter::once(Ok(tag_layout)))
|
.chain(iter::once(Ok(tag_layout)))
|
||||||
.chain(promoted_layouts)
|
.chain(promoted_layouts)
|
||||||
.try_collect::<IndexVec<_, _>>()?;
|
.try_collect::<IndexVec<_, _>>()?;
|
||||||
@ -947,9 +949,7 @@ fn coroutine_layout<'tcx>(
|
|||||||
let mut variant = univariant_uninterned(
|
let mut variant = univariant_uninterned(
|
||||||
cx,
|
cx,
|
||||||
ty,
|
ty,
|
||||||
&variant_only_tys
|
&variant_only_tys.map(|ty| cx.layout_of(ty)).try_collect::<IndexVec<_, _>>()?,
|
||||||
.map(|ty| Ok(cx.layout_of(ty)?.layout))
|
|
||||||
.try_collect::<IndexVec<_, _>>()?,
|
|
||||||
&ReprOptions::default(),
|
&ReprOptions::default(),
|
||||||
StructKind::Prefixed(prefix_size, prefix_align.abi),
|
StructKind::Prefixed(prefix_size, prefix_align.abi),
|
||||||
)?;
|
)?;
|
||||||
|
@ -106,10 +106,10 @@ impl fmt::Display for LayoutError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<LayoutCalculatorError> for LayoutError {
|
impl<F> From<LayoutCalculatorError<F>> for LayoutError {
|
||||||
fn from(err: LayoutCalculatorError) -> Self {
|
fn from(err: LayoutCalculatorError<F>) -> Self {
|
||||||
match err {
|
match err {
|
||||||
LayoutCalculatorError::UnexpectedUnsized | LayoutCalculatorError::EmptyUnion => {
|
LayoutCalculatorError::UnexpectedUnsized(_) | LayoutCalculatorError::EmptyUnion => {
|
||||||
LayoutError::Unknown
|
LayoutError::Unknown
|
||||||
}
|
}
|
||||||
LayoutCalculatorError::SizeOverflow => LayoutError::SizeOverflow,
|
LayoutCalculatorError::SizeOverflow => LayoutError::SizeOverflow,
|
||||||
|
Loading…
Reference in New Issue
Block a user