Do not render meta info when hovering usages

This commit is contained in:
Lukas Wirth 2024-10-29 15:33:55 +01:00
parent 25b0846e96
commit d8f6538bac
4 changed files with 124 additions and 83 deletions

View File

@ -158,7 +158,7 @@ fn hover_offset(
if let Some(doc_comment) = token_as_doc_comment(&original_token) { if let Some(doc_comment) = token_as_doc_comment(&original_token) {
cov_mark::hit!(no_highlight_on_comment_hover); cov_mark::hit!(no_highlight_on_comment_hover);
return doc_comment.get_definition_with_descend_at(sema, offset, |def, node, range| { 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)) Some(RangeInfo::new(range, res))
}); });
} }
@ -172,6 +172,7 @@ fn hover_offset(
Definition::from(resolution?), Definition::from(resolution?),
&original_token.parent()?, &original_token.parent()?,
None, None,
false,
config, config,
edition, edition,
); );
@ -218,6 +219,7 @@ fn hover_offset(
break 'a vec![( break 'a vec![(
Definition::Macro(macro_), Definition::Macro(macro_),
sema.resolve_macro_call_arm(&macro_call), sema.resolve_macro_call_arm(&macro_call),
false,
node, node,
)]; )];
} }
@ -234,19 +236,34 @@ fn hover_offset(
decl, decl,
.. ..
}) => { }) => {
vec![(Definition::ExternCrateDecl(decl), None, node)] vec![(Definition::ExternCrateDecl(decl), None, false, node)]
} }
class => { class => {
multizip((class.definitions(), iter::repeat(None), iter::repeat(node))) let is_def = matches!(class, IdentClass::NameClass(_));
.collect::<Vec<_>>() multizip((
class.definitions(),
iter::repeat(None),
iter::repeat(is_def),
iter::repeat(node),
))
.collect::<Vec<_>>()
} }
} }
} }
.into_iter() .into_iter()
.unique_by(|&(def, _, _)| def) .unique_by(|&(def, _, _, _)| def)
.map(|(def, macro_arm, node)| { .map(|(def, macro_arm, hovered_definition, node)| {
hover_for_definition(sema, file_id, def, &node, macro_arm, config, edition) hover_for_definition(
sema,
file_id,
def,
&node,
macro_arm,
hovered_definition,
config,
edition,
)
}) })
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
) )
@ -366,6 +383,7 @@ pub(crate) fn hover_for_definition(
def: Definition, def: Definition,
scope_node: &SyntaxNode, scope_node: &SyntaxNode,
macro_arm: Option<u32>, macro_arm: Option<u32>,
hovered_definition: bool,
config: &HoverConfig, config: &HoverConfig,
edition: Edition, edition: Edition,
) -> HoverResult { ) -> HoverResult {
@ -397,6 +415,7 @@ pub(crate) fn hover_for_definition(
famous_defs.as_ref(), famous_defs.as_ref(),
&notable_traits, &notable_traits,
macro_arm, macro_arm,
hovered_definition,
config, config,
edition, edition,
); );

View File

@ -419,6 +419,7 @@ pub(super) fn definition(
famous_defs: Option<&FamousDefs<'_, '_>>, famous_defs: Option<&FamousDefs<'_, '_>>,
notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)], notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)],
macro_arm: Option<u32>, macro_arm: Option<u32>,
hovered_definition: bool,
config: &HoverConfig, config: &HoverConfig,
edition: Edition, edition: Edition,
) -> Markup { ) -> Markup {
@ -456,7 +457,7 @@ pub(super) fn definition(
_ => def.label(db, edition), _ => def.label(db, edition),
}; };
let docs = def.docs(db, famous_defs, edition); let docs = def.docs(db, famous_defs, edition);
let value = (|| match def { let value = || match def {
Definition::Variant(it) => { Definition::Variant(it) => {
if !it.parent_enum(db).is_data_carrying(db) { if !it.parent_enum(db).is_data_carrying(db) {
match it.eval(db) { match it.eval(db) {
@ -494,9 +495,9 @@ pub(super) fn definition(
Some(body.to_string()) Some(body.to_string())
} }
_ => None, _ => None,
})(); };
let layout_info = match def { let layout_info = || match def {
Definition::Field(it) => render_memory_layout( Definition::Field(it) => render_memory_layout(
config.memory_layout, config.memory_layout,
|| it.layout(db), || it.layout(db),
@ -529,12 +530,13 @@ pub(super) fn definition(
_ => None, _ => None,
}; };
let dyn_compatibility_info = if let Definition::Trait(it) = def { let dyn_compatibility_info = || match def {
let mut dyn_compatibility_info = String::new(); Definition::Trait(it) => {
render_dyn_compatibility(db, &mut dyn_compatibility_info, it.dyn_compatibility(db)); let mut dyn_compatibility_info = String::new();
Some(dyn_compatibility_info) render_dyn_compatibility(db, &mut dyn_compatibility_info, it.dyn_compatibility(db));
} else { Some(dyn_compatibility_info)
None }
_ => None,
}; };
let mut desc = String::new(); let mut desc = String::new();
@ -542,16 +544,18 @@ pub(super) fn definition(
desc.push_str(&notable_traits); desc.push_str(&notable_traits);
desc.push('\n'); desc.push('\n');
} }
if let Some(layout_info) = layout_info { if hovered_definition {
desc.push_str(&layout_info); if let Some(layout_info) = layout_info() {
desc.push('\n'); desc.push_str(&layout_info);
} desc.push('\n');
if let Some(dyn_compatibility_info) = dyn_compatibility_info { }
desc.push_str(&dyn_compatibility_info); if let Some(dyn_compatibility_info) = dyn_compatibility_info() {
desc.push('\n'); desc.push_str(&dyn_compatibility_info);
desc.push('\n');
}
} }
desc.push_str(&label); desc.push_str(&label);
if let Some(value) = value { if let Some(value) = value() {
desc.push_str(" = "); desc.push_str(" = ");
desc.push_str(&value); desc.push_str(&value);
} }
@ -994,55 +998,53 @@ fn render_dyn_compatibility(
safety: Option<DynCompatibilityViolation>, safety: Option<DynCompatibilityViolation>,
) { ) {
let Some(osv) = safety else { let Some(osv) = safety else {
buf.push_str("// Dyn Compatible: Yes"); buf.push_str("// Is Dyn compatible");
return; return;
}; };
buf.push_str("// Dyn Compatible: No\n// - Reason: "); buf.push_str("// Is not Dyn compatible due to ");
match osv { match osv {
DynCompatibilityViolation::SizedSelf => { DynCompatibilityViolation::SizedSelf => {
buf.push_str("has a `Self: Sized` bound"); buf.push_str("having a `Self: Sized` bound");
} }
DynCompatibilityViolation::SelfReferential => { DynCompatibilityViolation::SelfReferential => {
buf.push_str("has a bound that references `Self`"); buf.push_str("having a bound that references `Self`");
} }
DynCompatibilityViolation::Method(func, mvc) => { DynCompatibilityViolation::Method(func, mvc) => {
let name = hir::Function::from(func).name(db); let name = hir::Function::from(func).name(db);
format_to!( format_to!(buf, "having a method `{}` that is not dispatchable due to ", name.as_str());
buf,
"has a method `{}` that is non dispatchable because of:\n// - ",
name.as_str()
);
let desc = match mvc { let desc = match mvc {
MethodViolationCode::StaticMethod => "missing a receiver", MethodViolationCode::StaticMethod => "missing a receiver",
MethodViolationCode::ReferencesSelfInput => "a parameter references `Self`", MethodViolationCode::ReferencesSelfInput => "having a parameter referencing `Self`",
MethodViolationCode::ReferencesSelfOutput => "the return type references `Self`", MethodViolationCode::ReferencesSelfOutput => "the return type referencing `Self`",
MethodViolationCode::ReferencesImplTraitInTrait => { MethodViolationCode::ReferencesImplTraitInTrait => {
"the return type contains `impl Trait`" "the return type containing `impl Trait`"
} }
MethodViolationCode::AsyncFn => "being async", MethodViolationCode::AsyncFn => "being async",
MethodViolationCode::WhereClauseReferencesSelf => { 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); buf.push_str(desc);
} }
DynCompatibilityViolation::AssocConst(const_) => { DynCompatibilityViolation::AssocConst(const_) => {
let name = hir::Const::from(const_).name(db); let name = hir::Const::from(const_).name(db);
if let Some(name) = name { 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 { } else {
buf.push_str("has an associated constant"); buf.push_str("having an associated constant");
} }
} }
DynCompatibilityViolation::GAT(alias) => { DynCompatibilityViolation::GAT(alias) => {
let name = hir::TypeAlias::from(alias).name(db); 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) => { DynCompatibilityViolation::HasNonCompatibleSuperTrait(super_trait) => {
let name = hir::Trait::from(super_trait).name(db); 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());
} }
} }
} }

View File

@ -260,7 +260,6 @@ fn foo() {
*local* *local*
```rust ```rust
// size = 4, align = 4
let local: i32 let local: i32
``` ```
"#]], "#]],
@ -819,7 +818,6 @@ fn main() {
``` ```
```rust ```rust
// size = 4, align = 4, offset = 0
pub field_a: u32 pub field_a: u32
``` ```
"#]], "#]],
@ -867,7 +865,6 @@ fn main() {
``` ```
```rust ```rust
// size = 4, align = 4, offset = 0
pub 0: u32 pub 0: u32
``` ```
"#]], "#]],
@ -888,7 +885,6 @@ fn foo(foo: Foo) {
``` ```
```rust ```rust
// size = 4, align = 4, offset = 0
pub 0: u32 pub 0: u32
``` ```
"#]], "#]],
@ -1670,7 +1666,6 @@ fn hover_for_local_variable() {
*foo* *foo*
```rust ```rust
// size = 4, align = 4
foo: i32 foo: i32
``` ```
"#]], "#]],
@ -1700,7 +1695,6 @@ fn hover_local_var_edge() {
*foo* *foo*
```rust ```rust
// size = 4, align = 4
foo: i32 foo: i32
``` ```
"#]], "#]],
@ -1985,7 +1979,6 @@ fn y() {
*x* *x*
```rust ```rust
// size = 4, align = 4
let x: i32 let x: i32
``` ```
"#]], "#]],
@ -2116,7 +2109,6 @@ macro_rules! id { ($($tt:tt)*) => { $($tt)* } }
*bar* *bar*
```rust ```rust
// size = 4, align = 4
bar: u32 bar: u32
``` ```
"#]], "#]],
@ -2135,7 +2127,6 @@ macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } }
*bar* *bar*
```rust ```rust
// size = 4, align = 4
bar: u32 bar: u32
``` ```
"#]], "#]],
@ -2537,7 +2528,6 @@ fn test_hover_struct_doc_comment() {
``` ```
```rust ```rust
// size = 0, align = 1
struct Bar struct Bar
``` ```
@ -2574,7 +2564,6 @@ fn test_hover_struct_doc_attr() {
``` ```
```rust ```rust
// size = 0, align = 1
struct Bar struct Bar
``` ```
@ -2604,7 +2593,6 @@ fn test_hover_struct_doc_attr_multiple_and_mixed() {
``` ```
```rust ```rust
// size = 0, align = 1
struct Bar struct Bar
``` ```
@ -5750,7 +5738,6 @@ fn foo(e: E) {
``` ```
```rust ```rust
// size = 0, align = 1
A = 3 A = 3
``` ```
@ -6036,7 +6023,6 @@ pub fn gimme() -> theitem::TheItem {
``` ```
```rust ```rust
// size = 0, align = 1
pub struct TheItem pub struct TheItem
``` ```
@ -6185,7 +6171,6 @@ mod string {
``` ```
```rust ```rust
// size = 0, align = 1
struct String struct String
``` ```
@ -6948,7 +6933,6 @@ macro_rules! foo_macro {
``` ```
```rust ```rust
// size = 0, align = 1
pub struct Foo pub struct Foo
``` ```
@ -6974,7 +6958,6 @@ fn hover_intra_in_attr() {
``` ```
```rust ```rust
// size = 4, align = 4
pub struct Foo(i32) pub struct Foo(i32)
``` ```
@ -7175,7 +7158,6 @@ impl T$0 for () {}
``` ```
```rust ```rust
// Dyn Compatible: Yes
trait T {} trait T {}
``` ```
"#]], "#]],
@ -7195,7 +7177,6 @@ impl T$0 for () {}
``` ```
```rust ```rust
// Dyn Compatible: Yes
trait T {} trait T {}
``` ```
"#]], "#]],
@ -7219,9 +7200,6 @@ impl T$0 for () {}
``` ```
```rust ```rust
// Dyn Compatible: No
// - Reason: has a method `func` that is non dispatchable because of:
// - missing a receiver
trait T { /**/ } trait T { /**/ }
``` ```
"#]], "#]],
@ -7245,9 +7223,6 @@ impl T$0 for () {}
``` ```
```rust ```rust
// Dyn Compatible: No
// - Reason: has a method `func` that is non dispatchable because of:
// - missing a receiver
trait T { trait T {
fn func(); fn func();
const FLAG: i32; const FLAG: i32;
@ -7275,9 +7250,6 @@ impl T$0 for () {}
``` ```
```rust ```rust
// Dyn Compatible: No
// - Reason: has a method `func` that is non dispatchable because of:
// - missing a receiver
trait T { trait T {
fn func(); fn func();
const FLAG: i32; const FLAG: i32;
@ -7305,9 +7277,6 @@ impl T$0 for () {}
``` ```
```rust ```rust
// Dyn Compatible: No
// - Reason: has a method `func` that is non dispatchable because of:
// - missing a receiver
trait T { trait T {
fn func(); fn func();
const FLAG: i32; const FLAG: i32;
@ -7784,7 +7753,6 @@ fn test() {
``` ```
```rust ```rust
// size = 4, align = 4, offset = 0
f: u32 f: u32
``` ```
"#]], "#]],
@ -7825,7 +7793,6 @@ fn test() {
*foo* *foo*
```rust ```rust
// size = 4, align = 4
let foo: i32 let foo: i32
``` ```
"#]], "#]],
@ -7846,7 +7813,6 @@ fn test() {
*aaaaa* *aaaaa*
```rust ```rust
// size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str let aaaaa: &str
``` ```
"#]], "#]],
@ -7867,7 +7833,6 @@ fn test() {
*aaaaa* *aaaaa*
```rust ```rust
// size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str let aaaaa: &str
``` ```
"#]], "#]],
@ -7888,7 +7853,6 @@ fn test() {
*aaaaa* *aaaaa*
```rust ```rust
// size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str let aaaaa: &str
``` ```
"#]], "#]],
@ -7914,7 +7878,6 @@ fn test() {
*aaaaa* *aaaaa*
```rust ```rust
// size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str let aaaaa: &str
``` ```
"#]], "#]],
@ -8419,7 +8382,6 @@ impl Iterator for S {
```rust ```rust
// Implements notable traits: Notable, Future<Output = u32>, Iterator<Item = S> // Implements notable traits: Notable, Future<Output = u32>, Iterator<Item = S>
// size = 0, align = 1
struct S struct S
``` ```
"#]], "#]],
@ -8678,7 +8640,6 @@ fn test() {
*f* *f*
```rust ```rust
// size = 0, align = 1
let f: fn bar<3>(bool) let f: fn bar<3>(bool)
``` ```
"#]], "#]],
@ -9159,7 +9120,6 @@ fn type_alias_without_docs() {
``` ```
```rust ```rust
// size = 0, align = 1
pub type A = B pub type A = B
``` ```
@ -9171,3 +9131,62 @@ fn type_alias_without_docs() {
"#]], "#]],
); );
} }
#[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
```
"#]],
);
}

View File

@ -212,6 +212,7 @@ fn add_file(&mut self, file_id: FileId) {
def, def,
&node, &node,
None, None,
false,
&hover_config, &hover_config,
edition, edition,
)), )),