Skip to content

Commit 8e6d126

Browse files
committed
rustc_target: TyAndLayout::field should never error.
1 parent 87d1fb7 commit 8e6d126

File tree

10 files changed

+77
-77
lines changed

10 files changed

+77
-77
lines changed

compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -160,12 +160,10 @@ impl<'tcx> DebugContext<'tcx> {
160160

161161
for (field_idx, field_def) in variant.fields.iter().enumerate() {
162162
let field_offset = layout.fields.offset(field_idx);
163-
let field_layout = layout
164-
.field(
165-
&layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() },
166-
field_idx,
167-
)
168-
.unwrap();
163+
let field_layout = layout.field(
164+
&layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() },
165+
field_idx,
166+
);
169167

170168
let field_type = self.dwarf_ty(field_layout.ty);
171169

compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
789789
return;
790790
}
791791

792-
if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true).unwrap() {
792+
if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true) {
793793
with_no_trimmed_paths(|| crate::base::codegen_panic(
794794
fx,
795795
&format!("attempted to zero-initialize type `{}`, which is invalid", T),
@@ -798,7 +798,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>(
798798
return;
799799
}
800800

801-
if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false).unwrap() {
801+
if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false) {
802802
with_no_trimmed_paths(|| crate::base::codegen_panic(
803803
fx,
804804
&format!("attempted to leave type `{}` uninitialized, which is invalid", T),

compiler/rustc_codegen_ssa/src/mir/block.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -472,10 +472,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
472472
let layout = bx.layout_of(ty);
473473
let do_panic = match intrinsic {
474474
Inhabited => layout.abi.is_uninhabited(),
475-
// We unwrap as the error type is `!`.
476-
ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true).unwrap(),
477-
// We unwrap as the error type is `!`.
478-
UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false).unwrap(),
475+
ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true),
476+
UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false),
479477
};
480478
if do_panic {
481479
let msg_str = with_no_trimmed_paths(|| {

compiler/rustc_middle/src/ty/layout.rs

+53-48
Original file line numberDiff line numberDiff line change
@@ -1788,22 +1788,18 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
17881788
let field_info: Vec<_> = flds
17891789
.iter()
17901790
.enumerate()
1791-
.map(|(i, &name)| match layout.field(self, i) {
1792-
Err(err) => {
1793-
bug!("no layout found for field {}: `{:?}`", name, err);
1791+
.map(|(i, &name)| {
1792+
let field_layout = layout.field(self, i);
1793+
let offset = layout.fields.offset(i);
1794+
let field_end = offset + field_layout.size;
1795+
if min_size < field_end {
1796+
min_size = field_end;
17941797
}
1795-
Ok(field_layout) => {
1796-
let offset = layout.fields.offset(i);
1797-
let field_end = offset + field_layout.size;
1798-
if min_size < field_end {
1799-
min_size = field_end;
1800-
}
1801-
FieldInfo {
1802-
name: name.to_string(),
1803-
offset: offset.bytes(),
1804-
size: field_layout.size.bytes(),
1805-
align: field_layout.align.abi.bytes(),
1806-
}
1798+
FieldInfo {
1799+
name: name.to_string(),
1800+
offset: offset.bytes(),
1801+
size: field_layout.size.bytes(),
1802+
align: field_layout.align.abi.bytes(),
18071803
}
18081804
})
18091805
.collect();
@@ -2146,30 +2142,24 @@ where
21462142
TyAndLayout { ty: this.ty, layout }
21472143
}
21482144

2149-
fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout {
2150-
enum TyMaybeWithLayout<'tcx, C: LayoutOf<'tcx>> {
2151-
Ty(C::Ty),
2152-
TyAndLayout(C::TyAndLayout),
2145+
fn ty_and_layout_field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> TyAndLayout<'tcx> {
2146+
enum TyMaybeWithLayout<'tcx> {
2147+
Ty(Ty<'tcx>),
2148+
TyAndLayout(TyAndLayout<'tcx>),
21532149
}
21542150

2155-
fn ty_and_layout_kind<
2156-
C: LayoutOf<'tcx, Ty = Ty<'tcx>> + HasTyCtxt<'tcx> + HasParamEnv<'tcx>,
2157-
>(
2151+
fn field_ty_or_layout(
21582152
this: TyAndLayout<'tcx>,
2159-
cx: &C,
2153+
cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>),
21602154
i: usize,
2161-
ty: C::Ty,
2162-
) -> TyMaybeWithLayout<'tcx, C> {
2155+
) -> TyMaybeWithLayout<'tcx> {
21632156
let tcx = cx.tcx();
2164-
let tag_layout = |tag: &Scalar| -> C::TyAndLayout {
2157+
let tag_layout = |tag: &Scalar| -> TyAndLayout<'tcx> {
21652158
let layout = Layout::scalar(cx, tag.clone());
2166-
MaybeResult::from(Ok(TyAndLayout {
2167-
layout: tcx.intern_layout(layout),
2168-
ty: tag.value.to_ty(tcx),
2169-
}))
2159+
TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx) }
21702160
};
21712161

2172-
match *ty.kind() {
2162+
match *this.ty.kind() {
21732163
ty::Bool
21742164
| ty::Char
21752165
| ty::Int(_)
@@ -2180,7 +2170,7 @@ where
21802170
| ty::FnDef(..)
21812171
| ty::GeneratorWitness(..)
21822172
| ty::Foreign(..)
2183-
| ty::Dynamic(..) => bug!("TyAndLayout::field_type({:?}): not applicable", this),
2173+
| ty::Dynamic(..) => bug!("TyAndLayout::field({:?}): not applicable", this),
21842174

21852175
// Potentially-fat pointers.
21862176
ty::Ref(_, pointee, _) | ty::RawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
@@ -2192,17 +2182,19 @@ where
21922182
// as the `Abi` or `FieldsShape` is checked by users.
21932183
if i == 0 {
21942184
let nil = tcx.mk_unit();
2195-
let ptr_ty = if ty.is_unsafe_ptr() {
2185+
let unit_ptr_ty = if this.ty.is_unsafe_ptr() {
21962186
tcx.mk_mut_ptr(nil)
21972187
} else {
21982188
tcx.mk_mut_ref(tcx.lifetimes.re_static, nil)
21992189
};
2200-
return TyMaybeWithLayout::TyAndLayout(MaybeResult::from(
2201-
cx.layout_of(ptr_ty).to_result().map(|mut ptr_layout| {
2202-
ptr_layout.ty = ty;
2203-
ptr_layout
2204-
}),
2205-
));
2190+
2191+
// NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing
2192+
// the `Result` should always work because the type is
2193+
// always either `*mut ()` or `&'static mut ()`.
2194+
return TyMaybeWithLayout::TyAndLayout(TyAndLayout {
2195+
ty: this.ty,
2196+
..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap()
2197+
});
22062198
}
22072199

22082200
match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() {
@@ -2226,7 +2218,7 @@ where
22262218
])
22272219
*/
22282220
}
2229-
_ => bug!("TyAndLayout::field_type({:?}): not applicable", this),
2221+
_ => bug!("TyAndLayout::field({:?}): not applicable", this),
22302222
}
22312223
}
22322224

@@ -2235,9 +2227,11 @@ where
22352227
ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
22362228

22372229
// Tuples, generators and closures.
2238-
ty::Closure(_, ref substs) => {
2239-
ty_and_layout_kind(this, cx, i, substs.as_closure().tupled_upvars_ty())
2240-
}
2230+
ty::Closure(_, ref substs) => field_ty_or_layout(
2231+
TyAndLayout { ty: substs.as_closure().tupled_upvars_ty(), ..this },
2232+
cx,
2233+
i,
2234+
),
22412235

22422236
ty::Generator(def_id, ref substs, _) => match this.variants {
22432237
Variants::Single { index } => TyMaybeWithLayout::Ty(
@@ -2280,14 +2274,25 @@ where
22802274
| ty::Opaque(..)
22812275
| ty::Param(_)
22822276
| ty::Infer(_)
2283-
| ty::Error(_) => bug!("TyAndLayout::field_type: unexpected type `{}`", this.ty),
2277+
| ty::Error(_) => bug!("TyAndLayout::field: unexpected type `{}`", this.ty),
22842278
}
22852279
}
22862280

2287-
cx.layout_of(match ty_and_layout_kind(this, cx, i, this.ty) {
2288-
TyMaybeWithLayout::Ty(result) => result,
2289-
TyMaybeWithLayout::TyAndLayout(result) => return result,
2290-
})
2281+
match field_ty_or_layout(this, cx, i) {
2282+
TyMaybeWithLayout::Ty(field_ty) => {
2283+
cx.tcx().layout_of(cx.param_env().and(field_ty)).unwrap_or_else(|e| {
2284+
bug!(
2285+
"failed to get layout for `{}`: {},\n\
2286+
despite it being a field (#{}) of an existing layout: {:#?}",
2287+
field_ty,
2288+
e,
2289+
i,
2290+
this
2291+
)
2292+
})
2293+
}
2294+
TyMaybeWithLayout::TyAndLayout(field_layout) => field_layout,
2295+
}
22912296
}
22922297

22932298
fn ty_and_layout_pointee_info_at(

compiler/rustc_mir/src/interpret/cast.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
340340
// Example: `Arc<T>` -> `Arc<Trait>`
341341
// here we need to increase the size of every &T thin ptr field to a fat ptr
342342
for i in 0..src.layout.fields.count() {
343-
let cast_ty_field = cast_ty.field(self, i)?;
343+
let cast_ty_field = cast_ty.field(self, i);
344344
if cast_ty_field.is_zst() {
345345
continue;
346346
}

compiler/rustc_mir/src/interpret/eval_context.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
592592
// Recurse to get the size of the dynamically sized field (must be
593593
// the last field). Can't have foreign types here, how would we
594594
// adjust alignment and size for them?
595-
let field = layout.field(self, layout.fields.count() - 1)?;
595+
let field = layout.field(self, layout.fields.count() - 1);
596596
let (unsized_size, unsized_align) =
597597
match self.size_and_align_of(metadata, &field)? {
598598
Some(size_and_align) => size_and_align,
@@ -645,7 +645,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
645645

646646
ty::Slice(_) | ty::Str => {
647647
let len = metadata.unwrap_meta().to_machine_usize(self)?;
648-
let elem = layout.field(self, 0)?;
648+
let elem = layout.field(self, 0);
649649

650650
// Make sure the slice is not too big.
651651
let size = elem.size.checked_mul(len, self).ok_or_else(|| {

compiler/rustc_mir/src/interpret/operand.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
364364
Err(value) => value,
365365
};
366366

367-
let field_layout = op.layout.field(self, field)?;
367+
let field_layout = op.layout.field(self, field);
368368
if field_layout.is_zst() {
369369
let immediate = Scalar::ZST.into();
370370
return Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout });

compiler/rustc_mir/src/interpret/place.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ where
355355
field: usize,
356356
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> {
357357
let offset = base.layout.fields.offset(field);
358-
let field_layout = base.layout.field(self, field)?;
358+
let field_layout = base.layout.field(self, field);
359359

360360
// Offset may need adjustment for unsized fields.
361361
let (meta, offset) = if field_layout.is_unsized() {
@@ -405,7 +405,7 @@ where
405405
}
406406
let offset = stride * index; // `Size` multiplication
407407
// All fields have the same layout.
408-
let field_layout = base.layout.field(self, 0)?;
408+
let field_layout = base.layout.field(self, 0);
409409

410410
assert!(!field_layout.is_unsized());
411411
base.offset(offset, MemPlaceMeta::None, field_layout, self)
@@ -430,7 +430,7 @@ where
430430
FieldsShape::Array { stride, .. } => stride,
431431
_ => span_bug!(self.cur_span(), "mplace_array_fields: expected an array layout"),
432432
};
433-
let layout = base.layout.field(self, 0)?;
433+
let layout = base.layout.field(self, 0);
434434
let dl = &self.tcx.data_layout;
435435
// `Size` multiplication
436436
Ok((0..len).map(move |i| base.offset(stride * i, MemPlaceMeta::None, layout, dl)))

compiler/rustc_mir/src/interpret/terminator.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
461461
// a thin pointer.
462462
assert!(receiver_place.layout.is_unsized());
463463
let receiver_ptr_ty = self.tcx.mk_mut_ptr(receiver_place.layout.ty);
464-
let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0)?;
464+
let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0);
465465
// Adjust receiver argument.
466466
args[0] = OpTy::from(ImmTy::from_immediate(
467467
Scalar::from_maybe_pointer(receiver_place.ptr, self).into(),

compiler/rustc_target/src/abi/mod.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ pub trait TyAbiInterface<'a, C: LayoutOf<'a, Ty = Self>>: Sized {
12441244
cx: &C,
12451245
variant_index: VariantIdx,
12461246
) -> TyAndLayout<'a, Self>;
1247-
fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> C::TyAndLayout;
1247+
fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>;
12481248
fn ty_and_layout_pointee_info_at(
12491249
this: TyAndLayout<'a, Self>,
12501250
cx: &C,
@@ -1261,7 +1261,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
12611261
Ty::ty_and_layout_for_variant(self, cx, variant_index)
12621262
}
12631263

1264-
pub fn field<C>(self, cx: &C, i: usize) -> C::TyAndLayout
1264+
pub fn field<C>(self, cx: &C, i: usize) -> Self
12651265
where
12661266
Ty: TyAbiInterface<'a, C>,
12671267
C: LayoutOf<'a, Ty = Ty>,
@@ -1302,11 +1302,11 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
13021302
/// FIXME: Once we removed all the conservatism, we could alternatively
13031303
/// create an all-0/all-undef constant and run the const value validator to see if
13041304
/// this is a valid value for the given type.
1305-
pub fn might_permit_raw_init<C, E>(self, cx: &C, zero: bool) -> Result<bool, E>
1305+
pub fn might_permit_raw_init<C>(self, cx: &C, zero: bool) -> bool
13061306
where
13071307
Self: Copy,
13081308
Ty: TyAbiInterface<'a, C>,
1309-
C: LayoutOf<'a, Ty = Ty, TyAndLayout: MaybeResult<Self, Error = E>> + HasDataLayout,
1309+
C: LayoutOf<'a, Ty = Ty> + HasDataLayout,
13101310
{
13111311
let scalar_allows_raw_init = move |s: &Scalar| -> bool {
13121312
if zero {
@@ -1331,7 +1331,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
13311331
};
13321332
if !valid {
13331333
// This is definitely not okay.
1334-
return Ok(false);
1334+
return false;
13351335
}
13361336

13371337
// 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> {
13421342
}
13431343
FieldsShape::Arbitrary { offsets, .. } => {
13441344
for idx in 0..offsets.len() {
1345-
let field = self.field(cx, idx).to_result()?;
1346-
if !field.might_permit_raw_init(cx, zero)? {
1345+
if !self.field(cx, idx).might_permit_raw_init(cx, zero) {
13471346
// We found a field that is unhappy with this kind of initialization.
1348-
return Ok(false);
1347+
return false;
13491348
}
13501349
}
13511350
}
13521351
}
13531352

13541353
// FIXME(#66151): For now, we are conservative and do not check `self.variants`.
1355-
Ok(true)
1354+
true
13561355
}
13571356
}

0 commit comments

Comments
 (0)