diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2024-05-13 12:26:45 +0200 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2024-05-13 12:26:45 +0200 |
| commit | a73973934f86a1e0c68d32752bb48123e92a4c63 (patch) | |
| tree | 8bf9ea682af331266d6323b527334c527c6454f7 | |
| parent | 6a3556b779f15c35b7a0e3a3631501c7d9b9e154 (diff) | |
| download | rust-a73973934f86a1e0c68d32752bb48123e92a4c63.tar.gz rust-a73973934f86a1e0c68d32752bb48123e92a4c63.zip | |
Fix literal hovers being confusing and wrong for floats
| -rw-r--r-- | src/tools/rust-analyzer/crates/hir/src/lib.rs | 14 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide/src/hover.rs | 57 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide/src/hover/render.rs | 56 | ||||
| -rw-r--r-- | src/tools/rust-analyzer/crates/ide/src/hover/tests.rs | 141 |
4 files changed, 171 insertions, 97 deletions
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 149e75c45cb..275c1390f27 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -2543,6 +2543,20 @@ impl BuiltinType { matches!(self.inner, hir_def::builtin_type::BuiltinType::Float(_)) } + pub fn is_f32(&self) -> bool { + matches!( + self.inner, + hir_def::builtin_type::BuiltinType::Float(hir_def::builtin_type::BuiltinFloat::F32) + ) + } + + pub fn is_f64(&self) -> bool { + matches!( + self.inner, + hir_def::builtin_type::BuiltinType::Float(hir_def::builtin_type::BuiltinFloat::F64) + ) + } + pub fn is_char(&self) -> bool { matches!(self.inner, hir_def::builtin_type::BuiltinType::Char) } diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs index f9210da5fd4..6b73afe08ea 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs @@ -298,61 +298,8 @@ fn hover_simple( }) // tokens .or_else(|| { - let mut res = HoverResult::default(); - match_ast! { - match original_token { - ast::String(string) => { - res.markup = Markup::fenced_block_text(format_args!("{}", string.value()?)); - }, - ast::ByteString(string) => { - res.markup = Markup::fenced_block_text(format_args!("{:?}", string.value()?)); - }, - ast::CString(string) => { - let val = string.value()?; - res.markup = Markup::fenced_block_text(format_args!("{}", std::str::from_utf8(val.as_ref()).ok()?)); - }, - ast::Char(char) => { - let mut res = HoverResult::default(); - res.markup = Markup::fenced_block_text(format_args!("{}", char.value()?)); - }, - ast::Byte(byte) => { - res.markup = Markup::fenced_block_text(format_args!("0x{:X}", byte.value()?)); - }, - ast::FloatNumber(num) => { - res.markup = if num.suffix() == Some("f32") { - match num.value_f32() { - Ok(num) => { - Markup::fenced_block_text(format_args!("{num} (bits: 0x{:X})", num.to_bits())) - }, - Err(e) => { - Markup::fenced_block_text(format_args!("{e}")) - }, - } - } else { - match num.value() { - Ok(num) => { - Markup::fenced_block_text(format_args!("{num} (bits: 0x{:X})", num.to_bits())) - }, - Err(e) => { - Markup::fenced_block_text(format_args!("{e}")) - }, - } - }; - }, - ast::IntNumber(num) => { - res.markup = match num.value() { - Ok(num) => { - Markup::fenced_block_text(format_args!("{num} (0x{num:X}|0b{num:b})")) - }, - Err(e) => { - Markup::fenced_block_text(format_args!("{e}")) - }, - }; - }, - _ => return None - } - } - Some(res) + render::literal(sema, original_token.clone()) + .map(|markup| HoverResult { markup, actions: vec![] }) }); result.map(|mut res: HoverResult| { diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs index ee96767411a..674b32a7f5c 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs @@ -17,11 +17,7 @@ use ide_db::{ }; use itertools::Itertools; use stdx::format_to; -use syntax::{ - algo, - ast::{self, RecordPat}, - match_ast, AstNode, Direction, SyntaxToken, T, -}; +use syntax::{algo, ast, match_ast, AstNode, AstToken, Direction, SyntaxToken, T}; use crate::{ doc_links::{remove_links, rewrite_links}, @@ -276,7 +272,7 @@ pub(super) fn keyword( pub(super) fn struct_rest_pat( sema: &Semantics<'_, RootDatabase>, _config: &HoverConfig, - pattern: &RecordPat, + pattern: &ast::RecordPat, ) -> HoverResult { let missing_fields = sema.record_pattern_missing_fields(pattern); @@ -526,6 +522,54 @@ pub(super) fn definition( markup(docs.map(Into::into), desc, mod_path) } +pub(super) fn literal(sema: &Semantics<'_, RootDatabase>, token: SyntaxToken) -> Option<Markup> { + let lit = token.parent().and_then(ast::Literal::cast)?; + let ty = if let Some(p) = lit.syntax().parent().and_then(ast::Pat::cast) { + sema.type_of_pat(&p)? + } else { + sema.type_of_expr(&ast::Expr::Literal(lit))? + } + .original; + + let value = match_ast! { + match token { + ast::String(string) => Ok(string.value()?.to_string()), + ast::ByteString(string) => Ok(format_args!("{:?}", string.value()?).to_string()), + ast::CString(string) => Ok(std::str::from_utf8(string.value()?.as_ref()).ok()?.to_owned()), + ast::Char(char) => Ok(char.value()?.to_string()), + ast::Byte(byte) => Ok(format!("0x{:X}", byte.value()?)), + ast::FloatNumber(num) => { + let (text, _) = num.split_into_parts(); + let text = text.replace('_', ""); + if ty.as_builtin().map(|it| it.is_f32()).unwrap_or(false) { + match text.parse::<f32>() { + Ok(num) => Ok(format!("{num} (bits: 0x{:X})", num.to_bits())), + Err(e) => Err(e.to_string()), + } + } else { + match text.parse::<f64>() { + Ok(num) => Ok(format!("{num} (bits: 0x{:X})", num.to_bits())), + Err(e) => Err(e.to_string()), + } + } + }, + ast::IntNumber(num) => match num.value() { + Ok(num) => Ok(format!("{num} (0x{num:X}|0b{num:b})")), + Err(e) => Err(e.to_string()), + }, + _ => return None + } + }; + let ty = ty.display(sema.db); + + let mut s = format!("```rust\n{ty}\n```\n___\n\n"); + match value { + Ok(value) => format_to!(s, "value of literal: {value}"), + Err(error) => format_to!(s, "invalid literal: {error}"), + } + Some(s.into()) +} + fn render_notable_trait_comment( db: &RootDatabase, notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)], diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs index f7af7950041..b5547c05148 100644 --- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs +++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs @@ -7790,9 +7790,12 @@ fn main() { "#, expect![[r#" *"🦀\u{1f980}\\\x41"* - ```text - 🦀🦀\A + ```rust + &str ``` + ___ + + value of literal: 🦀🦀\A "#]], ); check( @@ -7803,9 +7806,12 @@ fn main() { "#, expect![[r#" *r"🦀\u{1f980}\\\x41"* - ```text - 🦀\u{1f980}\\\x41 + ```rust + &str ``` + ___ + + value of literal: 🦀\u{1f980}\\\x41 "#]], ); } @@ -7820,9 +7826,12 @@ fn main() { "#, expect![[r#" *c"🦀\u{1f980}\\\x41"* - ```text - 🦀🦀\A + ```rust + &{unknown} ``` + ___ + + value of literal: 🦀🦀\A "#]], ); } @@ -7837,9 +7846,12 @@ fn main() { "#, expect![[r#" *b"\xF0\x9F\xA6\x80\\"* - ```text - [240, 159, 166, 128, 92] + ```rust + &[u8; 5] ``` + ___ + + value of literal: [240, 159, 166, 128, 92] "#]], ); check( @@ -7850,9 +7862,12 @@ fn main() { "#, expect![[r#" *br"\xF0\x9F\xA6\x80\\"* - ```text - [92, 120, 70, 48, 92, 120, 57, 70, 92, 120, 65, 54, 92, 120, 56, 48, 92, 92] + ```rust + &[u8; 18] ``` + ___ + + value of literal: [92, 120, 70, 48, 92, 120, 57, 70, 92, 120, 65, 54, 92, 120, 56, 48, 92, 92] "#]], ); } @@ -7867,9 +7882,12 @@ fn main() { "#, expect![[r#" *b'\xF0'* - ```text - 0xF0 + ```rust + u8 ``` + ___ + + value of literal: 0xF0 "#]], ); check( @@ -7880,9 +7898,12 @@ fn main() { "#, expect![[r#" *b'\\'* - ```text - 0x5C + ```rust + u8 ``` + ___ + + value of literal: 0x5C "#]], ); } @@ -7897,7 +7918,12 @@ fn main() { "#, expect![[r#" *'\x41'* + ```rust + char + ``` + ___ + value of literal: A "#]], ); check( @@ -7908,7 +7934,12 @@ fn main() { "#, expect![[r#" *'\\'* + ```rust + char + ``` + ___ + value of literal: \ "#]], ); check( @@ -7919,7 +7950,12 @@ fn main() { "#, expect![[r#" *'\u{1f980}'* + ```rust + char + ``` + ___ + value of literal: 🦀 "#]], ); } @@ -7934,9 +7970,12 @@ fn main() { "#, expect![[r#" *1.0* - ```text - 1 (bits: 0x3FF0000000000000) + ```rust + f64 ``` + ___ + + value of literal: 1 (bits: 0x3FF0000000000000) "#]], ); check( @@ -7947,9 +7986,12 @@ fn main() { "#, expect![[r#" *1.0f32* - ```text - 1 (bits: 0x3F800000) + ```rust + f32 ``` + ___ + + value of literal: 1 (bits: 0x3F800000) "#]], ); check( @@ -7960,9 +8002,12 @@ fn main() { "#, expect![[r#" *134e12* - ```text - 134000000000000 (bits: 0x42DE77D399980000) + ```rust + f64 ``` + ___ + + value of literal: 134000000000000 (bits: 0x42DE77D399980000) "#]], ); check( @@ -7973,9 +8018,12 @@ fn main() { "#, expect![[r#" *1523527134274733643531312.0* - ```text - 1523527134274733600000000 (bits: 0x44F429E9249F629B) + ```rust + f64 ``` + ___ + + value of literal: 1523527134274733600000000 (bits: 0x44F429E9249F629B) "#]], ); check( @@ -7986,9 +8034,12 @@ fn main() { "#, expect![[r#" *0.1ea123* - ```text - invalid float literal + ```rust + f64 ``` + ___ + + invalid literal: invalid float literal "#]], ); } @@ -8003,9 +8054,12 @@ fn main() { "#, expect![[r#" *34325236457856836345234* - ```text - 34325236457856836345234 (0x744C659178614489D92|0b111010001001100011001011001000101111000011000010100010010001001110110010010) + ```rust + i32 ``` + ___ + + value of literal: 34325236457856836345234 (0x744C659178614489D92|0b111010001001100011001011001000101111000011000010100010010001001110110010010) "#]], ); check( @@ -8016,9 +8070,12 @@ fn main() { "#, expect![[r#" *134_123424_21* - ```text - 13412342421 (0x31F701A95|0b1100011111011100000001101010010101) + ```rust + i32 ``` + ___ + + value of literal: 13412342421 (0x31F701A95|0b1100011111011100000001101010010101) "#]], ); check( @@ -8029,9 +8086,12 @@ fn main() { "#, expect![[r#" *0x12423423* - ```text - 306328611 (0x12423423|0b10010010000100011010000100011) + ```rust + i32 ``` + ___ + + value of literal: 306328611 (0x12423423|0b10010010000100011010000100011) "#]], ); check( @@ -8042,9 +8102,12 @@ fn main() { "#, expect![[r#" *0b1111_1111* - ```text - 255 (0xFF|0b11111111) + ```rust + i32 ``` + ___ + + value of literal: 255 (0xFF|0b11111111) "#]], ); check( @@ -8055,9 +8118,12 @@ fn main() { "#, expect![[r#" *0o12345* - ```text - 5349 (0x14E5|0b1010011100101) + ```rust + i32 ``` + ___ + + value of literal: 5349 (0x14E5|0b1010011100101) "#]], ); check( @@ -8068,9 +8134,12 @@ fn main() { "#, expect![[r#" *0xFFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_F* - ```text - number too large to fit in target type + ```rust + i32 ``` + ___ + + invalid literal: number too large to fit in target type "#]], ); } |
