diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 892ccf27f6df8..03f462a63b31b 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -256,7 +256,7 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> { pub(crate) inline_asm_index: u32, } -impl<'tcx> LayoutOf for FunctionCx<'_, '_, 'tcx> { +impl<'tcx> LayoutOf<'tcx> for FunctionCx<'_, '_, 'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = TyAndLayout<'tcx>; @@ -364,7 +364,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> { pub(crate) struct RevealAllLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>); -impl<'tcx> LayoutOf for RevealAllLayoutCx<'tcx> { +impl<'tcx> LayoutOf<'tcx> for RevealAllLayoutCx<'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = TyAndLayout<'tcx>; diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs index c471da83de234..95216f1c3d787 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/mod.rs @@ -160,12 +160,10 @@ impl<'tcx> DebugContext<'tcx> { for (field_idx, field_def) in variant.fields.iter().enumerate() { let field_offset = layout.fields.offset(field_idx); - let field_layout = layout - .field( - &layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() }, - field_idx, - ) - .unwrap(); + let field_layout = layout.field( + &layout::LayoutCx { tcx: self.tcx, param_env: ParamEnv::reveal_all() }, + field_idx, + ); let field_type = self.dwarf_ty(field_layout.ty); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs index 1c4d307fc50e1..12f61e0c564aa 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs @@ -789,7 +789,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( return; } - if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true).unwrap() { + if intrinsic == sym::assert_zero_valid && !layout.might_permit_raw_init(fx, /*zero:*/ true) { with_no_trimmed_paths(|| crate::base::codegen_panic( fx, &format!("attempted to zero-initialize type `{}`, which is invalid", T), @@ -798,7 +798,7 @@ pub(crate) fn codegen_intrinsic_call<'tcx>( return; } - if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false).unwrap() { + if intrinsic == sym::assert_uninit_valid && !layout.might_permit_raw_init(fx, /*zero:*/ false) { with_no_trimmed_paths(|| crate::base::codegen_panic( fx, &format!("attempted to leave type `{}` uninitialized, which is invalid", T), diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 13538683e05af..47529f719b514 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -88,7 +88,7 @@ impl HasTargetSpec for Builder<'_, '_, 'tcx> { } } -impl abi::LayoutOf for Builder<'_, '_, 'tcx> { +impl abi::LayoutOf<'tcx> for Builder<'_, '_, 'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = TyAndLayout<'tcx>; diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 35c866d48a41b..45da18d4a24f3 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -835,7 +835,7 @@ impl ty::layout::HasTyCtxt<'tcx> for CodegenCx<'ll, 'tcx> { } } -impl LayoutOf for CodegenCx<'ll, 'tcx> { +impl LayoutOf<'tcx> for CodegenCx<'ll, 'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = TyAndLayout<'tcx>; diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 85efe3e64836c..9818905464dce 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -9,7 +9,7 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Ty, TypeFoldable}; use rustc_target::abi::{Abi, AddressSpace, Align, FieldsShape}; use rustc_target::abi::{Int, Pointer, F32, F64}; -use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAndLayoutMethods, Variants}; +use rustc_target::abi::{LayoutOf, PointeeInfo, Scalar, Size, TyAbiInterface, Variants}; use smallvec::{smallvec, SmallVec}; use tracing::debug; @@ -393,12 +393,15 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { } } + // FIXME(eddyb) this having the same name as `TyAndLayout::pointee_info_at` + // (the inherent method, which is lacking this caching logic) can result in + // the uncached version being called - not wrong, but potentially inefficient. fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size) -> Option { if let Some(&pointee) = cx.pointee_infos.borrow().get(&(self.ty, offset)) { return pointee; } - let result = Ty::pointee_info_at(*self, cx, offset); + let result = Ty::ty_and_layout_pointee_info_at(*self, cx, offset); cx.pointee_infos.borrow_mut().insert((self.ty, offset), result); result diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 673d348a2a89c..2a76ad0fb1356 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -472,10 +472,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let layout = bx.layout_of(ty); let do_panic = match intrinsic { Inhabited => layout.abi.is_uninhabited(), - // We unwrap as the error type is `!`. - ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true).unwrap(), - // We unwrap as the error type is `!`. - UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false).unwrap(), + ZeroValid => !layout.might_permit_raw_init(bx, /*zero:*/ true), + UninitValid => !layout.might_permit_raw_init(bx, /*zero:*/ false), }; if do_panic { let msg_str = with_no_trimmed_paths(|| { diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs index dc4146ec7b58d..1393fc71d6bc3 100644 --- a/compiler/rustc_codegen_ssa/src/traits/backend.rs +++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs @@ -39,12 +39,17 @@ pub trait BackendTypes { } pub trait Backend<'tcx>: - Sized + BackendTypes + HasTyCtxt<'tcx> + LayoutOf, TyAndLayout = TyAndLayout<'tcx>> + Sized + + BackendTypes + + HasTyCtxt<'tcx> + + LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>> { } impl<'tcx, T> Backend<'tcx> for T where - Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf, TyAndLayout = TyAndLayout<'tcx>> + Self: BackendTypes + + HasTyCtxt<'tcx> + + LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>> { } diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index c2a46e997df47..7dbc3d60439c4 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -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::LayoutOf; +use rustc_target::abi::{self, LayoutOf}; use tracing::debug; use std::cell::Cell; @@ -1059,7 +1059,28 @@ impl<'tcx> LateContext<'tcx> { } } -impl<'tcx> LayoutOf for LateContext<'tcx> { +impl<'tcx> abi::HasDataLayout for LateContext<'tcx> { + #[inline] + fn data_layout(&self) -> &abi::TargetDataLayout { + &self.tcx.data_layout + } +} + +impl<'tcx> ty::layout::HasTyCtxt<'tcx> for LateContext<'tcx> { + #[inline] + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } +} + +impl<'tcx> ty::layout::HasParamEnv<'tcx> for LateContext<'tcx> { + #[inline] + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.param_env + } +} + +impl<'tcx> LayoutOf<'tcx> for LateContext<'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = Result, LayoutError<'tcx>>; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 5068ace58b466..5e5902abe662f 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -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(); @@ -2034,6 +2030,20 @@ impl<'tcx> HasTyCtxt<'tcx> for TyCtxt<'tcx> { } } +impl<'tcx> HasDataLayout for ty::query::TyCtxtAt<'tcx> { + #[inline] + fn data_layout(&self) -> &TargetDataLayout { + &self.data_layout + } +} + +impl<'tcx> HasTyCtxt<'tcx> for ty::query::TyCtxtAt<'tcx> { + #[inline] + fn tcx(&self) -> TyCtxt<'tcx> { + **self + } +} + impl<'tcx, C> HasParamEnv<'tcx> for LayoutCx<'tcx, C> { fn param_env(&self) -> ty::ParamEnv<'tcx> { self.param_env @@ -2054,7 +2064,7 @@ impl<'tcx, T: HasTyCtxt<'tcx>> HasTyCtxt<'tcx> for LayoutCx<'tcx, T> { pub type TyAndLayout<'tcx> = rustc_target::abi::TyAndLayout<'tcx, Ty<'tcx>>; -impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> { +impl LayoutOf<'tcx> for LayoutCx<'tcx, TyCtxt<'tcx>> { type Ty = Ty<'tcx>; type TyAndLayout = Result, LayoutError<'tcx>>; @@ -2066,7 +2076,7 @@ impl<'tcx> LayoutOf for LayoutCx<'tcx, TyCtxt<'tcx>> { } } -impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { +impl LayoutOf<'tcx> for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { type Ty = Ty<'tcx>; type TyAndLayout = Result, LayoutError<'tcx>>; @@ -2078,13 +2088,11 @@ impl LayoutOf for LayoutCx<'tcx, ty::query::TyCtxtAt<'tcx>> { } } -impl<'tcx, C> TyAndLayoutMethods<'tcx, C> for Ty<'tcx> +impl<'tcx, C> TyAbiInterface<'tcx, C> for Ty<'tcx> where - C: LayoutOf, TyAndLayout: MaybeResult>> - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>, + C: HasTyCtxt<'tcx> + HasParamEnv<'tcx>, { - fn for_variant( + fn ty_and_layout_for_variant( this: TyAndLayout<'tcx>, cx: &C, variant_index: VariantIdx, @@ -2101,8 +2109,11 @@ where } Variants::Single { index } => { + let tcx = cx.tcx(); + let param_env = cx.param_env(); + // Deny calling for_variant more than once for non-Single enums. - if let Ok(original_layout) = cx.layout_of(this.ty).to_result() { + if let Ok(original_layout) = tcx.layout_of(param_env.and(this.ty)) { assert_eq!(original_layout.variants, Variants::Single { index }); } @@ -2112,7 +2123,6 @@ where ty::Adt(def, _) => def.variants[variant_index].fields.len(), _ => bug!(), }; - let tcx = cx.tcx(); tcx.intern_layout(Layout { variants: Variants::Single { index: variant_index }, fields: match NonZeroUsize::new(fields) { @@ -2134,32 +2144,24 @@ where TyAndLayout { ty: this.ty, layout } } - fn field(this: TyAndLayout<'tcx>, cx: &C, i: usize) -> C::TyAndLayout { - enum TyMaybeWithLayout { - 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, TyAndLayout: MaybeResult>> - + 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 { + ) -> 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(_) @@ -2170,7 +2172,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, .. }) => { @@ -2182,17 +2184,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() { @@ -2216,7 +2220,7 @@ where ]) */ } - _ => bug!("TyAndLayout::field_type({:?}): not applicable", this), + _ => bug!("TyAndLayout::field({:?}): not applicable", this), } } @@ -2225,9 +2229,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( @@ -2270,24 +2276,42 @@ 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 pointee_info_at(this: TyAndLayout<'tcx>, cx: &C, offset: Size) -> Option { + fn ty_and_layout_pointee_info_at( + this: TyAndLayout<'tcx>, + cx: &C, + offset: Size, + ) -> Option { + let tcx = cx.tcx(); + let param_env = cx.param_env(); + let addr_space_of_ty = |ty: Ty<'tcx>| { if ty.is_fn() { cx.data_layout().instruction_address_space } else { AddressSpace::DATA } }; let pointee_info = match *this.ty.kind() { ty::RawPtr(mt) if offset.bytes() == 0 => { - cx.layout_of(mt.ty).to_result().ok().map(|layout| PointeeInfo { + tcx.layout_of(param_env.and(mt.ty)).ok().map(|layout| PointeeInfo { size: layout.size, align: layout.align.abi, safe: None, @@ -2295,18 +2319,15 @@ where }) } ty::FnPtr(fn_sig) if offset.bytes() == 0 => { - cx.layout_of(cx.tcx().mk_fn_ptr(fn_sig)).to_result().ok().map(|layout| { - PointeeInfo { - size: layout.size, - align: layout.align.abi, - safe: None, - address_space: cx.data_layout().instruction_address_space, - } + tcx.layout_of(param_env.and(tcx.mk_fn_ptr(fn_sig))).ok().map(|layout| PointeeInfo { + size: layout.size, + align: layout.align.abi, + safe: None, + address_space: cx.data_layout().instruction_address_space, }) } ty::Ref(_, ty, mt) if offset.bytes() == 0 => { let address_space = addr_space_of_ty(ty); - let tcx = cx.tcx(); let kind = if tcx.sess.opts.optimize == OptLevel::No { // Use conservative pointer kind if not optimizing. This saves us the // Freeze/Unpin queries, and can save time in the codegen backend (noalias @@ -2335,7 +2356,7 @@ where } }; - cx.layout_of(ty).to_result().ok().map(|layout| PointeeInfo { + tcx.layout_of(param_env.and(ty)).ok().map(|layout| PointeeInfo { size: layout.size, align: layout.align.abi, safe: Some(kind), @@ -2538,7 +2559,7 @@ impl<'tcx> ty::Instance<'tcx> { pub trait FnAbiExt<'tcx, C> where - C: LayoutOf, TyAndLayout = TyAndLayout<'tcx>> + C: LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>> + HasDataLayout + HasTargetSpec + HasTyCtxt<'tcx> @@ -2725,7 +2746,7 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { impl<'tcx, C> FnAbiExt<'tcx, C> for call::FnAbi<'tcx, Ty<'tcx>> where - C: LayoutOf, TyAndLayout = TyAndLayout<'tcx>> + C: LayoutOf<'tcx, Ty = Ty<'tcx>, TyAndLayout = TyAndLayout<'tcx>> + HasDataLayout + HasTargetSpec + HasTyCtxt<'tcx> @@ -3004,16 +3025,15 @@ where } } -fn make_thin_self_ptr<'tcx, C>(cx: &C, mut layout: TyAndLayout<'tcx>) -> TyAndLayout<'tcx> -where - C: LayoutOf, TyAndLayout = TyAndLayout<'tcx>> - + HasTyCtxt<'tcx> - + HasParamEnv<'tcx>, -{ +fn make_thin_self_ptr<'tcx>( + cx: &(impl HasTyCtxt<'tcx> + HasParamEnv<'tcx>), + layout: TyAndLayout<'tcx>, +) -> TyAndLayout<'tcx> { + let tcx = cx.tcx(); let fat_pointer_ty = if layout.is_unsized() { // unsized `self` is passed as a pointer to `self` // FIXME (mikeyhew) change this to use &own if it is ever added to the language - cx.tcx().mk_mut_ptr(layout.ty) + tcx.mk_mut_ptr(layout.ty) } else { match layout.abi { Abi::ScalarPair(..) => (), @@ -3047,8 +3067,13 @@ where // we now have a type like `*mut RcBox` // change its layout to that of `*mut ()`, a thin pointer, but keep the same type // this is understood as a special case elsewhere in the compiler - let unit_pointer_ty = cx.tcx().mk_mut_ptr(cx.tcx().mk_unit()); - layout = cx.layout_of(unit_pointer_ty); - layout.ty = fat_pointer_ty; - layout + let unit_ptr_ty = tcx.mk_mut_ptr(tcx.mk_unit()); + + TyAndLayout { + ty: fat_pointer_ty, + + // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing the `Result` + // should always work because the type is always `*mut ()`. + ..tcx.layout_of(ty::ParamEnv::reveal_all().and(unit_ptr_ty)).unwrap() + } } diff --git a/compiler/rustc_mir/src/interpret/cast.rs b/compiler/rustc_mir/src/interpret/cast.rs index 697e98311e2d3..6f18009cf4730 100644 --- a/compiler/rustc_mir/src/interpret/cast.rs +++ b/compiler/rustc_mir/src/interpret/cast.rs @@ -340,7 +340,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Example: `Arc` -> `Arc` // here we need to increase the size of every &T thin ptr field to a fat ptr for i in 0..src.layout.fields.count() { - let cast_ty_field = cast_ty.field(self, i)?; + let cast_ty_field = cast_ty.field(self, i); if cast_ty_field.is_zst() { continue; } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index 516ef4f4e53ca..bfb3de04c59fb 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -312,7 +312,7 @@ where } } -impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOf for InterpCx<'mir, 'tcx, M> { +impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> LayoutOf<'tcx> for InterpCx<'mir, 'tcx, M> { type Ty = Ty<'tcx>; type TyAndLayout = InterpResult<'tcx, TyAndLayout<'tcx>>; @@ -592,7 +592,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Recurse to get the size of the dynamically sized field (must be // the last field). Can't have foreign types here, how would we // adjust alignment and size for them? - let field = layout.field(self, layout.fields.count() - 1)?; + let field = layout.field(self, layout.fields.count() - 1); let (unsized_size, unsized_align) = match self.size_and_align_of(metadata, &field)? { Some(size_and_align) => size_and_align, @@ -645,7 +645,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ty::Slice(_) | ty::Str => { let len = metadata.unwrap_meta().to_machine_usize(self)?; - let elem = layout.field(self, 0)?; + let elem = layout.field(self, 0); // Make sure the slice is not too big. let size = elem.size.checked_mul(len, self).ok_or_else(|| { diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs index 403dc1b4793d0..4afce2b6b80f2 100644 --- a/compiler/rustc_mir/src/interpret/operand.rs +++ b/compiler/rustc_mir/src/interpret/operand.rs @@ -364,7 +364,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Err(value) => value, }; - let field_layout = op.layout.field(self, field)?; + let field_layout = op.layout.field(self, field); if field_layout.is_zst() { let immediate = Scalar::ZST.into(); return Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout }); diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs index 91fcc3495b1c1..afad9716b3fe1 100644 --- a/compiler/rustc_mir/src/interpret/place.rs +++ b/compiler/rustc_mir/src/interpret/place.rs @@ -355,7 +355,7 @@ where field: usize, ) -> InterpResult<'tcx, MPlaceTy<'tcx, M::PointerTag>> { let offset = base.layout.fields.offset(field); - let field_layout = base.layout.field(self, field)?; + let field_layout = base.layout.field(self, field); // Offset may need adjustment for unsized fields. let (meta, offset) = if field_layout.is_unsized() { @@ -405,7 +405,7 @@ where } let offset = stride * index; // `Size` multiplication // All fields have the same layout. - let field_layout = base.layout.field(self, 0)?; + let field_layout = base.layout.field(self, 0); assert!(!field_layout.is_unsized()); base.offset(offset, MemPlaceMeta::None, field_layout, self) @@ -430,7 +430,7 @@ where FieldsShape::Array { stride, .. } => stride, _ => span_bug!(self.cur_span(), "mplace_array_fields: expected an array layout"), }; - let layout = base.layout.field(self, 0)?; + let layout = base.layout.field(self, 0); let dl = &self.tcx.data_layout; // `Size` multiplication Ok((0..len).map(move |i| base.offset(stride * i, MemPlaceMeta::None, layout, dl))) diff --git a/compiler/rustc_mir/src/interpret/terminator.rs b/compiler/rustc_mir/src/interpret/terminator.rs index d87aa4a6267ec..63496045e0d73 100644 --- a/compiler/rustc_mir/src/interpret/terminator.rs +++ b/compiler/rustc_mir/src/interpret/terminator.rs @@ -461,7 +461,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // a thin pointer. assert!(receiver_place.layout.is_unsized()); let receiver_ptr_ty = self.tcx.mk_mut_ptr(receiver_place.layout.ty); - let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0)?; + let this_receiver_ptr = self.layout_of(receiver_ptr_ty)?.field(self, 0); // Adjust receiver argument. args[0] = OpTy::from(ImmTy::from_immediate( Scalar::from_maybe_pointer(receiver_place.ptr, self).into(), diff --git a/compiler/rustc_mir/src/transform/const_prop.rs b/compiler/rustc_mir/src/transform/const_prop.rs index 1932cd5de29b5..5c51aa4ed679b 100644 --- a/compiler/rustc_mir/src/transform/const_prop.rs +++ b/compiler/rustc_mir/src/transform/const_prop.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::{ Location, Operand, Place, Rvalue, SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE, }; -use rustc_middle::ty::layout::{HasTyCtxt, LayoutError, TyAndLayout}; +use rustc_middle::ty::layout::{LayoutError, TyAndLayout}; use rustc_middle::ty::subst::{InternalSubsts, Subst}; use rustc_middle::ty::{ self, ConstInt, ConstKind, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, TypeFoldable, @@ -330,7 +330,7 @@ struct ConstPropagator<'mir, 'tcx> { source_info: Option, } -impl<'mir, 'tcx> LayoutOf for ConstPropagator<'mir, 'tcx> { +impl<'mir, 'tcx> LayoutOf<'tcx> for ConstPropagator<'mir, 'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = Result, LayoutError<'tcx>>; @@ -346,13 +346,20 @@ impl<'mir, 'tcx> HasDataLayout for ConstPropagator<'mir, 'tcx> { } } -impl<'mir, 'tcx> HasTyCtxt<'tcx> for ConstPropagator<'mir, 'tcx> { +impl<'mir, 'tcx> ty::layout::HasTyCtxt<'tcx> for ConstPropagator<'mir, 'tcx> { #[inline] fn tcx(&self) -> TyCtxt<'tcx> { self.tcx } } +impl<'mir, 'tcx> ty::layout::HasParamEnv<'tcx> for ConstPropagator<'mir, 'tcx> { + #[inline] + fn param_env(&self) -> ty::ParamEnv<'tcx> { + self.param_env + } +} + impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn new( body: &Body<'tcx>, diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs index 43a3a3062e77b..64ea4ee570e82 100644 --- a/compiler/rustc_passes/src/layout_test.rs +++ b/compiler/rustc_passes/src/layout_test.rs @@ -113,7 +113,7 @@ struct UnwrapLayoutCx<'tcx> { param_env: ParamEnv<'tcx>, } -impl LayoutOf for UnwrapLayoutCx<'tcx> { +impl LayoutOf<'tcx> for UnwrapLayoutCx<'tcx> { type Ty = Ty<'tcx>; type TyAndLayout = TyAndLayout<'tcx>; diff --git a/compiler/rustc_target/src/abi/call/aarch64.rs b/compiler/rustc_target/src/abi/call/aarch64.rs index a5e985d471271..4613a459c51d6 100644 --- a/compiler/rustc_target/src/abi/call/aarch64.rs +++ b/compiler/rustc_target/src/abi/call/aarch64.rs @@ -1,10 +1,10 @@ use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform}; -use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{HasDataLayout, TyAbiInterface}; fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { let size = arg.layout.size; @@ -26,8 +26,8 @@ where fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); @@ -48,8 +48,8 @@ where fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); @@ -70,8 +70,8 @@ where pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !fn_abi.ret.is_ignore() { classify_ret(cx, &mut fn_abi.ret); diff --git a/compiler/rustc_target/src/abi/call/amdgpu.rs b/compiler/rustc_target/src/abi/call/amdgpu.rs index 0b4f279fece40..9be97476ce8f0 100644 --- a/compiler/rustc_target/src/abi/call/amdgpu.rs +++ b/compiler/rustc_target/src/abi/call/amdgpu.rs @@ -1,26 +1,26 @@ use crate::abi::call::{ArgAbi, FnAbi}; -use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{HasDataLayout, TyAbiInterface}; fn classify_ret<'a, Ty, C>(_cx: &C, ret: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { ret.extend_integer_width_to(32); } fn classify_arg<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { arg.extend_integer_width_to(32); } pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !fn_abi.ret.is_ignore() { classify_ret(cx, &mut fn_abi.ret); diff --git a/compiler/rustc_target/src/abi/call/arm.rs b/compiler/rustc_target/src/abi/call/arm.rs index b560e11fe1c5e..e66c2132b8677 100644 --- a/compiler/rustc_target/src/abi/call/arm.rs +++ b/compiler/rustc_target/src/abi/call/arm.rs @@ -1,11 +1,11 @@ use crate::abi::call::{ArgAbi, Conv, FnAbi, Reg, RegKind, Uniform}; -use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{HasDataLayout, TyAbiInterface}; use crate::spec::HasTargetSpec; fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { let size = arg.layout.size; @@ -27,8 +27,8 @@ where fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, vfp: bool) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); @@ -53,8 +53,8 @@ where fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, vfp: bool) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !arg.layout.is_aggregate() { arg.extend_integer_width_to(32); @@ -75,8 +75,8 @@ where pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout + HasTargetSpec, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, { // If this is a target with a hard-float ABI, and the function is not explicitly // `extern "aapcs"`, then we must use the VFP registers for homogeneous aggregates. diff --git a/compiler/rustc_target/src/abi/call/mips.rs b/compiler/rustc_target/src/abi/call/mips.rs index 733a7328bd3a0..cc443197680e4 100644 --- a/compiler/rustc_target/src/abi/call/mips.rs +++ b/compiler/rustc_target/src/abi/call/mips.rs @@ -1,10 +1,9 @@ use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform}; -use crate::abi::{HasDataLayout, LayoutOf, Size, TyAndLayoutMethods}; +use crate::abi::{HasDataLayout, Size}; -fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size) +fn classify_ret(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size) where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf + HasDataLayout, + C: HasDataLayout, { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); @@ -14,10 +13,9 @@ where } } -fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size) +fn classify_arg(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size) where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf + HasDataLayout, + C: HasDataLayout, { let dl = cx.data_layout(); let size = arg.layout.size; @@ -35,10 +33,9 @@ where *offset = offset.align_to(align) + size.align_to(align); } -pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>) +pub fn compute_abi_info(cx: &C, fn_abi: &mut FnAbi<'_, Ty>) where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf + HasDataLayout, + C: HasDataLayout, { let mut offset = Size::ZERO; if !fn_abi.ret.is_ignore() { diff --git a/compiler/rustc_target/src/abi/call/mips64.rs b/compiler/rustc_target/src/abi/call/mips64.rs index a630c84142b4d..28ca93c46921e 100644 --- a/compiler/rustc_target/src/abi/call/mips64.rs +++ b/compiler/rustc_target/src/abi/call/mips64.rs @@ -1,5 +1,5 @@ use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform}; -use crate::abi::{self, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{self, HasDataLayout, Size, TyAbiInterface}; fn extend_integer_width_mips(arg: &mut ArgAbi<'_, Ty>, bits: u64) { // Always sign extend u32 values on 64-bit mips @@ -19,8 +19,8 @@ fn extend_integer_width_mips(arg: &mut ArgAbi<'_, Ty>, bits: u64) { fn float_reg<'a, Ty, C>(cx: &C, ret: &ArgAbi<'a, Ty>, i: usize) -> Option where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { match ret.layout.field(cx, i).abi { abi::Abi::Scalar(ref scalar) => match scalar.value { @@ -34,8 +34,8 @@ where fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !ret.layout.is_aggregate() { extend_integer_width_mips(ret, 64); @@ -74,8 +74,8 @@ where fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !arg.layout.is_aggregate() { extend_integer_width_mips(arg, 64); @@ -144,8 +144,8 @@ where pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !fn_abi.ret.is_ignore() { classify_ret(cx, &mut fn_abi.ret); diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 6e0e140374033..6d3c731809107 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -1,5 +1,5 @@ use crate::abi::{self, Abi, Align, FieldsShape, Size}; -use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout}; use crate::spec::{self, HasTargetSpec}; mod aarch64; @@ -316,8 +316,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// specific targets. pub fn homogeneous_aggregate(&self, cx: &C) -> Result where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf, + Ty: TyAbiInterface<'a, C> + Copy, { match self.abi { Abi::Uninhabited => Err(Heterogeneous), @@ -603,8 +602,8 @@ pub struct FnAbi<'a, Ty> { impl<'a, Ty> FnAbi<'a, Ty> { pub fn adjust_for_cabi(&mut self, cx: &C, abi: spec::abi::Abi) -> Result<(), String> where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout + HasTargetSpec, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, { if abi == spec::abi::Abi::X86Interrupt { if let Some(arg) = self.args.first_mut() { diff --git a/compiler/rustc_target/src/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs index 8c2a9d09a3d9a..c22ef9c8f2a7f 100644 --- a/compiler/rustc_target/src/abi/call/powerpc64.rs +++ b/compiler/rustc_target/src/abi/call/powerpc64.rs @@ -3,7 +3,7 @@ // need to be fixed when PowerPC vector support is added. use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform}; -use crate::abi::{Endian, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{Endian, HasDataLayout, TyAbiInterface}; use crate::spec::HasTargetSpec; #[derive(Debug, Clone, Copy, PartialEq)] @@ -19,8 +19,8 @@ fn is_homogeneous_aggregate<'a, Ty, C>( abi: ABI, ) -> Option where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { // ELFv1 only passes one-member aggregates transparently. @@ -43,8 +43,8 @@ where fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, abi: ABI) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(64); @@ -86,8 +86,8 @@ where fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, abi: ABI) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); @@ -116,8 +116,8 @@ where pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout + HasTargetSpec, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, { let abi = if cx.target_spec().env == "musl" { ELFv2 diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs index 1ab881dd13d1c..8c2ef8c7a017d 100644 --- a/compiler/rustc_target/src/abi/call/riscv.rs +++ b/compiler/rustc_target/src/abi/call/riscv.rs @@ -5,9 +5,7 @@ // https://github.com/llvm/llvm-project/blob/8e780252a7284be45cf1ba224cabd884847e8e92/clang/lib/CodeGen/TargetInfo.cpp#L9311-L9773 use crate::abi::call::{ArgAbi, ArgExtension, CastTarget, FnAbi, PassMode, Reg, RegKind, Uniform}; -use crate::abi::{ - self, Abi, FieldsShape, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods, -}; +use crate::abi::{self, Abi, FieldsShape, HasDataLayout, Size, TyAbiInterface, TyAndLayout}; use crate::spec::HasTargetSpec; #[derive(Copy, Clone)] @@ -43,8 +41,7 @@ fn should_use_fp_conv_helper<'a, Ty, C>( field2_kind: &mut RegPassKind, ) -> Result<(), CannotUseFpConv> where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf>, + Ty: TyAbiInterface<'a, C> + Copy, { match arg_layout.abi { Abi::Scalar(ref scalar) => match scalar.value { @@ -130,8 +127,7 @@ fn should_use_fp_conv<'a, Ty, C>( flen: u64, ) -> Option where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf>, + Ty: TyAbiInterface<'a, C> + Copy, { let mut field1_kind = RegPassKind::Unknown; let mut field2_kind = RegPassKind::Unknown; @@ -149,8 +145,7 @@ where fn classify_ret<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, xlen: u64, flen: u64) -> bool where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf>, + Ty: TyAbiInterface<'a, C> + Copy, { if let Some(conv) = should_use_fp_conv(cx, &arg.layout, xlen, flen) { match conv { @@ -212,8 +207,7 @@ fn classify_arg<'a, Ty, C>( avail_gprs: &mut u64, avail_fprs: &mut u64, ) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf>, + Ty: TyAbiInterface<'a, C> + Copy, { if !is_vararg { match should_use_fp_conv(cx, &arg.layout, xlen, flen) { @@ -320,8 +314,8 @@ fn extend_integer_width<'a, Ty>(arg: &mut ArgAbi<'a, Ty>, xlen: u64) { pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout + HasTargetSpec, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, { let flen = match &cx.target_spec().llvm_abiname[..] { "ilp32f" | "lp64f" => 32, diff --git a/compiler/rustc_target/src/abi/call/s390x.rs b/compiler/rustc_target/src/abi/call/s390x.rs index 005dcc62dfdc1..594108925de80 100644 --- a/compiler/rustc_target/src/abi/call/s390x.rs +++ b/compiler/rustc_target/src/abi/call/s390x.rs @@ -2,13 +2,9 @@ // for a pre-z13 machine or using -mno-vx. use crate::abi::call::{ArgAbi, FnAbi, Reg}; -use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{self, HasDataLayout, TyAbiInterface, TyAndLayout}; -fn classify_ret<'a, Ty, C>(ret: &mut ArgAbi<'_, Ty>) -where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf + HasDataLayout, -{ +fn classify_ret(ret: &mut ArgAbi<'_, Ty>) { if !ret.layout.is_aggregate() && ret.layout.size.bits() <= 64 { ret.extend_integer_width_to(64); } else { @@ -18,8 +14,8 @@ where fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C>, + C: HasDataLayout, { match layout.abi { abi::Abi::Scalar(ref scalar) => scalar.value.is_float(), @@ -36,8 +32,8 @@ where fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !arg.layout.is_aggregate() && arg.layout.size.bits() <= 64 { arg.extend_integer_width_to(64); @@ -63,8 +59,8 @@ where pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !fn_abi.ret.is_ignore() { classify_ret(&mut fn_abi.ret); diff --git a/compiler/rustc_target/src/abi/call/sparc.rs b/compiler/rustc_target/src/abi/call/sparc.rs index 733a7328bd3a0..cc443197680e4 100644 --- a/compiler/rustc_target/src/abi/call/sparc.rs +++ b/compiler/rustc_target/src/abi/call/sparc.rs @@ -1,10 +1,9 @@ use crate::abi::call::{ArgAbi, FnAbi, Reg, Uniform}; -use crate::abi::{HasDataLayout, LayoutOf, Size, TyAndLayoutMethods}; +use crate::abi::{HasDataLayout, Size}; -fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size) +fn classify_ret(cx: &C, ret: &mut ArgAbi<'_, Ty>, offset: &mut Size) where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf + HasDataLayout, + C: HasDataLayout, { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(32); @@ -14,10 +13,9 @@ where } } -fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size) +fn classify_arg(cx: &C, arg: &mut ArgAbi<'_, Ty>, offset: &mut Size) where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf + HasDataLayout, + C: HasDataLayout, { let dl = cx.data_layout(); let size = arg.layout.size; @@ -35,10 +33,9 @@ where *offset = offset.align_to(align) + size.align_to(align); } -pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'_, Ty>) +pub fn compute_abi_info(cx: &C, fn_abi: &mut FnAbi<'_, Ty>) where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf + HasDataLayout, + C: HasDataLayout, { let mut offset = Size::ZERO; if !fn_abi.ret.is_ignore() { diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs index a647675e0735b..5d74c94e2c6f6 100644 --- a/compiler/rustc_target/src/abi/call/sparc64.rs +++ b/compiler/rustc_target/src/abi/call/sparc64.rs @@ -1,12 +1,12 @@ // FIXME: This needs an audit for correctness and completeness. use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform}; -use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{HasDataLayout, TyAbiInterface}; fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { // Ensure we have at most eight uniquely addressable members. @@ -26,8 +26,8 @@ where fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !ret.layout.is_aggregate() { ret.extend_integer_width_to(64); @@ -52,8 +52,8 @@ where fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !arg.layout.is_aggregate() { arg.extend_integer_width_to(64); @@ -76,8 +76,8 @@ where pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !fn_abi.ret.is_ignore() { classify_ret(cx, &mut fn_abi.ret); diff --git a/compiler/rustc_target/src/abi/call/wasm.rs b/compiler/rustc_target/src/abi/call/wasm.rs index bf2c08bb1662d..3237cde10654a 100644 --- a/compiler/rustc_target/src/abi/call/wasm.rs +++ b/compiler/rustc_target/src/abi/call/wasm.rs @@ -1,10 +1,10 @@ use crate::abi::call::{ArgAbi, FnAbi, Uniform}; -use crate::abi::{HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{HasDataLayout, TyAbiInterface}; fn unwrap_trivial_aggregate<'a, Ty, C>(cx: &C, val: &mut ArgAbi<'a, Ty>) -> bool where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if val.layout.is_aggregate() { if let Some(unit) = val.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()) { @@ -20,8 +20,8 @@ where fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { ret.extend_integer_width_to(32); if ret.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, ret) { @@ -31,8 +31,8 @@ where fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { arg.extend_integer_width_to(32); if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) { @@ -43,8 +43,8 @@ where /// The purpose of this ABI is to match the C ABI (aka clang) exactly. pub fn compute_c_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !fn_abi.ret.is_ignore() { classify_ret(cx, &mut fn_abi.ret); diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs index ff8849e1cf83b..3fc197b5d7537 100644 --- a/compiler/rustc_target/src/abi/call/x86.rs +++ b/compiler/rustc_target/src/abi/call/x86.rs @@ -1,5 +1,5 @@ use crate::abi::call::{ArgAttribute, FnAbi, PassMode, Reg, RegKind}; -use crate::abi::{self, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{self, HasDataLayout, TyAbiInterface, TyAndLayout}; use crate::spec::HasTargetSpec; #[derive(PartialEq)] @@ -10,8 +10,8 @@ pub enum Flavor { fn is_single_fp_element<'a, Ty, C>(cx: &C, layout: TyAndLayout<'a, Ty>) -> bool where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { match layout.abi { abi::Abi::Scalar(ref scalar) => scalar.value.is_float(), @@ -28,8 +28,8 @@ where pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, flavor: Flavor) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout + HasTargetSpec, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout + HasTargetSpec, { if !fn_abi.ret.is_ignore() { if fn_abi.ret.layout.is_aggregate() { diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs index a55658b7a3ec6..08f0aaba59af4 100644 --- a/compiler/rustc_target/src/abi/call/x86_64.rs +++ b/compiler/rustc_target/src/abi/call/x86_64.rs @@ -2,7 +2,7 @@ // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp use crate::abi::call::{ArgAbi, CastTarget, FnAbi, Reg, RegKind}; -use crate::abi::{self, Abi, HasDataLayout, LayoutOf, Size, TyAndLayout, TyAndLayoutMethods}; +use crate::abi::{self, Abi, HasDataLayout, Size, TyAbiInterface, TyAndLayout}; /// Classification of "eightbyte" components. // N.B., the order of the variants is from general to specific, @@ -26,8 +26,8 @@ fn classify_arg<'a, Ty, C>( arg: &ArgAbi<'a, Ty>, ) -> Result<[Option; MAX_EIGHTBYTES], Memory> where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { fn classify<'a, Ty, C>( cx: &C, @@ -36,8 +36,8 @@ where off: Size, ) -> Result<(), Memory> where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { if !off.is_aligned(layout.align.abi) { if !layout.is_zst() { @@ -172,8 +172,8 @@ const MAX_SSE_REGS: usize = 8; // XMM0-7 pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>) where - Ty: TyAndLayoutMethods<'a, C> + Copy, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C> + Copy, + C: HasDataLayout, { let mut int_regs = MAX_INT_REGS; let mut sse_regs = MAX_SSE_REGS; diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 2820a486dfd4b..820399943f0af 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1174,9 +1174,9 @@ impl<'a, Ty> Deref for TyAndLayout<'a, Ty> { } /// Trait for context types that can compute layouts of things. -pub trait LayoutOf { - type Ty; - type TyAndLayout; +pub trait LayoutOf<'a>: Sized { + type Ty: TyAbiInterface<'a, Self>; + type TyAndLayout: MaybeResult>; fn layout_of(&self, ty: Self::Ty) -> Self::TyAndLayout; fn spanned_layout_of(&self, ty: Self::Ty, _span: Span) -> Self::TyAndLayout { @@ -1184,9 +1184,6 @@ pub trait LayoutOf { } } -/// The `TyAndLayout` above will always be a `MaybeResult>`. -/// We can't add the bound due to the lifetime, but this trait is still useful when -/// writing code that's generic over the `LayoutOf` impl. pub trait MaybeResult { type Error; @@ -1239,41 +1236,42 @@ pub struct PointeeInfo { pub address_space: AddressSpace, } -pub trait TyAndLayoutMethods<'a, C: LayoutOf>: Sized { - fn for_variant( +/// Trait that needs to be implemented by the higher-level type representation +/// (e.g. `rustc_middle::ty::Ty`), to provide `rustc_target::abi` functionality. +pub trait TyAbiInterface<'a, C>: Sized { + fn ty_and_layout_for_variant( this: TyAndLayout<'a, Self>, cx: &C, variant_index: VariantIdx, ) -> TyAndLayout<'a, Self>; - fn field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> C::TyAndLayout; - fn pointee_info_at(this: TyAndLayout<'a, Self>, cx: &C, offset: Size) -> Option; + fn ty_and_layout_field(this: TyAndLayout<'a, Self>, cx: &C, i: usize) -> TyAndLayout<'a, Self>; + fn ty_and_layout_pointee_info_at( + this: TyAndLayout<'a, Self>, + cx: &C, + offset: Size, + ) -> Option; } impl<'a, Ty> TyAndLayout<'a, Ty> { pub fn for_variant(self, cx: &C, variant_index: VariantIdx) -> Self where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf, + Ty: TyAbiInterface<'a, C>, { - Ty::for_variant(self, cx, variant_index) + Ty::ty_and_layout_for_variant(self, cx, variant_index) } - /// Callers might want to use `C: LayoutOf>` - /// to allow recursion (see `might_permit_zero_init` below for an example). - pub fn field(self, cx: &C, i: usize) -> C::TyAndLayout + pub fn field(self, cx: &C, i: usize) -> Self where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf, + Ty: TyAbiInterface<'a, C>, { - Ty::field(self, cx, i) + Ty::ty_and_layout_field(self, cx, i) } pub fn pointee_info_at(self, cx: &C, offset: Size) -> Option where - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf, + Ty: TyAbiInterface<'a, C>, { - Ty::pointee_info_at(self, cx, offset) + Ty::ty_and_layout_pointee_info_at(self, cx, offset) } } @@ -1301,11 +1299,11 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { /// FIXME: Once we removed all the conservatism, we could alternatively /// create an all-0/all-undef constant and run the const value validator to see if /// this is a valid value for the given type. - pub fn might_permit_raw_init(self, cx: &C, zero: bool) -> Result + pub fn might_permit_raw_init(self, cx: &C, zero: bool) -> bool where Self: Copy, - Ty: TyAndLayoutMethods<'a, C>, - C: LayoutOf> + HasDataLayout, + Ty: TyAbiInterface<'a, C>, + C: HasDataLayout, { let scalar_allows_raw_init = move |s: &Scalar| -> bool { if zero { @@ -1330,7 +1328,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { }; if !valid { // This is definitely not okay. - return Ok(false); + return false; } // If we have not found an error yet, we need to recursively descend into fields. @@ -1341,16 +1339,15 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { } FieldsShape::Arbitrary { offsets, .. } => { for idx in 0..offsets.len() { - let field = self.field(cx, idx).to_result()?; - if !field.might_permit_raw_init(cx, zero)? { + if !self.field(cx, idx).might_permit_raw_init(cx, zero) { // We found a field that is unhappy with this kind of initialization. - return Ok(false); + return false; } } } } // FIXME(#66151): For now, we are conservative and do not check `self.variants`. - Ok(true) + true } }