Auto merge of #13185 - ChayimFriedman2:insert-ws-in-static-const-macro, r=Veykril

fix: Insert whitespaces into static & const bodies if they are expanded from macro on hover

Partially fixes #13143.

To resolve the other part we need to expand macros in unevaluated static & const bodies, and I'm not sure we want to. If for example it includes a call to `assert!()`, expanding it will lead to worse hover.
This commit is contained in:
bors 2022-09-05 11:10:40 +00:00
commit 5be2e6574d
3 changed files with 77 additions and 4 deletions

View File

@ -95,7 +95,7 @@ pub fn insert_ws_into(syn: SyntaxNode) -> SyntaxNode {
AS_KW | DYN_KW | IMPL_KW | CONST_KW => { AS_KW | DYN_KW | IMPL_KW | CONST_KW => {
mods.push(do_ws(after, tok)); mods.push(do_ws(after, tok));
} }
T![;] => { T![;] if is_next(|it| it != R_CURLY, true) => {
if indent > 0 { if indent > 0 {
mods.push(do_indent(after, tok, indent)); mods.push(do_indent(after, tok, indent));
} }

View File

@ -2,12 +2,13 @@
use std::fmt::Display; use std::fmt::Display;
use either::Either; use either::Either;
use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HirDisplay, Semantics, TypeInfo}; use hir::{AsAssocItem, AttributeTemplate, HasAttrs, HasSource, HirDisplay, Semantics, TypeInfo};
use ide_db::{ use ide_db::{
base_db::SourceDatabase, base_db::SourceDatabase,
defs::Definition, defs::Definition,
famous_defs::FamousDefs, famous_defs::FamousDefs,
generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES}, generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
syntax_helpers::insert_whitespace_into_node,
RootDatabase, RootDatabase,
}; };
use itertools::Itertools; use itertools::Itertools;
@ -350,10 +351,24 @@ pub(super) fn definition(
let body = it.eval(db); let body = it.eval(db);
match body { match body {
Ok(x) => Some(format!("{}", x)), 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::Trait(it) => label_and_docs(db, it),
Definition::TypeAlias(it) => label_and_docs(db, it), Definition::TypeAlias(it) => label_and_docs(db, it),
Definition::BuiltinType(it) => { Definition::BuiltinType(it) => {

View File

@ -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;
}
```
"#]],
);
}