Skip to content

Commit 593ae9e

Browse files
committed
fix: f32 and f64 representation during lowering
1 parent d7c1474 commit 593ae9e

File tree

5 files changed

+87
-4
lines changed

5 files changed

+87
-4
lines changed

crates/hir-def/src/body/lower.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -968,7 +968,7 @@ impl From<ast::LiteralKind> for Literal {
968968
// FIXME: these should have actual values filled in, but unsure on perf impact
969969
LiteralKind::IntNumber(lit) => {
970970
if let builtin @ Some(_) = lit.suffix().and_then(BuiltinFloat::from_suffix) {
971-
Literal::Float(Default::default(), builtin)
971+
Literal::Float(lit.float_value().unwrap_or(Default::default()), builtin)
972972
} else if let builtin @ Some(_) = lit.suffix().and_then(BuiltinInt::from_suffix) {
973973
Literal::Int(lit.value().unwrap_or(0) as i128, builtin)
974974
} else {
@@ -978,7 +978,7 @@ impl From<ast::LiteralKind> for Literal {
978978
}
979979
LiteralKind::FloatNumber(lit) => {
980980
let ty = lit.suffix().and_then(BuiltinFloat::from_suffix);
981-
Literal::Float(Default::default(), ty)
981+
Literal::Float(lit.value().unwrap_or(Default::default()), ty)
982982
}
983983
LiteralKind::ByteString(bs) => {
984984
let text = bs.value().map(Box::from).unwrap_or_else(Default::default);

crates/hir-def/src/expr.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ use crate::{
2323
BlockId,
2424
};
2525

26+
use syntax::ast::FloatTypeWrapper;
27+
2628
pub use syntax::ast::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp};
2729

2830
pub type ExprId = Idx<Expr>;
@@ -46,7 +48,10 @@ pub enum Literal {
4648
Bool(bool),
4749
Int(i128, Option<BuiltinInt>),
4850
Uint(u128, Option<BuiltinUint>),
49-
Float(u64, Option<BuiltinFloat>), // FIXME: f64 is not Eq
51+
// Here we are using a wrapper around float because f32 and f64 do not implement Eq, so they
52+
// could not be used directly here, to understand how the wrapper works go to definition of
53+
// FloatTypeWrapper
54+
Float(FloatTypeWrapper, Option<BuiltinFloat>),
5055
}
5156

5257
#[derive(Debug, Clone, Eq, PartialEq)]

crates/ide/src/hover/tests.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,6 +3598,52 @@ const FOO$0: u8 = b'\x61';
35983598
This is a doc
35993599
"#]],
36003600
);
3601+
3602+
// show float literal
3603+
check(
3604+
r#"
3605+
/// This is a doc
3606+
const FOO$0: f64 = 1.0234;
3607+
"#,
3608+
expect![[r#"
3609+
*FOO*
3610+
3611+
```rust
3612+
test
3613+
```
3614+
3615+
```rust
3616+
const FOO: f64 = 1.0234
3617+
```
3618+
3619+
---
3620+
3621+
This is a doc
3622+
"#]],
3623+
);
3624+
3625+
//show float typecasted
3626+
check(
3627+
r#"
3628+
/// This is a doc
3629+
const FOO$0: f32 = 1f32;
3630+
"#,
3631+
expect![[r#"
3632+
*FOO*
3633+
3634+
```rust
3635+
test
3636+
```
3637+
3638+
```rust
3639+
const FOO: f32 = 1
3640+
```
3641+
3642+
---
3643+
3644+
This is a doc
3645+
"#]],
3646+
);
36013647
}
36023648

36033649
#[test]

crates/syntax/src/ast.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ pub use self::{
2525
SlicePatComponents, StructKind, TypeBoundKind, TypeOrConstParam, VisibilityKind,
2626
},
2727
operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp},
28-
token_ext::{CommentKind, CommentPlacement, CommentShape, IsString, QuoteOffsets, Radix},
28+
token_ext::{
29+
CommentKind, CommentPlacement, CommentShape, FloatTypeWrapper, IsString, QuoteOffsets,
30+
Radix,
31+
},
2932
traits::{
3033
AttrDocCommentIter, DocCommentIter, HasArgList, HasAttrs, HasDocComments, HasGenericParams,
3134
HasLoopBody, HasModuleItem, HasName, HasTypeBounds, HasVisibility,

crates/syntax/src/ast/token_ext.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,30 @@ impl ast::IntNumber {
319319
Some(suffix)
320320
}
321321
}
322+
323+
pub fn float_value(&self) -> Option<FloatTypeWrapper> {
324+
let (_, text, _) = self.split_into_parts();
325+
let float_value = text.parse::<f64>().ok()?;
326+
Some(FloatTypeWrapper::new(float_value))
327+
}
328+
}
329+
330+
// We convert float values into bits and that's how we don't need to deal with f32 and f64.
331+
// For PartialEq, bits comparison should work, as ordering is not important
332+
// https://github.com/rust-lang/rust-analyzer/issues/12380#issuecomment-1137284360
333+
#[derive(Default, Debug, Clone, Eq, PartialEq)]
334+
pub struct FloatTypeWrapper(u64);
335+
336+
impl FloatTypeWrapper {
337+
fn new(value: f64) -> Self {
338+
Self(value.to_bits())
339+
}
340+
}
341+
342+
impl std::fmt::Display for FloatTypeWrapper {
343+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
344+
write!(f, "{}", f64::from_bits(self.0))
345+
}
322346
}
323347

324348
impl ast::FloatNumber {
@@ -331,6 +355,11 @@ impl ast::FloatNumber {
331355
}
332356
Some(&text[suffix_start..])
333357
}
358+
359+
pub fn value(&self) -> Option<FloatTypeWrapper> {
360+
let float_value = self.text().parse::<f64>().ok()?;
361+
Some(FloatTypeWrapper::new(float_value))
362+
}
334363
}
335364

336365
#[derive(Debug, PartialEq, Eq, Copy, Clone)]

0 commit comments

Comments
 (0)