Skip to content

rustc_target: route LayoutOf through TyAbiInterface. #88338

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub(crate) fn codegen_fn<'tcx>(
let arg_uninhabited = fx
.mir
.args_iter()
.any(|arg| fx.layout_of(fx.monomorphize(&fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
.any(|arg| fx.layout_of(fx.monomorphize(fx.mir.local_decls[arg].ty)).abi.is_uninhabited());

if !crate::constant::check_constants(&mut fx) {
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
Expand Down Expand Up @@ -835,7 +835,7 @@ pub(crate) fn codegen_place<'tcx>(
let from: u64 = from;
let to: u64 = to;

match cplace.layout().ty.kind() {
match *cplace.layout().ty.kind() {
ty::Array(elem_ty, _len) => {
assert!(!from_end, "array subslices are never `from_end`");
let elem_layout = fx.layout_of(elem_ty);
Expand Down
48 changes: 23 additions & 25 deletions compiler/rustc_codegen_cranelift/src/common.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rustc_index::vec::IndexVec;
use rustc_middle::ty::layout::LayoutError;
use rustc_middle::ty::SymbolName;
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::{Integer, Primitive};
Expand Down Expand Up @@ -256,15 +257,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
pub(crate) inline_asm_index: u32,
}

impl<'tcx> LayoutOf<'tcx> for FunctionCx<'_, '_, 'tcx> {
type Ty = Ty<'tcx>;
type TyAndLayout = TyAndLayout<'tcx>;

fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> {
RevealAllLayoutCx(self.tcx).layout_of(ty)
}
}

impl<'tcx> layout::HasTyCtxt<'tcx> for FunctionCx<'_, '_, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.tcx
Expand All @@ -289,6 +281,15 @@ impl<'tcx> HasTargetSpec for FunctionCx<'_, '_, 'tcx> {
}
}

impl<'tcx> ty::layout::IsLayoutCx<'tcx> for FunctionCx<'_, '_, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;

#[inline]
fn map_err_for_layout_of(err: LayoutError<'tcx>, cx: &Self, span: Span, ty: Ty<'tcx>) -> ! {
RevealAllLayoutCx::map_err_for_layout_of(err, &RevealAllLayoutCx(cx.tcx), span, ty)
}
}

impl<'tcx> FunctionCx<'_, '_, 'tcx> {
pub(crate) fn monomorphize<T>(&self, value: T) -> T
where
Expand Down Expand Up @@ -364,22 +365,6 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {

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

impl<'tcx> LayoutOf<'tcx> for RevealAllLayoutCx<'tcx> {
type Ty = Ty<'tcx>;
type TyAndLayout = TyAndLayout<'tcx>;

fn layout_of(&self, ty: Ty<'tcx>) -> TyAndLayout<'tcx> {
assert!(!ty.still_further_specializable());
self.0.layout_of(ParamEnv::reveal_all().and(&ty)).unwrap_or_else(|e| {
if let layout::LayoutError::SizeOverflow(_) = e {
self.0.sess.fatal(&e.to_string())
} else {
bug!("failed to get layout for `{}`: {}", ty, e)
}
})
}
}

impl<'tcx> layout::HasTyCtxt<'tcx> for RevealAllLayoutCx<'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'tcx> {
self.0
Expand All @@ -403,3 +388,16 @@ impl<'tcx> HasTargetSpec for RevealAllLayoutCx<'tcx> {
&self.0.sess.target
}
}

impl<'tcx> ty::layout::IsLayoutCx<'tcx> for RevealAllLayoutCx<'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;

#[inline]
fn map_err_for_layout_of(err: LayoutError<'tcx>, cx: &Self, span: Span, ty: Ty<'tcx>) -> ! {
if let layout::LayoutError::SizeOverflow(_) = err {
cx.0.sess.span_fatal(span, &err.to_string())
} else {
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
return None;
}
let const_val = mir_operand_get_const_val(fx, operand)?;
if fx.layout_of(ty).size
if fx.layout_of(*ty).size
!= const_val.try_to_scalar_int()?.size()
{
return None;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_cranelift/src/value_and_place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ impl<'tcx> CPlace<'tcx> {
fx: &mut FunctionCx<'_, '_, 'tcx>,
index: Value,
) -> CPlace<'tcx> {
let (elem_layout, ptr) = match self.layout().ty.kind() {
let (elem_layout, ptr) = match *self.layout().ty.kind() {
ty::Array(elem_ty, _) => (fx.layout_of(elem_ty), self.to_ptr()),
ty::Slice(elem_ty) => (fx.layout_of(elem_ty), self.to_ptr_maybe_unsized().0),
_ => bug!("place_index({:?})", self.layout().ty),
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::MemFlags;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::ty::layout::{LayoutError, TyAndLayout};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;
use rustc_target::abi::{self, Align, Size};
Expand Down Expand Up @@ -88,12 +88,12 @@ impl HasTargetSpec for Builder<'_, '_, 'tcx> {
}
}

impl abi::LayoutOf<'tcx> for Builder<'_, '_, 'tcx> {
type Ty = Ty<'tcx>;
type TyAndLayout = TyAndLayout<'tcx>;
impl ty::layout::IsLayoutCx<'tcx> for Builder<'_, '_, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;

fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
self.cx.layout_of(ty)
#[inline]
fn map_err_for_layout_of(err: LayoutError<'tcx>, bx: &Self, span: Span, ty: Ty<'tcx>) -> ! {
CodegenCx::map_err_for_layout_of(err, bx.cx, span, ty)
}
}

Expand Down
38 changes: 16 additions & 22 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ use rustc_codegen_ssa::traits::*;
use rustc_data_structures::base_n;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_middle::bug;
use rustc_middle::mir::mono::CodegenUnit;
use rustc_middle::ty::layout::{HasParamEnv, LayoutError, TyAndLayout};
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::config::{CFGuard, CrateType, DebugInfo};
use rustc_session::Session;
use rustc_span::source_map::{Span, DUMMY_SP};
use rustc_span::source_map::Span;
use rustc_span::symbol::Symbol;
use rustc_target::abi::{HasDataLayout, LayoutOf, PointeeInfo, Size, TargetDataLayout, VariantIdx};
use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
use rustc_target::spec::{HasTargetSpec, RelocModel, Target, TlsModel};
use smallvec::SmallVec;

Expand Down Expand Up @@ -835,27 +835,21 @@ impl ty::layout::HasTyCtxt<'tcx> for CodegenCx<'ll, 'tcx> {
}
}

impl LayoutOf<'tcx> for CodegenCx<'ll, 'tcx> {
type Ty = Ty<'tcx>;
type TyAndLayout = TyAndLayout<'tcx>;

fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
self.spanned_layout_of(ty, DUMMY_SP)
}

fn spanned_layout_of(&self, ty: Ty<'tcx>, span: Span) -> Self::TyAndLayout {
self.tcx.layout_of(ty::ParamEnv::reveal_all().and(ty)).unwrap_or_else(|e| {
if let LayoutError::SizeOverflow(_) = e {
self.sess().span_fatal(span, &e.to_string())
} else {
bug!("failed to get layout for `{}`: {}", ty, e)
}
})
}
}

impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> {
fn param_env(&self) -> ty::ParamEnv<'tcx> {
ty::ParamEnv::reveal_all()
}
}

impl ty::layout::IsLayoutCx<'tcx> for CodegenCx<'ll, 'tcx> {
type LayoutOfResult = TyAndLayout<'tcx>;

#[inline]
fn map_err_for_layout_of(err: LayoutError<'tcx>, cx: &Self, span: Span, ty: Ty<'tcx>) -> ! {
if let LayoutError::SizeOverflow(_) = err {
cx.sess().span_fatal(span, &err.to_string())
} else {
span_bug!(span, "failed to get layout for `{}`: {}", ty, err)
}
}
}
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
let t = arg.layout.ty;
let t = match t.kind() {
ty::Array(ct, _)
if (*ct == cx.tcx.types.u8) || cx.layout_of(ct).is_zst() =>
if (*ct == cx.tcx.types.u8) || cx.layout_of(*ct).is_zst() =>
{
cx.tcx.mk_imm_ptr(ct)
}
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_codegen_ssa/src/traits/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,12 @@ use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::{
config::{self, OutputFilenames, PrintRequest},
Session,
};
use rustc_span::symbol::Symbol;
use rustc_target::abi::LayoutOf;
use rustc_target::spec::Target;

pub use rustc_data_structures::sync::MetadataRef;
Expand All @@ -42,14 +41,14 @@ pub trait Backend<'tcx>:
Sized
+ BackendTypes
+ HasTyCtxt<'tcx>
+ LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
+ ty::layout::IsLayoutCx<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
{
}

impl<'tcx, T> Backend<'tcx> for T where
Self: BackendTypes
+ HasTyCtxt<'tcx>
+ LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>>
+ ty::layout::IsLayoutCx<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
{
}

Expand Down
5 changes: 5 additions & 0 deletions compiler/rustc_codegen_ssa/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ pub use self::type_::{
};
pub use self::write::{ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};

// HACK(eddyb) this means that `traits::*` imports will also import `LayoutOf`,
// which wasn't needed previously because `Backend` itself having `LayoutOf` as
// a supertrait meant that methods from `LayoutOf` were always available.
pub use rustc_target::abi::LayoutOf as _;

use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt};
use rustc_target::spec::HasTargetSpec;

Expand Down
25 changes: 13 additions & 12 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2830,18 +2830,19 @@ impl ClashingExternDeclarations {
let a_kind = a.kind();
let b_kind = b.kind();

let compare_layouts = |a, b| -> Result<bool, LayoutError<'tcx>> {
debug!("compare_layouts({:?}, {:?})", a, b);
let a_layout = &cx.layout_of(a)?.layout.abi;
let b_layout = &cx.layout_of(b)?.layout.abi;
debug!(
"comparing layouts: {:?} == {:?} = {}",
a_layout,
b_layout,
a_layout == b_layout
);
Ok(a_layout == b_layout)
};
let compare_layouts =
|a: Ty<'tcx>, b: Ty<'tcx>| -> Result<bool, LayoutError<'tcx>> {
debug!("compare_layouts({:?}, {:?})", a, b);
let a_layout = &cx.layout_of(a)?.layout.abi;
let b_layout = &cx.layout_of(b)?.layout.abi;
debug!(
"comparing layouts: {:?} == {:?} = {}",
a_layout,
b_layout,
a_layout == b_layout
);
Ok(a_layout == b_layout)
};

#[allow(rustc::usage_of_ty_tykind)]
let is_primitive_or_pointer = |kind: &ty::TyKind<'_>| {
Expand Down
17 changes: 11 additions & 6 deletions compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use rustc_session::Session;
use rustc_session::SessionLintStore;
use rustc_span::lev_distance::find_best_match_for_name;
use rustc_span::{symbol::Symbol, MultiSpan, Span, DUMMY_SP};
use rustc_target::abi::{self, LayoutOf};
use rustc_target::abi;
use tracing::debug;

use std::cell::Cell;
Expand Down Expand Up @@ -1080,12 +1080,17 @@ impl<'tcx> ty::layout::HasParamEnv<'tcx> for LateContext<'tcx> {
}
}

impl<'tcx> LayoutOf<'tcx> for LateContext<'tcx> {
type Ty = Ty<'tcx>;
type TyAndLayout = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;
impl<'tcx> ty::layout::IsLayoutCx<'tcx> for LateContext<'tcx> {
type LayoutOfResult = Result<TyAndLayout<'tcx>, LayoutError<'tcx>>;

fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyAndLayout {
self.tcx.layout_of(self.param_env.and(ty))
#[inline]
fn map_err_for_layout_of(
err: LayoutError<'tcx>,
_cx: &Self,
_span: Span,
_ty: Ty<'tcx>,
) -> LayoutError<'tcx> {
err
}
}

Expand Down
Loading