mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 13:48:50 +00:00
Merge pull request #18436 from Veykril/lw-yvkqwpnwsouo
Do not render meta info when hovering usages
This commit is contained in:
commit
436ace3ecb
5 changed files with 479 additions and 192 deletions
|
@ -34,7 +34,10 @@ pub mod term_search;
|
||||||
|
|
||||||
mod display;
|
mod display;
|
||||||
|
|
||||||
use std::{mem::discriminant, ops::ControlFlow};
|
use std::{
|
||||||
|
mem::discriminant,
|
||||||
|
ops::{ControlFlow, Not},
|
||||||
|
};
|
||||||
|
|
||||||
use arrayvec::ArrayVec;
|
use arrayvec::ArrayVec;
|
||||||
use base_db::{CrateDisplayName, CrateId, CrateOrigin};
|
use base_db::{CrateDisplayName, CrateId, CrateOrigin};
|
||||||
|
@ -2697,6 +2700,18 @@ impl Trait {
|
||||||
hir_ty::dyn_compatibility::dyn_compatibility(db, self.id)
|
hir_ty::dyn_compatibility::dyn_compatibility(db, self.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dyn_compatibility_all_violations(
|
||||||
|
&self,
|
||||||
|
db: &dyn HirDatabase,
|
||||||
|
) -> Option<Vec<DynCompatibilityViolation>> {
|
||||||
|
let mut violations = vec![];
|
||||||
|
hir_ty::dyn_compatibility::dyn_compatibility_with_callback(db, self.id, &mut |violation| {
|
||||||
|
violations.push(violation);
|
||||||
|
ControlFlow::Continue(())
|
||||||
|
});
|
||||||
|
violations.is_empty().not().then_some(violations)
|
||||||
|
}
|
||||||
|
|
||||||
fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId<ast::Item>, MacroCallId)]> {
|
fn all_macro_calls(&self, db: &dyn HirDatabase) -> Box<[(AstId<ast::Item>, MacroCallId)]> {
|
||||||
db.trait_data(self.id)
|
db.trait_data(self.id)
|
||||||
.macro_calls
|
.macro_calls
|
||||||
|
|
|
@ -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(¯o_call),
|
sema.resolve_macro_call_arm(¯o_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(),
|
||||||
¬able_traits,
|
¬able_traits,
|
||||||
macro_arm,
|
macro_arm,
|
||||||
|
hovered_definition,
|
||||||
config,
|
config,
|
||||||
edition,
|
edition,
|
||||||
);
|
);
|
||||||
|
|
|
@ -273,7 +273,7 @@ pub(super) fn keyword(
|
||||||
let markup = process_markup(
|
let markup = process_markup(
|
||||||
sema.db,
|
sema.db,
|
||||||
Definition::Module(doc_owner),
|
Definition::Module(doc_owner),
|
||||||
&markup(Some(docs.into()), description, None),
|
&markup(Some(docs.into()), description, None, None),
|
||||||
config,
|
config,
|
||||||
);
|
);
|
||||||
Some(HoverResult { markup, actions })
|
Some(HoverResult { markup, actions })
|
||||||
|
@ -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,34 +530,38 @@ 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 extra = String::new();
|
||||||
|
if hovered_definition {
|
||||||
|
if let Some(notable_traits) = render_notable_trait(db, notable_traits, edition) {
|
||||||
|
extra.push_str("\n___\n");
|
||||||
|
extra.push_str(¬able_traits);
|
||||||
|
}
|
||||||
|
if let Some(layout_info) = layout_info() {
|
||||||
|
extra.push_str("\n___\n");
|
||||||
|
extra.push_str(&layout_info);
|
||||||
|
}
|
||||||
|
if let Some(dyn_compatibility_info) = dyn_compatibility_info() {
|
||||||
|
extra.push_str("\n___\n");
|
||||||
|
extra.push_str(&dyn_compatibility_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut desc = String::new();
|
let mut desc = String::new();
|
||||||
if let Some(notable_traits) = render_notable_trait_comment(db, notable_traits, edition) {
|
|
||||||
desc.push_str(¬able_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');
|
|
||||||
}
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
markup(docs.map(Into::into), desc, mod_path)
|
markup(docs.map(Into::into), desc, extra.is_empty().not().then_some(extra), mod_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn literal(
|
pub(super) fn literal(
|
||||||
|
@ -626,7 +631,7 @@ pub(super) fn literal(
|
||||||
Some(s.into())
|
Some(s.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_notable_trait_comment(
|
fn render_notable_trait(
|
||||||
db: &RootDatabase,
|
db: &RootDatabase,
|
||||||
notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)],
|
notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)],
|
||||||
edition: Edition,
|
edition: Edition,
|
||||||
|
@ -635,7 +640,7 @@ fn render_notable_trait_comment(
|
||||||
let mut needs_impl_header = true;
|
let mut needs_impl_header = true;
|
||||||
for (trait_, assoc_types) in notable_traits {
|
for (trait_, assoc_types) in notable_traits {
|
||||||
desc.push_str(if mem::take(&mut needs_impl_header) {
|
desc.push_str(if mem::take(&mut needs_impl_header) {
|
||||||
"// Implements notable traits: "
|
"Implements notable traits: "
|
||||||
} else {
|
} else {
|
||||||
", "
|
", "
|
||||||
});
|
});
|
||||||
|
@ -728,13 +733,12 @@ fn type_info(
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
} else {
|
} else {
|
||||||
let mut desc =
|
let mut desc = format!("```rust\n{}\n```", original.display(db, edition));
|
||||||
match render_notable_trait_comment(db, ¬able_traits(db, &original), edition) {
|
if let Some(extra) = render_notable_trait(db, ¬able_traits(db, &original), edition) {
|
||||||
Some(desc) => desc + "\n",
|
desc.push_str("\n___\n");
|
||||||
None => String::new(),
|
desc.push_str(&extra);
|
||||||
};
|
};
|
||||||
format_to!(desc, "{}", original.display(db, edition));
|
desc.into()
|
||||||
Markup::fenced_block(&desc)
|
|
||||||
};
|
};
|
||||||
if let Some(actions) = HoverAction::goto_type_from_targets(db, targets, edition) {
|
if let Some(actions) = HoverAction::goto_type_from_targets(db, targets, edition) {
|
||||||
res.actions.push(actions);
|
res.actions.push(actions);
|
||||||
|
@ -786,20 +790,16 @@ fn closure_ty(
|
||||||
};
|
};
|
||||||
let mut markup = format!("```rust\n{}", c.display_with_id(sema.db, edition));
|
let mut markup = format!("```rust\n{}", c.display_with_id(sema.db, edition));
|
||||||
|
|
||||||
if let Some(layout) =
|
|
||||||
render_memory_layout(config.memory_layout, || original.layout(sema.db), |_| None, |_| None)
|
|
||||||
{
|
|
||||||
format_to!(markup, " {layout}");
|
|
||||||
}
|
|
||||||
if let Some(trait_) = c.fn_trait(sema.db).get_id(sema.db, original.krate(sema.db).into()) {
|
if let Some(trait_) = c.fn_trait(sema.db).get_id(sema.db, original.krate(sema.db).into()) {
|
||||||
push_new_def(hir::Trait::from(trait_).into())
|
push_new_def(hir::Trait::from(trait_).into())
|
||||||
}
|
}
|
||||||
format_to!(
|
format_to!(markup, "\n{}\n```", c.display_with_impl(sema.db, edition),);
|
||||||
markup,
|
if let Some(layout) =
|
||||||
"\n{}\n```{adjusted}\n\n## Captures\n{}",
|
render_memory_layout(config.memory_layout, || original.layout(sema.db), |_| None, |_| None)
|
||||||
c.display_with_impl(sema.db, edition),
|
{
|
||||||
captures_rendered,
|
format_to!(markup, "\n___\n{layout}");
|
||||||
);
|
}
|
||||||
|
format_to!(markup, "{adjusted}\n\n## Captures\n{}", captures_rendered,);
|
||||||
|
|
||||||
let mut res = HoverResult::default();
|
let mut res = HoverResult::default();
|
||||||
if let Some(actions) = HoverAction::goto_type_from_targets(sema.db, targets, edition) {
|
if let Some(actions) = HoverAction::goto_type_from_targets(sema.db, targets, edition) {
|
||||||
|
@ -824,7 +824,12 @@ fn definition_mod_path(db: &RootDatabase, def: &Definition, edition: Edition) ->
|
||||||
.map(|module| path(db, module, definition_owner_name(db, def, edition), edition))
|
.map(|module| path(db, module, definition_owner_name(db, def, edition), edition))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn markup(docs: Option<String>, desc: String, mod_path: Option<String>) -> Markup {
|
fn markup(
|
||||||
|
docs: Option<String>,
|
||||||
|
rust: String,
|
||||||
|
extra: Option<String>,
|
||||||
|
mod_path: Option<String>,
|
||||||
|
) -> Markup {
|
||||||
let mut buf = String::new();
|
let mut buf = String::new();
|
||||||
|
|
||||||
if let Some(mod_path) = mod_path {
|
if let Some(mod_path) = mod_path {
|
||||||
|
@ -832,7 +837,11 @@ fn markup(docs: Option<String>, desc: String, mod_path: Option<String>) -> Marku
|
||||||
format_to!(buf, "```rust\n{}\n```\n\n", mod_path);
|
format_to!(buf, "```rust\n{}\n```\n\n", mod_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
format_to!(buf, "```rust\n{}\n```", desc);
|
format_to!(buf, "```rust\n{}\n```", rust);
|
||||||
|
|
||||||
|
if let Some(extra) = extra {
|
||||||
|
buf.push_str(&extra);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(doc) = docs {
|
if let Some(doc) = docs {
|
||||||
format_to!(buf, "\n___\n\n{}", doc);
|
format_to!(buf, "\n___\n\n{}", doc);
|
||||||
|
@ -862,7 +871,7 @@ fn render_memory_layout(
|
||||||
let config = config?;
|
let config = config?;
|
||||||
let layout = layout().ok()?;
|
let layout = layout().ok()?;
|
||||||
|
|
||||||
let mut label = String::from("// ");
|
let mut label = String::new();
|
||||||
|
|
||||||
if let Some(render) = config.size {
|
if let Some(render) = config.size {
|
||||||
let size = match tag(&layout) {
|
let size = match tag(&layout) {
|
||||||
|
@ -994,55 +1003,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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -212,6 +212,7 @@ impl StaticIndex<'_> {
|
||||||
def,
|
def,
|
||||||
&node,
|
&node,
|
||||||
None,
|
None,
|
||||||
|
false,
|
||||||
&hover_config,
|
&hover_config,
|
||||||
edition,
|
edition,
|
||||||
)),
|
)),
|
||||||
|
|
Loading…
Reference in a new issue