From 3769fddba23985e9ab83828ccce672507e7dd891 Mon Sep 17 00:00:00 2001 From: beetrees Date: Mon, 6 May 2024 13:27:40 +0100 Subject: [PATCH] Refactor float `Primitive`s to a separate `Float` type --- compiler/rustc_abi/src/lib.rs | 50 ++++++++++++++----- .../rustc_codegen_cranelift/src/common.rs | 12 +++-- compiler/rustc_codegen_gcc/src/type_of.rs | 9 ++-- compiler/rustc_codegen_llvm/src/asm.rs | 22 ++++---- compiler/rustc_codegen_llvm/src/builder.rs | 2 +- .../src/debuginfo/metadata/enums/mod.rs | 5 +- compiler/rustc_codegen_llvm/src/intrinsic.rs | 14 ++++-- compiler/rustc_codegen_llvm/src/type_of.rs | 7 +-- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 8 ++- .../rustc_codegen_ssa/src/traits/type_.rs | 12 ++++- compiler/rustc_middle/src/ty/layout.rs | 27 ++++++++-- compiler/rustc_middle/src/ty/util.rs | 7 ++- .../rustc_smir/src/rustc_smir/convert/abi.rs | 20 ++++++-- .../rustc_target/src/abi/call/loongarch.rs | 2 +- compiler/rustc_target/src/abi/call/mips64.rs | 6 +-- compiler/rustc_target/src/abi/call/mod.rs | 2 +- compiler/rustc_target/src/abi/call/riscv.rs | 2 +- compiler/rustc_target/src/abi/call/sparc64.rs | 10 ++-- compiler/rustc_target/src/abi/call/x86_64.rs | 2 +- compiler/rustc_target/src/abi/mod.rs | 6 ++- compiler/rustc_ty_utils/src/layout.rs | 9 +--- .../rust-analyzer/crates/hir-ty/src/layout.rs | 12 ++--- tests/ui/abi/debug.stderr | 4 +- 23 files changed, 155 insertions(+), 95 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 5e3f64540e4aa..bc2ad2394c85e 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -926,6 +926,41 @@ impl Integer { } } +/// Floating-point types. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[cfg_attr(feature = "nightly", derive(HashStable_Generic))] +pub enum Float { + F16, + F32, + F64, + F128, +} + +impl Float { + pub fn size(self) -> Size { + use Float::*; + + match self { + F16 => Size::from_bits(16), + F32 => Size::from_bits(32), + F64 => Size::from_bits(64), + F128 => Size::from_bits(128), + } + } + + pub fn align(self, cx: &C) -> AbiAndPrefAlign { + use Float::*; + let dl = cx.data_layout(); + + match self { + F16 => dl.f16_align, + F32 => dl.f32_align, + F64 => dl.f64_align, + F128 => dl.f128_align, + } + } +} + /// Fundamental unit of memory access and layout. #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] @@ -938,10 +973,7 @@ pub enum Primitive { /// a negative integer passed by zero-extension will appear positive in /// the callee, and most operations on it will produce the wrong values. Int(Integer, bool), - F16, - F32, - F64, - F128, + Float(Float), Pointer(AddressSpace), } @@ -952,10 +984,7 @@ impl Primitive { match self { Int(i, _) => i.size(), - F16 => Size::from_bits(16), - F32 => Size::from_bits(32), - F64 => Size::from_bits(64), - F128 => Size::from_bits(128), + Float(f) => f.size(), // FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in // different address spaces can have different sizes // (but TargetDataLayout doesn't currently parse that part of the DL string) @@ -969,10 +998,7 @@ impl Primitive { match self { Int(i, _) => i.align(dl), - F16 => dl.f16_align, - F32 => dl.f32_align, - F64 => dl.f64_align, - F128 => dl.f128_align, + Float(f) => f.align(dl), // FIXME(erikdesjardins): ignoring address space is technically wrong, pointers in // different address spaces can have different alignments // (but TargetDataLayout doesn't currently parse that part of the DL string) diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 2a24d6150bd6e..21d0cd2d30f2a 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -7,7 +7,7 @@ use rustc_middle::ty::layout::{ use rustc_middle::ty::TypeFoldable; use rustc_span::source_map::Spanned; use rustc_target::abi::call::FnAbi; -use rustc_target::abi::{Integer, Primitive}; +use rustc_target::abi::{Float, Integer, Primitive}; use rustc_target::spec::{HasTargetSpec, Target}; use crate::constant::ConstantCx; @@ -32,10 +32,12 @@ pub(crate) fn scalar_to_clif_type(tcx: TyCtxt<'_>, scalar: Scalar) -> Type { Integer::I64 => types::I64, Integer::I128 => types::I128, }, - Primitive::F16 => unimplemented!("f16_f128"), - Primitive::F32 => types::F32, - Primitive::F64 => types::F64, - Primitive::F128 => unimplemented!("f16_f128"), + Primitive::Float(float) => match float { + Float::F16 => unimplemented!("f16_f128"), + Float::F32 => types::F32, + Float::F64 => types::F64, + Float::F128 => unimplemented!("f16_f128"), + }, // FIXME(erikdesjardins): handle non-default addrspace ptr sizes Primitive::Pointer(_) => pointer_ty(tcx), } diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 8f9bfbbd18fb0..90e139494b8a7 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -8,8 +8,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_target::abi::call::{CastTarget, FnAbi, Reg}; use rustc_target::abi::{ - self, Abi, Align, FieldsShape, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, - Variants, F128, F16, F32, F64, + self, Abi, Align, FieldsShape, Float, Int, Integer, PointeeInfo, Pointer, Size, TyAbiInterface, + Variants, }; use crate::abi::{FnAbiGcc, FnAbiGccExt, GccType}; @@ -283,10 +283,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> { match scalar.primitive() { Int(i, true) => cx.type_from_integer(i), Int(i, false) => cx.type_from_unsigned_integer(i), - F16 => cx.type_f16(), - F32 => cx.type_f32(), - F64 => cx.type_f64(), - F128 => cx.type_f128(), + Float(f) => cx.type_from_float(f), Pointer(address_space) => { // If we know the alignment, pick something better than i8. let pointee = if let Some(pointee) = self.pointee_info_at(cx, offset) { diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index e09869cf425c1..71d4343ee07fb 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -904,8 +904,8 @@ fn llvm_asm_scalar_type<'ll>(cx: &CodegenCx<'ll, '_>, scalar: Scalar) -> &'ll Ty Primitive::Int(Integer::I16, _) => cx.type_i16(), Primitive::Int(Integer::I32, _) => cx.type_i32(), Primitive::Int(Integer::I64, _) => cx.type_i64(), - Primitive::F32 => cx.type_f32(), - Primitive::F64 => cx.type_f64(), + Primitive::Float(Float::F32) => cx.type_f32(), + Primitive::Float(Float::F64) => cx.type_f64(), // FIXME(erikdesjardins): handle non-default addrspace ptr sizes Primitive::Pointer(_) => cx.type_from_integer(dl.ptr_sized_integer()), _ => unreachable!(), @@ -950,7 +950,7 @@ fn llvm_fixup_input<'ll, 'tcx>( bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices)) } (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s)) - if s.primitive() == Primitive::F64 => + if s.primitive() == Primitive::Float(Float::F64) => { bx.bitcast(value, bx.cx.type_i64()) } @@ -986,8 +986,8 @@ fn llvm_fixup_input<'ll, 'tcx>( match s.primitive() { // MIPS only supports register-length arithmetics. Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()), - Primitive::F32 => bx.bitcast(value, bx.cx.type_i32()), - Primitive::F64 => bx.bitcast(value, bx.cx.type_i64()), + Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_i32()), + Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_i64()), _ => value, } } @@ -1027,7 +1027,7 @@ fn llvm_fixup_output<'ll, 'tcx>( bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices)) } (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s)) - if s.primitive() == Primitive::F64 => + if s.primitive() == Primitive::Float(Float::F64) => { bx.bitcast(value, bx.cx.type_f64()) } @@ -1064,8 +1064,8 @@ fn llvm_fixup_output<'ll, 'tcx>( // MIPS only supports register-length arithmetics. Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()), Primitive::Int(Integer::I16, _) => bx.trunc(value, bx.cx.type_i16()), - Primitive::F32 => bx.bitcast(value, bx.cx.type_f32()), - Primitive::F64 => bx.bitcast(value, bx.cx.type_f64()), + Primitive::Float(Float::F32) => bx.bitcast(value, bx.cx.type_f32()), + Primitive::Float(Float::F64) => bx.bitcast(value, bx.cx.type_f64()), _ => value, } } @@ -1100,7 +1100,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>( cx.type_vector(elem_ty, count * 2) } (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s)) - if s.primitive() == Primitive::F64 => + if s.primitive() == Primitive::Float(Float::F64) => { cx.type_i64() } @@ -1136,8 +1136,8 @@ fn llvm_fixup_output_type<'ll, 'tcx>( match s.primitive() { // MIPS only supports register-length arithmetics. Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(), - Primitive::F32 => cx.type_i32(), - Primitive::F64 => cx.type_i64(), + Primitive::Float(Float::F32) => cx.type_i32(), + Primitive::Float(Float::F64) => cx.type_i64(), _ => layout.llvm_type(cx), } } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 1a1b4ae383133..49ffa9bd7ec8b 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -576,7 +576,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { } } } - abi::F16 | abi::F32 | abi::F64 | abi::F128 => {} + abi::Float(_) => {} } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 657e9ce998f93..bacd74f430f73 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -122,10 +122,7 @@ fn tag_base_type<'ll, 'tcx>( // Niche tags are always normalized to unsized integers of the correct size. match tag.primitive() { Primitive::Int(t, _) => t, - Primitive::F16 => Integer::I16, - Primitive::F32 => Integer::I32, - Primitive::F64 => Integer::I64, - Primitive::F128 => Integer::I128, + Primitive::Float(f) => Integer::from_size(f.size()).unwrap(), // FIXME(erikdesjardins): handle non-default addrspace ptr sizes Primitive::Pointer(_) => { // If the niche is the NULL value of a reference, then `discr_enum_ty` will be diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs index 56550dbfa4b8b..0bd886c55b002 100644 --- a/compiler/rustc_codegen_llvm/src/intrinsic.rs +++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, GenericArgsRef, Ty}; use rustc_middle::{bug, span_bug}; use rustc_span::{sym, Span, Symbol}; -use rustc_target::abi::{self, Align, HasDataLayout, Primitive, Size}; +use rustc_target::abi::{self, Align, Float, HasDataLayout, Primitive, Size}; use rustc_target::spec::{HasTargetSpec, PanicStrategy}; use std::cmp::Ordering; @@ -231,13 +231,17 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> { emit_va_arg(self, args[0], ret_ty) } } - Primitive::F16 => bug!("the va_arg intrinsic does not work with `f16`"), - Primitive::F64 | Primitive::Pointer(_) => { + Primitive::Float(Float::F16) => { + bug!("the va_arg intrinsic does not work with `f16`") + } + Primitive::Float(Float::F64) | Primitive::Pointer(_) => { emit_va_arg(self, args[0], ret_ty) } // `va_arg` should never be used with the return type f32. - Primitive::F32 => bug!("the va_arg intrinsic does not work with `f32`"), - Primitive::F128 => { + Primitive::Float(Float::F32) => { + bug!("the va_arg intrinsic does not work with `f32`") + } + Primitive::Float(Float::F128) => { bug!("the va_arg intrinsic does not work with `f128`") } } diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index 40ed6baa61072..5f60fd23a5fe9 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -6,7 +6,7 @@ use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths}; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use rustc_target::abi::{Abi, Align, FieldsShape}; -use rustc_target::abi::{Int, Pointer, F128, F16, F32, F64}; +use rustc_target::abi::{Float, Int, Pointer}; use rustc_target::abi::{Scalar, Size, Variants}; use std::fmt::Write; @@ -272,10 +272,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> { fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, scalar: Scalar) -> &'a Type { match scalar.primitive() { Int(i, _) => cx.type_from_integer(i), - F16 => cx.type_f16(), - F32 => cx.type_f32(), - F64 => cx.type_f64(), - F128 => cx.type_f128(), + Float(f) => cx.type_from_float(f), Pointer(address_space) => cx.type_ptr_ext(address_space), } } diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 4e7d251a2e928..2ed212d0712bd 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -306,17 +306,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { self.assume_scalar_range(bx, imm, from_scalar, from_backend_ty); imm = match (from_scalar.primitive(), to_scalar.primitive()) { - (Int(..) | F16 | F32 | F64 | F128, Int(..) | F16 | F32 | F64 | F128) => { - bx.bitcast(imm, to_backend_ty) - } + (Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty), (Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty), (Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm), (Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty), - (F16 | F32 | F64 | F128, Pointer(..)) => { + (Float(_), Pointer(..)) => { let int_imm = bx.bitcast(imm, bx.cx().type_isize()); bx.ptradd(bx.const_null(bx.type_ptr()), int_imm) } - (Pointer(..), F16 | F32 | F64 | F128) => { + (Pointer(..), Float(_)) => { let int_imm = bx.ptrtoint(imm, bx.cx().type_isize()); bx.bitcast(int_imm, to_backend_ty) } diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index ccb35629a829d..403f6a7327715 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -7,7 +7,7 @@ use rustc_middle::bug; use rustc_middle::ty::layout::TyAndLayout; use rustc_middle::ty::{self, Ty}; use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg}; -use rustc_target::abi::{AddressSpace, Integer}; +use rustc_target::abi::{AddressSpace, Float, Integer}; // This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use // `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves. @@ -65,6 +65,16 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { } } + fn type_from_float(&self, f: Float) -> Self::Type { + use Float::*; + match f { + F16 => self.type_f16(), + F32 => self.type_f32(), + F64 => self.type_f64(), + F128 => self.type_f128(), + } + } + fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool { ty.needs_drop(self.tcx(), ty::ParamEnv::reveal_all()) } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index f8490e5e15fc0..eb5dfd4e0c075 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -114,16 +114,35 @@ impl Integer { } } -#[extension(pub trait PrimitiveExt)] -impl Primitive { +#[extension(pub trait FloatExt)] +impl Float { #[inline] fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { match *self { - Int(i, signed) => i.to_ty(tcx, signed), F16 => tcx.types.f16, F32 => tcx.types.f32, F64 => tcx.types.f64, F128 => tcx.types.f128, + } + } + + fn from_float_ty(fty: ty::FloatTy) -> Self { + match fty { + ty::FloatTy::F16 => F16, + ty::FloatTy::F32 => F32, + ty::FloatTy::F64 => F64, + ty::FloatTy::F128 => F128, + } + } +} + +#[extension(pub trait PrimitiveExt)] +impl Primitive { + #[inline] + fn to_ty<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + match *self { + Int(i, signed) => i.to_ty(tcx, signed), + Float(f) => f.to_ty(tcx), // FIXME(erikdesjardins): handle non-default addrspace ptr sizes Pointer(_) => Ty::new_mut_ptr(tcx, tcx.types.unit), } @@ -140,7 +159,7 @@ impl Primitive { let signed = false; tcx.data_layout().ptr_sized_integer().to_ty(tcx, signed) } - F16 | F32 | F64 | F128 => bug!("floats do not have an int type"), + Float(_) => bug!("floats do not have an int type"), } } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index f5e973f85da12..6ad4f492f742f 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -2,7 +2,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags; use crate::query::{IntoQueryParam, Providers}; -use crate::ty::layout::IntegerExt; +use crate::ty::layout::{FloatExt, IntegerExt}; use crate::ty::{ self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, @@ -20,7 +20,7 @@ use rustc_index::bit_set::GrowableBitSet; use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable}; use rustc_session::Limit; use rustc_span::sym; -use rustc_target::abi::{Integer, IntegerType, Primitive, Size}; +use rustc_target::abi::{Float, Integer, IntegerType, Size}; use rustc_target::spec::abi::Abi; use smallvec::{smallvec, SmallVec}; use std::{fmt, iter}; @@ -1145,8 +1145,7 @@ impl<'tcx> Ty<'tcx> { ty::Char => Size::from_bytes(4), ty::Int(ity) => Integer::from_int_ty(&tcx, ity).size(), ty::Uint(uty) => Integer::from_uint_ty(&tcx, uty).size(), - ty::Float(ty::FloatTy::F32) => Primitive::F32.size(&tcx), - ty::Float(ty::FloatTy::F64) => Primitive::F64.size(&tcx), + ty::Float(fty) => Float::from_float_ty(fty).size(), _ => bug!("non primitive type"), } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs index 6fb1560ac6c10..cbc3aae1703ea 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/abi.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/abi.rs @@ -256,10 +256,9 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Primitive { rustc_abi::Primitive::Int(length, signed) => { Primitive::Int { length: length.stable(tables), signed: *signed } } - rustc_abi::Primitive::F16 => Primitive::Float { length: FloatLength::F16 }, - rustc_abi::Primitive::F32 => Primitive::Float { length: FloatLength::F32 }, - rustc_abi::Primitive::F64 => Primitive::Float { length: FloatLength::F64 }, - rustc_abi::Primitive::F128 => Primitive::Float { length: FloatLength::F128 }, + rustc_abi::Primitive::Float(length) => { + Primitive::Float { length: length.stable(tables) } + } rustc_abi::Primitive::Pointer(space) => Primitive::Pointer(space.stable(tables)), } } @@ -287,6 +286,19 @@ impl<'tcx> Stable<'tcx> for rustc_abi::Integer { } } +impl<'tcx> Stable<'tcx> for rustc_abi::Float { + type T = FloatLength; + + fn stable(&self, _tables: &mut Tables<'_>) -> Self::T { + match self { + rustc_abi::Float::F16 => FloatLength::F16, + rustc_abi::Float::F32 => FloatLength::F32, + rustc_abi::Float::F64 => FloatLength::F64, + rustc_abi::Float::F128 => FloatLength::F128, + } + } +} + impl<'tcx> Stable<'tcx> for rustc_abi::WrappingRange { type T = WrappingRange; diff --git a/compiler/rustc_target/src/abi/call/loongarch.rs b/compiler/rustc_target/src/abi/call/loongarch.rs index 943b12a9fbfcc..893818af77c30 100644 --- a/compiler/rustc_target/src/abi/call/loongarch.rs +++ b/compiler/rustc_target/src/abi/call/loongarch.rs @@ -59,7 +59,7 @@ where _ => return Err(CannotUseFpConv), } } - abi::F16 | abi::F32 | abi::F64 | abi::F128 => { + abi::Float(_) => { if arg_layout.size.bits() > flen { return Err(CannotUseFpConv); } diff --git a/compiler/rustc_target/src/abi/call/mips64.rs b/compiler/rustc_target/src/abi/call/mips64.rs index b2a2c34b980f6..5b52ebbdedd1a 100644 --- a/compiler/rustc_target/src/abi/call/mips64.rs +++ b/compiler/rustc_target/src/abi/call/mips64.rs @@ -26,8 +26,8 @@ where { match ret.layout.field(cx, i).abi { abi::Abi::Scalar(scalar) => match scalar.primitive() { - abi::F32 => Some(Reg::f32()), - abi::F64 => Some(Reg::f64()), + abi::Float(abi::F32) => Some(Reg::f32()), + abi::Float(abi::F64) => Some(Reg::f64()), _ => None, }, _ => None, @@ -110,7 +110,7 @@ where // We only care about aligned doubles if let abi::Abi::Scalar(scalar) = field.abi { - if let abi::F64 = scalar.primitive() { + if scalar.primitive() == abi::Float(abi::F64) { if offset.is_aligned(dl.f64_align.abi) { // Insert enough integers to cover [last_offset, offset) assert!(last_offset.is_aligned(dl.f64_align.abi)); diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 3ddea42f67bbd..919fa2140d5be 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -443,7 +443,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Abi::Scalar(scalar) => { let kind = match scalar.primitive() { abi::Int(..) | abi::Pointer(_) => RegKind::Integer, - abi::F16 | abi::F32 | abi::F64 | abi::F128 => RegKind::Float, + abi::Float(_) => RegKind::Float, }; Ok(HomogeneousAggregate::Homogeneous(Reg { kind, size: self.size })) } diff --git a/compiler/rustc_target/src/abi/call/riscv.rs b/compiler/rustc_target/src/abi/call/riscv.rs index 5d4b3a9d245a4..84f13f8cc5da9 100644 --- a/compiler/rustc_target/src/abi/call/riscv.rs +++ b/compiler/rustc_target/src/abi/call/riscv.rs @@ -65,7 +65,7 @@ where _ => return Err(CannotUseFpConv), } } - abi::F16 | abi::F32 | abi::F64 | abi::F128 => { + abi::Float(_) => { if arg_layout.size.bits() > flen { return Err(CannotUseFpConv); } diff --git a/compiler/rustc_target/src/abi/call/sparc64.rs b/compiler/rustc_target/src/abi/call/sparc64.rs index acdcd5cc0d482..c0952130e0410 100644 --- a/compiler/rustc_target/src/abi/call/sparc64.rs +++ b/compiler/rustc_target/src/abi/call/sparc64.rs @@ -20,7 +20,7 @@ where { let dl = cx.data_layout(); - if !matches!(scalar.primitive(), abi::F32 | abi::F64) { + if !matches!(scalar.primitive(), abi::Float(abi::F32 | abi::F64)) { return data; } @@ -56,7 +56,7 @@ where return data; } - if scalar.primitive() == abi::F32 { + if scalar.primitive() == abi::Float(abi::F32) { data.arg_attribute = ArgAttribute::InReg; data.prefix[data.prefix_index] = Some(Reg::f32()); data.last_offset = offset + Reg::f32().size; @@ -80,14 +80,14 @@ where { data = arg_scalar(cx, scalar1, offset, data); match (scalar1.primitive(), scalar2.primitive()) { - (abi::F32, _) => offset += Reg::f32().size, - (_, abi::F64) => offset += Reg::f64().size, + (abi::Float(abi::F32), _) => offset += Reg::f32().size, + (_, abi::Float(abi::F64)) => offset += Reg::f64().size, (abi::Int(i, _signed), _) => offset += i.size(), (abi::Pointer(_), _) => offset += Reg::i64().size, _ => {} } - if (offset.bytes() % 4) != 0 && matches!(scalar2.primitive(), abi::F32 | abi::F64) { + if (offset.bytes() % 4) != 0 && matches!(scalar2.primitive(), abi::Float(abi::F32 | abi::F64)) { offset += Size::from_bytes(4 - (offset.bytes() % 4)); } data = arg_scalar(cx, scalar2, offset, data); diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs index f3208fe5d0351..fcd712489fa40 100644 --- a/compiler/rustc_target/src/abi/call/x86_64.rs +++ b/compiler/rustc_target/src/abi/call/x86_64.rs @@ -51,7 +51,7 @@ where Abi::Scalar(scalar) => match scalar.primitive() { abi::Int(..) | abi::Pointer(_) => Class::Int, - abi::F16 | abi::F32 | abi::F64 | abi::F128 => Class::Sse, + abi::Float(_) => Class::Sse, }, Abi::Vector { .. } => Class::Sse, diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 24e49ff648f2f..666efd9deca28 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1,4 +1,5 @@ use rustc_data_structures::intern::Interned; +pub use Float::*; pub use Integer::*; pub use Primitive::*; @@ -11,7 +12,8 @@ use rustc_macros::HashStable_Generic; pub mod call; -pub use rustc_abi::*; +// Explicitly import `Float` to avoid ambiguity with `Primitive::Float`. +pub use rustc_abi::{Float, *}; impl ToJson for Endian { fn to_json(&self) -> Json { @@ -207,7 +209,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { C: HasDataLayout, { match self.abi { - Abi::Scalar(scalar) => matches!(scalar.primitive(), F32 | F64), + Abi::Scalar(scalar) => matches!(scalar.primitive(), Float(F32 | F64)), Abi::Aggregate { .. } => { if self.fields.count() == 1 && self.fields.offset(0).bytes() == 0 { self.field(cx, 0).is_single_fp_element(cx) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 902b76e8c1e26..f78a28d16fdf5 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -5,7 +5,7 @@ use rustc_index::{IndexSlice, IndexVec}; use rustc_middle::mir::{CoroutineLayout, CoroutineSavedLocal}; use rustc_middle::query::Providers; use rustc_middle::ty::layout::{ - IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, + FloatExt, IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, }; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{ @@ -180,12 +180,7 @@ fn layout_of_uncached<'tcx>( )), ty::Int(ity) => scalar(Int(Integer::from_int_ty(dl, ity), true)), ty::Uint(ity) => scalar(Int(Integer::from_uint_ty(dl, ity), false)), - ty::Float(fty) => scalar(match fty { - ty::FloatTy::F16 => F16, - ty::FloatTy::F32 => F32, - ty::FloatTy::F64 => F64, - ty::FloatTy::F128 => F128, - }), + ty::Float(fty) => scalar(Float(Float::from_float_ty(fty))), ty::FnPtr(_) => { let mut ptr = scalar_unit(Pointer(dl.instruction_address_space)); ptr.valid_range_mut().start = 1; diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs index dd949e26c2ab2..d9fd029d378c7 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs @@ -6,8 +6,8 @@ use base_db::salsa::Cycle; use chalk_ir::{AdtId, FloatTy, IntTy, TyKind, UintTy}; use hir_def::{ layout::{ - Abi, FieldsShape, Integer, LayoutCalculator, LayoutS, Primitive, ReprOptions, Scalar, Size, - StructKind, TargetDataLayout, WrappingRange, + Abi, FieldsShape, Float, Integer, LayoutCalculator, LayoutS, Primitive, ReprOptions, + Scalar, Size, StructKind, TargetDataLayout, WrappingRange, }, LocalFieldId, StructId, }; @@ -264,10 +264,10 @@ pub fn layout_of_ty_query( ), chalk_ir::Scalar::Float(f) => scalar( dl, - match f { - FloatTy::F32 => Primitive::F32, - FloatTy::F64 => Primitive::F64, - }, + Primitive::Float(match f { + FloatTy::F32 => Float::F32, + FloatTy::F64 => Float::F64, + }), ), }, TyKind::Tuple(len, tys) => { diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr index 00fc7d1ece1d9..7365839da89dc 100644 --- a/tests/ui/abi/debug.stderr +++ b/tests/ui/abi/debug.stderr @@ -576,7 +576,9 @@ error: ABIs are not compatible }, abi: Scalar( Initialized { - value: F32, + value: Float( + F32, + ), valid_range: $FULL, }, ),