@@ -17,11 +17,7 @@ use ide_db::{
1717} ;
1818use itertools:: Itertools ;
1919use stdx:: format_to;
20- use syntax:: {
21- algo,
22- ast:: { self , RecordPat } ,
23- match_ast, AstNode , Direction , SyntaxToken , T ,
24- } ;
20+ use syntax:: { algo, ast, match_ast, AstNode , AstToken , Direction , SyntaxToken , T } ;
2521
2622use crate :: {
2723 doc_links:: { remove_links, rewrite_links} ,
@@ -276,7 +272,7 @@ pub(super) fn keyword(
276272pub ( super ) fn struct_rest_pat (
277273 sema : & Semantics < ' _ , RootDatabase > ,
278274 _config : & HoverConfig ,
279- pattern : & RecordPat ,
275+ pattern : & ast :: RecordPat ,
280276) -> HoverResult {
281277 let missing_fields = sema. record_pattern_missing_fields ( pattern) ;
282278
@@ -526,6 +522,60 @@ pub(super) fn definition(
526522 markup ( docs. map ( Into :: into) , desc, mod_path)
527523}
528524
525+ pub ( super ) fn literal ( sema : & Semantics < ' _ , RootDatabase > , token : SyntaxToken ) -> Option < Markup > {
526+ let lit = token. parent ( ) . and_then ( ast:: Literal :: cast) ?;
527+ let ty = if let Some ( p) = lit. syntax ( ) . parent ( ) . and_then ( ast:: Pat :: cast) {
528+ sema. type_of_pat ( & p) ?
529+ } else {
530+ sema. type_of_expr ( & ast:: Expr :: Literal ( lit) ) ?
531+ }
532+ . original ;
533+
534+ let value = match_ast ! {
535+ match token {
536+ ast:: String ( string) => string. value( ) . as_ref( ) . map_err( |e| format!( "{e:?}" ) ) . map( ToString :: to_string) ,
537+ ast:: ByteString ( string) => string. value( ) . as_ref( ) . map_err( |e| format!( "{e:?}" ) ) . map( |it| format!( "{it:?}" ) ) ,
538+ ast:: CString ( string) => string. value( ) . as_ref( ) . map_err( |e| format!( "{e:?}" ) ) . map( |it| std:: str :: from_utf8( it) . map_or_else( |e| format!( "{e:?}" ) , ToOwned :: to_owned) ) ,
539+ ast:: Char ( char ) => char . value( ) . as_ref( ) . map_err( |e| format!( "{e:?}" ) ) . map( ToString :: to_string) ,
540+ ast:: Byte ( byte) => byte . value( ) . as_ref( ) . map_err( |e| format!( "{e:?}" ) ) . map( |it| format!( "0x{it:X}" ) ) ,
541+ ast:: FloatNumber ( num) => {
542+ let ( text, _) = num. split_into_parts( ) ;
543+ let text = text. replace( '_' , "" ) ;
544+ if ty. as_builtin( ) . map( |it| it. is_f32( ) ) . unwrap_or( false ) {
545+ match text. parse:: <f32 >( ) {
546+ Ok ( num) => Ok ( format!( "{num} (bits: 0x{:X})" , num. to_bits( ) ) ) ,
547+ Err ( e) => Err ( e. to_string( ) ) ,
548+ }
549+ } else {
550+ match text. parse:: <f64 >( ) {
551+ Ok ( num) => Ok ( format!( "{num} (bits: 0x{:X})" , num. to_bits( ) ) ) ,
552+ Err ( e) => Err ( e. to_string( ) ) ,
553+ }
554+ }
555+ } ,
556+ ast:: IntNumber ( num) => match num. value( ) {
557+ Ok ( num) => Ok ( format!( "{num} (0x{num:X}|0b{num:b})" ) ) ,
558+ Err ( e) => Err ( e. to_string( ) ) ,
559+ } ,
560+ _ => return None
561+ }
562+ } ;
563+ let ty = ty. display ( sema. db ) ;
564+
565+ let mut s = format ! ( "```rust\n {ty}\n ```\n ___\n \n " ) ;
566+ match value {
567+ Ok ( value) => {
568+ if let Some ( newline) = value. find ( '\n' ) {
569+ format_to ! ( s, "value of literal (truncated up to newline): {}" , & value[ ..newline] )
570+ } else {
571+ format_to ! ( s, "value of literal: {value}" )
572+ }
573+ }
574+ Err ( error) => format_to ! ( s, "invalid literal: {error}" ) ,
575+ }
576+ Some ( s. into ( ) )
577+ }
578+
529579fn render_notable_trait_comment (
530580 db : & RootDatabase ,
531581 notable_traits : & [ ( Trait , Vec < ( Option < Type > , Name ) > ) ] ,
0 commit comments