Unnamed repository; edit this file 'description' to name the repository.
Do not render meta info when hovering usages
Lukas Wirth 2024-10-29
parent 80e9d01 · commit 3741b86
-rw-r--r--crates/ide/src/hover.rs33
-rw-r--r--crates/ide/src/hover/render.rs74
-rw-r--r--crates/ide/src/hover/tests.rs99
-rw-r--r--crates/ide/src/static_index.rs1
4 files changed, 124 insertions, 83 deletions
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs
index 6cac4f1ee4..332dfacbb4 100644
--- a/crates/ide/src/hover.rs
+++ b/crates/ide/src/hover.rs
@@ -158,7 +158,7 @@ fn hover_offset(
if let Some(doc_comment) = token_as_doc_comment(&original_token) {
cov_mark::hit!(no_highlight_on_comment_hover);
return doc_comment.get_definition_with_descend_at(sema, offset, |def, node, range| {
- let res = hover_for_definition(sema, file_id, def, &node, None, config, edition);
+ let res = hover_for_definition(sema, file_id, def, &node, None, false, config, edition);
Some(RangeInfo::new(range, res))
});
}
@@ -172,6 +172,7 @@ fn hover_offset(
Definition::from(resolution?),
&original_token.parent()?,
None,
+ false,
config,
edition,
);
@@ -218,6 +219,7 @@ fn hover_offset(
break 'a vec![(
Definition::Macro(macro_),
sema.resolve_macro_call_arm(&macro_call),
+ false,
node,
)];
}
@@ -234,19 +236,34 @@ fn hover_offset(
decl,
..
}) => {
- vec![(Definition::ExternCrateDecl(decl), None, node)]
+ vec![(Definition::ExternCrateDecl(decl), None, false, node)]
}
class => {
- multizip((class.definitions(), iter::repeat(None), iter::repeat(node)))
- .collect::<Vec<_>>()
+ let is_def = matches!(class, IdentClass::NameClass(_));
+ multizip((
+ class.definitions(),
+ iter::repeat(None),
+ iter::repeat(is_def),
+ iter::repeat(node),
+ ))
+ .collect::<Vec<_>>()
}
}
}
.into_iter()
- .unique_by(|&(def, _, _)| def)
- .map(|(def, macro_arm, node)| {
- hover_for_definition(sema, file_id, def, &node, macro_arm, config, edition)
+ .unique_by(|&(def, _, _, _)| def)
+ .map(|(def, macro_arm, hovered_definition, node)| {
+ hover_for_definition(
+ sema,
+ file_id,
+ def,
+ &node,
+ macro_arm,
+ hovered_definition,
+ config,
+ edition,
+ )
})
.collect::<Vec<_>>(),
)
@@ -366,6 +383,7 @@ pub(crate) fn hover_for_definition(
def: Definition,
scope_node: &SyntaxNode,
macro_arm: Option<u32>,
+ hovered_definition: bool,
config: &HoverConfig,
edition: Edition,
) -> HoverResult {
@@ -397,6 +415,7 @@ pub(crate) fn hover_for_definition(
famous_defs.as_ref(),
&notable_traits,
macro_arm,
+ hovered_definition,
config,
edition,
);
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index a31b14dbd3..37addfd49a 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -419,6 +419,7 @@ pub(super) fn definition(
famous_defs: Option<&FamousDefs<'_, '_>>,
notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)],
macro_arm: Option<u32>,
+ hovered_definition: bool,
config: &HoverConfig,
edition: Edition,
) -> Markup {
@@ -456,7 +457,7 @@ pub(super) fn definition(
_ => def.label(db, edition),
};
let docs = def.docs(db, famous_defs, edition);
- let value = (|| match def {
+ let value = || match def {
Definition::Variant(it) => {
if !it.parent_enum(db).is_data_carrying(db) {
match it.eval(db) {
@@ -494,9 +495,9 @@ pub(super) fn definition(
Some(body.to_string())
}
_ => None,
- })();
+ };
- let layout_info = match def {
+ let layout_info = || match def {
Definition::Field(it) => render_memory_layout(
config.memory_layout,
|| it.layout(db),
@@ -529,12 +530,13 @@ pub(super) fn definition(
_ => None,
};
- let dyn_compatibility_info = if let Definition::Trait(it) = def {
- let mut dyn_compatibility_info = String::new();
- render_dyn_compatibility(db, &mut dyn_compatibility_info, it.dyn_compatibility(db));
- Some(dyn_compatibility_info)
- } else {
- None
+ let dyn_compatibility_info = || match def {
+ Definition::Trait(it) => {
+ let mut dyn_compatibility_info = String::new();
+ render_dyn_compatibility(db, &mut dyn_compatibility_info, it.dyn_compatibility(db));
+ Some(dyn_compatibility_info)
+ }
+ _ => None,
};
let mut desc = String::new();
@@ -542,16 +544,18 @@ pub(super) fn definition(
desc.push_str(&notable_traits);
desc.push('\n');
}
- if let Some(layout_info) = layout_info {
- desc.push_str(&layout_info);
- desc.push('\n');
- }
- if let Some(dyn_compatibility_info) = dyn_compatibility_info {
- desc.push_str(&dyn_compatibility_info);
- desc.push('\n');
+ if hovered_definition {
+ if let Some(layout_info) = layout_info() {
+ desc.push_str(&layout_info);
+ desc.push('\n');
+ }
+ if let Some(dyn_compatibility_info) = dyn_compatibility_info() {
+ desc.push_str(&dyn_compatibility_info);
+ desc.push('\n');
+ }
}
desc.push_str(&label);
- if let Some(value) = value {
+ if let Some(value) = value() {
desc.push_str(" = ");
desc.push_str(&value);
}
@@ -994,55 +998,53 @@ fn render_dyn_compatibility(
safety: Option<DynCompatibilityViolation>,
) {
let Some(osv) = safety else {
- buf.push_str("// Dyn Compatible: Yes");
+ buf.push_str("// Is Dyn compatible");
return;
};
- buf.push_str("// Dyn Compatible: No\n// - Reason: ");
+ buf.push_str("// Is not Dyn compatible due to ");
match osv {
DynCompatibilityViolation::SizedSelf => {
- buf.push_str("has a `Self: Sized` bound");
+ buf.push_str("having a `Self: Sized` bound");
}
DynCompatibilityViolation::SelfReferential => {
- buf.push_str("has a bound that references `Self`");
+ buf.push_str("having a bound that references `Self`");
}
DynCompatibilityViolation::Method(func, mvc) => {
let name = hir::Function::from(func).name(db);
- format_to!(
- buf,
- "has a method `{}` that is non dispatchable because of:\n// - ",
- name.as_str()
- );
+ format_to!(buf, "having a method `{}` that is not dispatchable due to ", name.as_str());
let desc = match mvc {
MethodViolationCode::StaticMethod => "missing a receiver",
- MethodViolationCode::ReferencesSelfInput => "a parameter references `Self`",
- MethodViolationCode::ReferencesSelfOutput => "the return type references `Self`",
+ MethodViolationCode::ReferencesSelfInput => "having a parameter referencing `Self`",
+ MethodViolationCode::ReferencesSelfOutput => "the return type referencing `Self`",
MethodViolationCode::ReferencesImplTraitInTrait => {
- "the return type contains `impl Trait`"
+ "the return type containing `impl Trait`"
}
MethodViolationCode::AsyncFn => "being async",
MethodViolationCode::WhereClauseReferencesSelf => {
- "a where clause references `Self`"
+ "a where clause referencing `Self`"
+ }
+ MethodViolationCode::Generic => "having a const or type generic parameter",
+ MethodViolationCode::UndispatchableReceiver => {
+ "having a non-dispatchable receiver type"
}
- MethodViolationCode::Generic => "a non-lifetime generic parameter",
- MethodViolationCode::UndispatchableReceiver => "a non-dispatchable receiver type",
};
buf.push_str(desc);
}
DynCompatibilityViolation::AssocConst(const_) => {
let name = hir::Const::from(const_).name(db);
if let Some(name) = name {
- format_to!(buf, "has an associated constant `{}`", name.as_str());
+ format_to!(buf, "having an associated constant `{}`", name.as_str());
} else {
- buf.push_str("has an associated constant");
+ buf.push_str("having an associated constant");
}
}
DynCompatibilityViolation::GAT(alias) => {
let name = hir::TypeAlias::from(alias).name(db);
- format_to!(buf, "has a generic associated type `{}`", name.as_str());
+ format_to!(buf, "having a generic associated type `{}`", name.as_str());
}
DynCompatibilityViolation::HasNonCompatibleSuperTrait(super_trait) => {
let name = hir::Trait::from(super_trait).name(db);
- format_to!(buf, "has a dyn incompatible supertrait `{}`", name.as_str());
+ format_to!(buf, "having a dyn incompatible supertrait `{}`", name.as_str());
}
}
}
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index 3e40263041..c44d6b78d1 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -260,7 +260,6 @@ fn foo() {
*local*
```rust
- // size = 4, align = 4
let local: i32
```
"#]],
@@ -819,7 +818,6 @@ fn main() {
```
```rust
- // size = 4, align = 4, offset = 0
pub field_a: u32
```
"#]],
@@ -867,7 +865,6 @@ fn main() {
```
```rust
- // size = 4, align = 4, offset = 0
pub 0: u32
```
"#]],
@@ -888,7 +885,6 @@ fn foo(foo: Foo) {
```
```rust
- // size = 4, align = 4, offset = 0
pub 0: u32
```
"#]],
@@ -1670,7 +1666,6 @@ fn hover_for_local_variable() {
*foo*
```rust
- // size = 4, align = 4
foo: i32
```
"#]],
@@ -1700,7 +1695,6 @@ fn hover_local_var_edge() {
*foo*
```rust
- // size = 4, align = 4
foo: i32
```
"#]],
@@ -1985,7 +1979,6 @@ fn y() {
*x*
```rust
- // size = 4, align = 4
let x: i32
```
"#]],
@@ -2116,7 +2109,6 @@ fn foo(bar:u32) { let a = id!(ba$0r); }
*bar*
```rust
- // size = 4, align = 4
bar: u32
```
"#]],
@@ -2135,7 +2127,6 @@ fn foo(bar:u32) { let a = id!(ba$0r); }
*bar*
```rust
- // size = 4, align = 4
bar: u32
```
"#]],
@@ -2537,7 +2528,6 @@ fn foo() { let bar = Ba$0r; }
```
```rust
- // size = 0, align = 1
struct Bar
```
@@ -2574,7 +2564,6 @@ fn foo() { let bar = Ba$0r; }
```
```rust
- // size = 0, align = 1
struct Bar
```
@@ -2604,7 +2593,6 @@ fn foo() { let bar = Ba$0r; }
```
```rust
- // size = 0, align = 1
struct Bar
```
@@ -5750,7 +5738,6 @@ fn foo(e: E) {
```
```rust
- // size = 0, align = 1
A = 3
```
@@ -6036,7 +6023,6 @@ pub fn gimme() -> theitem::TheItem {
```
```rust
- // size = 0, align = 1
pub struct TheItem
```
@@ -6185,7 +6171,6 @@ mod string {
```
```rust
- // size = 0, align = 1
struct String
```
@@ -6948,7 +6933,6 @@ foo_macro!(
```
```rust
- // size = 0, align = 1
pub struct Foo
```
@@ -6974,7 +6958,6 @@ pub struct Foo(i32);
```
```rust
- // size = 4, align = 4
pub struct Foo(i32)
```
@@ -7175,7 +7158,6 @@ impl T$0 for () {}
```
```rust
- // Dyn Compatible: Yes
trait T {}
```
"#]],
@@ -7195,7 +7177,6 @@ impl T$0 for () {}
```
```rust
- // Dyn Compatible: Yes
trait T {}
```
"#]],
@@ -7219,9 +7200,6 @@ impl T$0 for () {}
```
```rust
- // Dyn Compatible: No
- // - Reason: has a method `func` that is non dispatchable because of:
- // - missing a receiver
trait T { /* … */ }
```
"#]],
@@ -7245,9 +7223,6 @@ impl T$0 for () {}
```
```rust
- // Dyn Compatible: No
- // - Reason: has a method `func` that is non dispatchable because of:
- // - missing a receiver
trait T {
fn func();
const FLAG: i32;
@@ -7275,9 +7250,6 @@ impl T$0 for () {}
```
```rust
- // Dyn Compatible: No
- // - Reason: has a method `func` that is non dispatchable because of:
- // - missing a receiver
trait T {
fn func();
const FLAG: i32;
@@ -7305,9 +7277,6 @@ impl T$0 for () {}
```
```rust
- // Dyn Compatible: No
- // - Reason: has a method `func` that is non dispatchable because of:
- // - missing a receiver
trait T {
fn func();
const FLAG: i32;
@@ -7784,7 +7753,6 @@ fn test() {
```
```rust
- // size = 4, align = 4, offset = 0
f: u32
```
"#]],
@@ -7825,7 +7793,6 @@ fn test() {
*foo*
```rust
- // size = 4, align = 4
let foo: i32
```
"#]],
@@ -7846,7 +7813,6 @@ format_args!("{aaaaa$0}");
*aaaaa*
```rust
- // size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str
```
"#]],
@@ -7867,7 +7833,6 @@ format_args!("{$0aaaaa}");
*aaaaa*
```rust
- // size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str
```
"#]],
@@ -7888,7 +7853,6 @@ format_args!(r"{$0aaaaa}");
*aaaaa*
```rust
- // size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str
```
"#]],
@@ -7914,7 +7878,6 @@ foo!(r"{$0aaaaa}");
*aaaaa*
```rust
- // size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str
```
"#]],
@@ -8419,7 +8382,6 @@ impl Iterator for S {
```rust
// Implements notable traits: Notable, Future<Output = u32>, Iterator<Item = S>
- // size = 0, align = 1
struct S
```
"#]],
@@ -8678,7 +8640,6 @@ fn test() {
*f*
```rust
- // size = 0, align = 1
let f: fn bar<3>(bool)
```
"#]],
@@ -9159,7 +9120,6 @@ use a::A$0;
```
```rust
- // size = 0, align = 1
pub type A = B
```
@@ -9171,3 +9131,62 @@ use a::A$0;
"#]],
);
}
+
+#[test]
+fn dyn_compat() {
+ check(
+ r#"
+trait Compat$0 {}
+"#,
+ expect![[r#"
+ *Compat*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ // Is Dyn compatible
+ trait Compat
+ ```
+ "#]],
+ );
+ check(
+ r#"
+trait UnCompat$0 {
+ fn f<T>() {}
+}
+"#,
+ expect![[r#"
+ *UnCompat*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ // Is not Dyn compatible due to having a method `f` that is not dispatchable due to missing a receiver
+ trait UnCompat
+ ```
+ "#]],
+ );
+ check(
+ r#"
+trait UnCompat {
+ fn f<T>() {}
+}
+fn f<T: UnCompat$0>
+"#,
+ expect![[r#"
+ *UnCompat*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ trait UnCompat
+ ```
+ "#]],
+ );
+}
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs
index 1cbe8c62a8..0f4b5e7d87 100644
--- a/crates/ide/src/static_index.rs
+++ b/crates/ide/src/static_index.rs
@@ -212,6 +212,7 @@ impl StaticIndex<'_> {
def,
&node,
None,
+ false,
&hover_config,
edition,
)),