Skip to content

Commit

Permalink
Add f16 and f128 support
Browse files Browse the repository at this point in the history
  • Loading branch information
beetrees committed Jul 10, 2024
1 parent 5445aef commit 69424f7
Show file tree
Hide file tree
Showing 28 changed files with 384 additions and 73 deletions.
20 changes: 12 additions & 8 deletions src/tools/rust-analyzer/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"

[[package]]
name = "chalk-derive"
version = "0.97.0"
version = "0.98.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92a0aedc4ac2adc5c0b7dc9ec38c5c816284ad28da6d4ecd01873b9683f54972"
checksum = "9426c8fd0fe61c3da880b801d3b510524df17843a8f9ec1f5b9cec24fb7412df"
dependencies = [
"proc-macro2",
"quote",
Expand All @@ -179,19 +179,19 @@ dependencies = [

[[package]]
name = "chalk-ir"
version = "0.97.0"
version = "0.98.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db18493569b190f7266a04901e520fc3a5c00564475154287906f8a27302c119"
checksum = "d5f2eb1cd6054da221bd1ac0197fb2fe5e2caf3dcb93619398fc1433f8f09093"
dependencies = [
"bitflags 2.5.0",
"chalk-derive",
]

[[package]]
name = "chalk-recursive"
version = "0.97.0"
version = "0.98.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae4ba8ce5bd2e1b59f1f79495bc8704db09a8285e51cc5ddf01d9baee1bf447d"
checksum = "129dc03458f71cfb9c3cd621c9c68166a94e87b85b16ccd29af015d7ff9a1c61"
dependencies = [
"chalk-derive",
"chalk-ir",
Expand All @@ -202,9 +202,9 @@ dependencies = [

[[package]]
name = "chalk-solve"
version = "0.97.0"
version = "0.98.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ec1b3b7f7b1ec38f099ef39c2bc3ea29335be1b8316d114baff46d96d131e9"
checksum = "d7e8a8c1e928f98cdf227b868416ef21dcd8cc3c61b347576d783713444d41c8"
dependencies = [
"chalk-derive",
"chalk-ir",
Expand Down Expand Up @@ -546,6 +546,7 @@ dependencies = [
"ra-ap-rustc_abi",
"ra-ap-rustc_parse_format",
"rustc-hash",
"rustc_apfloat",
"smallvec",
"span",
"stdx",
Expand Down Expand Up @@ -613,6 +614,7 @@ dependencies = [
"ra-ap-rustc_index",
"ra-ap-rustc_pattern_analysis",
"rustc-hash",
"rustc_apfloat",
"scoped-tls",
"smallvec",
"span",
Expand Down Expand Up @@ -658,6 +660,7 @@ dependencies = [
"profile",
"pulldown-cmark",
"pulldown-cmark-to-cmark",
"rustc_apfloat",
"smallvec",
"span",
"stdx",
Expand Down Expand Up @@ -1939,6 +1942,7 @@ dependencies = [
"rayon",
"rowan",
"rustc-hash",
"rustc_apfloat",
"smol_str",
"stdx",
"test-utils",
Expand Down
8 changes: 4 additions & 4 deletions src/tools/rust-analyzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ arrayvec = "0.7.4"
bitflags = "2.4.1"
cargo_metadata = "0.18.1"
camino = "1.1.6"
chalk-solve = { version = "0.97.0", default-features = false }
chalk-ir = "0.97.0"
chalk-recursive = { version = "0.97.0", default-features = false }
chalk-derive = "0.97.0"
chalk-solve = { version = "0.98.0", default-features = false }
chalk-ir = "0.98.0"
chalk-recursive = { version = "0.98.0", default-features = false }
chalk-derive = "0.98.0"
crossbeam-channel = "0.5.8"
dissimilar = "1.0.7"
dot = "0.1.4"
Expand Down
1 change: 1 addition & 0 deletions src/tools/rust-analyzer/crates/hir-def/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ tracing.workspace = true
smallvec.workspace = true
hashbrown.workspace = true
triomphe.workspace = true
rustc_apfloat = "0.2.0"

ra-ap-rustc_parse_format.workspace = true
ra-ap-rustc_abi.workspace = true
Expand Down
10 changes: 10 additions & 0 deletions src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,10 @@ pub enum BuiltinUint {

#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum BuiltinFloat {
F16,
F32,
F64,
F128,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
Expand Down Expand Up @@ -65,8 +67,10 @@ impl BuiltinType {
(name![u64], BuiltinType::Uint(BuiltinUint::U64)),
(name![u128], BuiltinType::Uint(BuiltinUint::U128)),

(name![f16], BuiltinType::Float(BuiltinFloat::F16)),
(name![f32], BuiltinType::Float(BuiltinFloat::F32)),
(name![f64], BuiltinType::Float(BuiltinFloat::F64)),
(name![f128], BuiltinType::Float(BuiltinFloat::F128)),
];

pub fn by_name(name: &Name) -> Option<Self> {
Expand Down Expand Up @@ -97,8 +101,10 @@ impl AsName for BuiltinType {
BuiltinUint::U128 => name![u128],
},
BuiltinType::Float(it) => match it {
BuiltinFloat::F16 => name![f16],
BuiltinFloat::F32 => name![f32],
BuiltinFloat::F64 => name![f64],
BuiltinFloat::F128 => name![f128],
},
}
}
Expand Down Expand Up @@ -155,8 +161,10 @@ impl BuiltinUint {
impl BuiltinFloat {
pub fn from_suffix(suffix: &str) -> Option<BuiltinFloat> {
let res = match suffix {
"f16" => BuiltinFloat::F16,
"f32" => BuiltinFloat::F32,
"f64" => BuiltinFloat::F64,
"f128" => BuiltinFloat::F128,
_ => return None,
};
Some(res)
Expand Down Expand Up @@ -192,8 +200,10 @@ impl fmt::Display for BuiltinUint {
impl fmt::Display for BuiltinFloat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
BuiltinFloat::F16 => "f16",
BuiltinFloat::F32 => "f32",
BuiltinFloat::F64 => "f64",
BuiltinFloat::F128 => "f128",
})
}
}
12 changes: 11 additions & 1 deletion src/tools/rust-analyzer/crates/hir-def/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::fmt;
use hir_expand::name::Name;
use intern::Interned;
use la_arena::{Idx, RawIdx};
use rustc_apfloat::ieee::{Half as f16, Quad as f128};
use smallvec::SmallVec;
use syntax::ast;

Expand Down Expand Up @@ -62,18 +63,27 @@ pub type LabelId = Idx<Label>;
#[derive(Default, Debug, Clone, Eq, PartialEq)]
pub struct FloatTypeWrapper(Box<str>);

// FIXME(#17451): Use builtin types once stabilised.
impl FloatTypeWrapper {
pub fn new(value: String) -> Self {
Self(value.into())
}

pub fn to_f128(&self) -> f128 {
self.0.parse().unwrap_or_default()
}

pub fn to_f64(&self) -> f64 {
self.0.parse().unwrap_or_default()
}

pub fn to_f32(&self) -> f32 {
self.0.parse().unwrap_or_default()
}

pub fn to_f16(&self) -> f16 {
self.0.parse().unwrap_or_default()
}
}

impl fmt::Display for FloatTypeWrapper {
Expand All @@ -91,7 +101,7 @@ pub enum Literal {
Bool(bool),
Int(i128, Option<BuiltinInt>),
Uint(u128, Option<BuiltinUint>),
// Here we are using a wrapper around float because f32 and f64 do not implement Eq, so they
// Here we are using a wrapper around float because float primitives do not implement Eq, so they
// could not be used directly here, to understand how the wrapper works go to definition of
// FloatTypeWrapper
Float(FloatTypeWrapper, Option<BuiltinFloat>),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ macro_rules! m {
let _ = 'c';
let _ = 1000;
let _ = 12E+99_f64;
let _ = 45E+1234_f128;
let _ = "rust1";
let _ = -92;
}
Expand All @@ -50,6 +51,7 @@ macro_rules! m {
let _ = 'c';
let _ = 1000;
let _ = 12E+99_f64;
let _ = 45E+1234_f128;
let _ = "rust1";
let _ = -92;
}
Expand All @@ -58,6 +60,7 @@ fn f() {
let _ = 'c';
let _ = 1000;
let _ = 12E+99_f64;
let _ = 45E+1234_f128;
let _ = "rust1";
let _ = -92;
}
Expand Down
2 changes: 2 additions & 0 deletions src/tools/rust-analyzer/crates/hir-expand/src/name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,10 @@ pub mod known {
u32,
u64,
u128,
f16,
f32,
f64,
f128,
bool,
char,
str,
Expand Down
1 change: 1 addition & 0 deletions src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ triomphe.workspace = true
nohash-hasher.workspace = true
typed-arena = "2.0.1"
indexmap.workspace = true
rustc_apfloat = "0.2.0"

ra-ap-rustc_abi.workspace = true
ra-ap-rustc_index.workspace = true
Expand Down
2 changes: 2 additions & 0 deletions src/tools/rust-analyzer/crates/hir-ty/src/chalk_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,10 @@ impl TyExt for Ty {
TyKind::Scalar(Scalar::Bool) => Some(BuiltinType::Bool),
TyKind::Scalar(Scalar::Char) => Some(BuiltinType::Char),
TyKind::Scalar(Scalar::Float(fty)) => Some(BuiltinType::Float(match fty {
FloatTy::F128 => BuiltinFloat::F128,
FloatTy::F64 => BuiltinFloat::F64,
FloatTy::F32 => BuiltinFloat::F32,
FloatTy::F16 => BuiltinFloat::F16,
})),
TyKind::Scalar(Scalar::Int(ity)) => Some(BuiltinType::Int(match ity {
IntTy::Isize => BuiltinInt::Isize,
Expand Down
26 changes: 26 additions & 0 deletions src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use base_db::FileId;
use chalk_ir::Substitution;
use hir_def::db::DefDatabase;
use rustc_apfloat::{
ieee::{Half as f16, Quad as f128},
Float,
};
use test_fixture::WithFixture;
use test_utils::skip_slow_tests;

Expand Down Expand Up @@ -140,6 +144,14 @@ fn bit_op() {

#[test]
fn floating_point() {
check_number(
r#"const GOAL: f128 = 2.0 + 3.0 * 5.5 - 8.;"#,
"10.5".parse::<f128>().unwrap().to_bits() as i128,
);
check_number(
r#"const GOAL: f128 = -90.0 + 36.0;"#,
"-54.0".parse::<f128>().unwrap().to_bits() as i128,
);
check_number(
r#"const GOAL: f64 = 2.0 + 3.0 * 5.5 - 8.;"#,
i128::from_le_bytes(pad16(&f64::to_le_bytes(10.5), true)),
Expand All @@ -152,6 +164,20 @@ fn floating_point() {
r#"const GOAL: f32 = -90.0 + 36.0;"#,
i128::from_le_bytes(pad16(&f32::to_le_bytes(-54.0), true)),
);
check_number(
r#"const GOAL: f16 = 2.0 + 3.0 * 5.5 - 8.;"#,
i128::from_le_bytes(pad16(
&u16::try_from("10.5".parse::<f16>().unwrap().to_bits()).unwrap().to_le_bytes(),
true,
)),
);
check_number(
r#"const GOAL: f16 = -90.0 + 36.0;"#,
i128::from_le_bytes(pad16(
&u16::try_from("-54.0".parse::<f16>().unwrap().to_bits()).unwrap().to_le_bytes(),
true,
)),
);
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ fn likely() {

#[test]
fn floating_point() {
// FIXME(#17451): Add `f16` and `f128` tests once intrinsics are added.
check_number(
r#"
extern "rust-intrinsic" {
Expand Down
26 changes: 26 additions & 0 deletions src/tools/rust-analyzer/crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ use hir_expand::name::Name;
use intern::{Internable, Interned};
use itertools::Itertools;
use la_arena::ArenaMap;
use rustc_apfloat::{
ieee::{Half as f16, Quad as f128},
Float,
};
use smallvec::SmallVec;
use stdx::{never, IsNoneOr};
use triomphe::Arc;
Expand Down Expand Up @@ -545,6 +549,17 @@ fn render_const_scalar(
write!(f, "{it}")
}
Scalar::Float(fl) => match fl {
chalk_ir::FloatTy::F16 => {
// FIXME(#17451): Replace with builtins once they are stabilised.
let it = f16::from_bits(u16::from_le_bytes(b.try_into().unwrap()).into());
let s = it.to_string();
if s.strip_prefix('-').unwrap_or(&s).chars().all(|c| c.is_ascii_digit()) {
// Match Rust debug formatting
write!(f, "{s}.0")
} else {
write!(f, "{s}")
}
}
chalk_ir::FloatTy::F32 => {
let it = f32::from_le_bytes(b.try_into().unwrap());
write!(f, "{it:?}")
Expand All @@ -553,6 +568,17 @@ fn render_const_scalar(
let it = f64::from_le_bytes(b.try_into().unwrap());
write!(f, "{it:?}")
}
chalk_ir::FloatTy::F128 => {
// FIXME(#17451): Replace with builtins once they are stabilised.
let it = f128::from_bits(u128::from_le_bytes(b.try_into().unwrap()));
let s = it.to_string();
if s.strip_prefix('-').unwrap_or(&s).chars().all(|c| c.is_ascii_digit()) {
// Match Rust debug formatting
write!(f, "{s}.0")
} else {
write!(f, "{s}")
}
}
},
},
TyKind::Ref(_, _, t) => match t.kind(Interner) {
Expand Down
2 changes: 2 additions & 0 deletions src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,10 @@ pub fn layout_of_ty_query(
chalk_ir::Scalar::Float(f) => scalar(
dl,
Primitive::Float(match f {
FloatTy::F16 => Float::F16,
FloatTy::F32 => Float::F32,
FloatTy::F64 => Float::F64,
FloatTy::F128 => Float::F128,
}),
),
},
Expand Down
1 change: 1 addition & 0 deletions src/tools/rust-analyzer/crates/hir-ty/src/layout/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ fn enums() {

#[test]
fn primitives() {
// FIXME(#17451): Add `f16` and `f128` once they are stabilised.
size_and_align! {
struct Goal(i32, i128, isize, usize, f32, f64, bool, char);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,11 @@ pub(crate) const ALL_INT_FPS: [TyFingerprint; 12] = [
TyFingerprint::Scalar(Scalar::Uint(UintTy::Usize)),
];

pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 2] = [
pub(crate) const ALL_FLOAT_FPS: [TyFingerprint; 4] = [
TyFingerprint::Scalar(Scalar::Float(FloatTy::F16)),
TyFingerprint::Scalar(Scalar::Float(FloatTy::F32)),
TyFingerprint::Scalar(Scalar::Float(FloatTy::F64)),
TyFingerprint::Scalar(Scalar::Float(FloatTy::F128)),
];

type TraitFpMap = FxHashMap<TraitId, FxHashMap<Option<TyFingerprint>, Box<[ImplId]>>>;
Expand Down
Loading

0 comments on commit 69424f7

Please sign in to comment.