Skip to content

Commit 9556d7a

Browse files
committed
Auto merge of rust-lang#88337 - eddyb:field-failure-is-not-an-option, r=nagisa
rustc_target: `TyAndLayout::field` should never error. This refactor (making `TyAndLayout::field` return `TyAndLayout` without any `Result` around it) is based on a simple observation, regarding `TyAndLayout::field`: If `cx.layout_of(ty)` succeeds (for some `cx` and `ty`), then `.field(cx, i)` on the resulting `TyAndLayout` should *always* succeed in computing `cx.layout_of(field_ty)` (where `field_ty` is the type of the `i`th field of `ty`). The reason for this is that no matter which field is chosen, `cx.layout_of(field_ty)` *will have already been computed*, as part of computing `cx.layout_of(ty)`, as we cannot determine the layout of *any* type without considering the layouts of *all* of its fields. And so it should be fine to turn any errors into ICEs, since they likely indicate a `cx` mismatch, or some other edge case that is due to a compiler bug (as opposed to ever being an user-facing error). <hr/> Each commit should probably be reviewed separately, though note that there's some `where` clauses (in `rustc_target::abi::call::*`) that change in most commits. cc `@nagisa` `@oli-obk`
2 parents 2f662b1 + 78778fc commit 9556d7a

File tree

32 files changed

+308
-271
lines changed

32 files changed

+308
-271
lines changed

compiler/rustc_codegen_cranelift/src/common.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
256256
pub(crate) inline_asm_index: u32,
257257
}
258258

259-
impl<'tcx> LayoutOf for FunctionCx<'_, '_, 'tcx> {
259+
impl<'tcx> LayoutOf<'tcx> for FunctionCx<'_, '_, 'tcx> {
260260
type Ty = Ty<'tcx>;
261261
type TyAndLayout = TyAndLayout<'tcx>;
262262

@@ -364,7 +364,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
364364

365365
pub(crate) struct RevealAllLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
366366

367-
impl<'tcx> LayoutOf for RevealAllLayoutCx<'tcx> {
367+
impl<'tcx> LayoutOf<'tcx> for RevealAllLayoutCx<'tcx> {
368368
type Ty = Ty<'tcx>;
369369
type TyAndLayout = TyAndLayout<'tcx>;
370370

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_llvm/src/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl HasTargetSpec for Builder<'_, '_, 'tcx> {
8888
}
8989
}
9090

91-
impl abi::LayoutOf for Builder<'_, '_, 'tcx> {
91+
impl abi::LayoutOf<'tcx> for Builder<'_, '_, 'tcx> {
9292
type Ty = Ty<'tcx>;
9393
type TyAndLayout = TyAndLayout<'tcx>;
9494

compiler/rustc_codegen_llvm/src/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ impl ty::layout::HasTyCtxt<'tcx> for CodegenCx<'ll, 'tcx> {
835835
}
836836
}
837837

838-
impl LayoutOf for CodegenCx<'ll, 'tcx> {
838+
impl LayoutOf<'tcx> for CodegenCx<'ll, 'tcx> {
839839
type Ty = Ty<'tcx>;
840840
type TyAndLayout = TyAndLayout<'tcx>;
841841

compiler/rustc_codegen_llvm/src/type_of.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
99
use rustc_middle::ty::{self, Ty, TypeFoldable};
1010
use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape};
1111
use rustc_target::abi::{Int, Pointer, F32, F64};
12-
use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAndLayoutMethods, Variants};
12+
use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAbiInterface, Variants};
1313
use smallvec::{smallvec, SmallVec};
1414
use tracing::debug;
1515

@@ -393,12 +393,15 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
393393
}
394394
}
395395

396+
// FIXME(eddyb) this having the same name as `TyAndLayout::pointee_info_at`
397+
// (the inherent method, which is lacking this caching logic) can result in
398+
// the uncached version being called - not wrong, but potentially inefficient.
396399
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option<PointeeInfo> {
397400
if let Some(&pointee) = cx.pointee_infos.borrow().get(&(self.ty, offset)) {
398401
return pointee;
399402
}
400403

401-
let result = Ty::pointee_info_at(*self, cx, offset);
404+
let result = Ty::ty_and_layout_pointee_info_at(*self, cx, offset);
402405

403406
cx.pointee_infos.borrow_mut().insert((self.ty, offset), result);
404407
result

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_codegen_ssa/src/traits/backend.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,17 @@ pub trait BackendTypes {
3939
}
4040

4141
pub trait Backend<'tcx>:
42-
Sized + BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
42+
Sized
43+
+ BackendTypes
44+
+ HasTyCtxt<'tcx>
45+
+ LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
4346
{
4447
}
4548

4649
impl<'tcx, T> Backend<'tcx> for T where
47-
Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
50+
Self: BackendTypes
51+
+ HasTyCtxt<'tcx>
52+
+ LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
4853
{
4954
}
5055

compiler/rustc_lint/src/context.rs

+23-2
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ use rustc_session::Session;
4141
use rustc_session::SessionLintStore;
4242
use rustc_span::lev_distance::find_best_match_for_name;
4343
use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
44-
use rustc_target::abi::LayoutOf;
44+
use rustc_target::abi::{self, LayoutOf};
4545
use tracing::debug;
4646

4747
use std::cell::Cell;
@@ -1059,7 +1059,28 @@ impl<'tcx> LateContext<'tcx> {
10591059
}
10601060
}
10611061

1062-
impl<'tcx> LayoutOf for LateContext<'tcx> {
1062+
impl<'tcx> abi::HasDataLayout for LateContext<'tcx> {
1063+
#[inline]
1064+
fn data_layout(&self) -> &abi::TargetDataLayout {
1065+
&self.tcx.data_layout
1066+
}
1067+
}
1068+
1069+
impl<'tcx> ty::layout::HasTyCtxt<'tcx> for LateContext<'tcx> {
1070+
#[inline]
1071+
fn tcx(&self) -> TyCtxt<'tcx> {
1072+
self.tcx
1073+
}
1074+
}
1075+
1076+
impl<'tcx> ty::layout::HasParamEnv<'tcx> for LateContext<'tcx> {
1077+
#[inline]
1078+
fn param_env(&self) -> ty::ParamEnv<'tcx> {
1079+
self.param_env
1080+
}
1081+
}
1082+
1083+
impl<'tcx> LayoutOf<'tcx> for LateContext<'tcx> {
10631084
type Ty = Ty<'tcx>;
10641085
type TyAndLayout = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
10651086

0 commit comments

Comments
 (0)