diff --git a/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs b/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs index f54ae6c920..8bc093a85a 100644 --- a/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs +++ b/crates/ide-db/src/syntax_helpers/insert_whitespace_into_node.rs @@ -95,7 +95,7 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode { AS_KW | DYN_KW | IMPL_KW | CONST_KW => { mods.push(do_ws(after, tok)); } - T![;] => { + T![;] if is_next(|it| it != R_CURLY, true) => { if indent > 0 { mods.push(do_indent(after, tok, indent)); } diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs index d52adaee53..c5c50d88dd 100644 --- a/crates/ide/src/hover/render.rs +++ b/crates/ide/src/hover/render.rs @@ -2,12 +2,13 @@ use std::fmt::Display; use either::Either; -use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HirDisplay, Semantics, TypeInfo}; +use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo}; use ide_db::{ base_db::SourceDatabase, defs::Definition, famous_defs::FamousDefs, generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES}, + syntax_helpers::insert_whitespace_into_node, RootDatabase, }; use itertools::Itertools; @@ -350,10 +351,24 @@ pub(super) fn definition( let body = it.eval(db); match body { Ok(x) => Some(format!("{}", x)), - Err(_) => it.value(db).map(|x| format!("{}", x)), + Err(_) => { + let source = it.source(db)?; + let mut body = source.value.body()?.syntax().clone(); + if source.file_id.is_macro() { + body = insert_whitespace_into_node::insert_ws_into(body); + } + Some(body.to_string()) + } } }), - Definition::Static(it) => label_value_and_docs(db, it, |it| it.value(db)), + Definition::Static(it) => label_value_and_docs(db, it, |it| { + let source = it.source(db)?; + let mut body = source.value.body()?.syntax().clone(); + if source.file_id.is_macro() { + body = insert_whitespace_into_node::insert_ws_into(body); + } + Some(body.to_string()) + }), Definition::Trait(it) => label_and_docs(db, it), Definition::TypeAlias(it) => label_and_docs(db, it), Definition::BuiltinType(it) => { diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 685eb4521e..4b8b47783d 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -5113,3 +5113,61 @@ fn f() { "#]], ); } + +#[test] +fn static_const_macro_expanded_body() { + check( + r#" +macro_rules! m { + () => { + pub const V: i8 = { + let e = 123; + f(e) // Prevent const eval from evaluating this constant, we want to print the body's code. + }; + }; +} +m!(); +fn main() { $0V; } +"#, + expect![[r#" + *V* + + ```rust + test + ``` + + ```rust + pub const V: i8 = { + let e = 123; + f(e) + } + ``` + "#]], + ); + check( + r#" +macro_rules! m { + () => { + pub static V: i8 = { + let e = 123; + }; + }; +} +m!(); +fn main() { $0V; } +"#, + expect![[r#" + *V* + + ```rust + test + ``` + + ```rust + pub static V: i8 = { + let e = 123; + } + ``` + "#]], + ); +}