rustc_target: TyAndLayout::field should never error.
This commit is contained in:
@@ -1788,22 +1788,18 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
||||
let field_info: Vec<_> = flds
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, &name)| match layout.field(self, i) {
|
||||
Err(err) => {
|
||||
bug!("no layout found for field {}: `{:?}`", name, err);
|
||||
.map(|(i, &name)| {
|
||||
let field_layout = layout.field(self, i);
|
||||
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) => {
|
||||
let offset = layout.fields.offset(i);
|
||||
let field_end = offset + field_layout.size;
|
||||
if min_size < field_end {
|
||||
min_size = field_end;
|
||||
}
|
||||
FieldInfo {
|
||||
name: name.to_string(),
|
||||
offset: offset.bytes(),
|
||||
size: field_layout.size.bytes(),
|
||||
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();
|
||||
@@ -2146,30 +2142,24 @@ where
|
||||
TyAndLayout { ty: this.ty, layout }
|
||||
}
|
||||
|
||||
fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout {
|
||||
enum TyMaybeWithLayout<'tcx, C: LayoutOf<'tcx>> {
|
||||
Ty(C::Ty),
|
||||
TyAndLayout(C::TyAndLayout),
|
||||
fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> TyAndLayout<'tcx> {
|
||||
enum TyMaybeWithLayout<'tcx> {
|
||||
Ty(Ty<'tcx>),
|
||||
TyAndLayout(TyAndLayout<'tcx>),
|
||||
}
|
||||
|
||||
fn ty_and_layout_kind<
|
||||
C: LayoutOf<'tcx, Ty = Ty<'tcx>> + HasTyCtxt<'tcx> + HasParamEnv<'tcx>,
|
||||
>(
|
||||
fn field_ty_or_layout(
|
||||
this: TyAndLayout<'tcx>,
|
||||
cx: &C,
|
||||
cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>),
|
||||
i: usize,
|
||||
ty: C::Ty,
|
||||
) -> TyMaybeWithLayout<'tcx, C> {
|
||||
) -> TyMaybeWithLayout<'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());
|
||||
MaybeResult::from(Ok(TyAndLayout {
|
||||
layout: tcx.intern_layout(layout),
|
||||
ty: tag.value.to_ty(tcx),
|
||||
}))
|
||||
TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx) }
|
||||
};
|
||||
|
||||
match *ty.kind() {
|
||||
match *this.ty.kind() {
|
||||
ty::Bool
|
||||
| ty::Char
|
||||
| ty::Int(_)
|
||||
@@ -2180,7 +2170,7 @@ where
|
||||
| ty::FnDef(..)
|
||||
| ty::GeneratorWitness(..)
|
||||
| ty::Foreign(..)
|
||||
| ty::Dynamic(..) => bug!("TyAndLayout::field_type({:?}): not applicable", this),
|
||||
| ty::Dynamic(..) => bug!("TyAndLayout::field({:?}): not applicable", this),
|
||||
|
||||
// Potentially-fat pointers.
|
||||
ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
|
||||
@@ -2192,17 +2182,19 @@ where
|
||||
// as the `Abi` or `FieldsShape` is checked by users.
|
||||
if i == 0 {
|
||||
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)
|
||||
} else {
|
||||
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| {
|
||||
ptr_layout.ty = ty;
|
||||
ptr_layout
|
||||
}),
|
||||
));
|
||||
|
||||
// NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing
|
||||
// the `Result` should always work because the type is
|
||||
// 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() {
|
||||
@@ -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),
|
||||
|
||||
// Tuples, generators and closures.
|
||||
ty::Closure(_, ref substs) => {
|
||||
ty_and_layout_kind(this, cx, i, substs.as_closure().tupled_upvars_ty())
|
||||
}
|
||||
ty::Closure(_, ref substs) => field_ty_or_layout(
|
||||
TyAndLayout { ty: substs.as_closure().tupled_upvars_ty(), ..this },
|
||||
cx,
|
||||
i,
|
||||
),
|
||||
|
||||
ty::Generator(def_id, ref substs, _) => match this.variants {
|
||||
Variants::Single { index } => TyMaybeWithLayout::Ty(
|
||||
@@ -2280,14 +2274,25 @@ where
|
||||
| ty::Opaque(..)
|
||||
| ty::Param(_)
|
||||
| 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) {
|
||||
TyMaybeWithLayout::Ty(result) => result,
|
||||
TyMaybeWithLayout::TyAndLayout(result) => return result,
|
||||
})
|
||||
match field_ty_or_layout(this, cx, i) {
|
||||
TyMaybeWithLayout::Ty(field_ty) => {
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user