Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir/src/lib.rs17
-rw-r--r--crates/ide/src/hover.rs33
-rw-r--r--crates/ide/src/hover/render.rs137
-rw-r--r--crates/ide/src/hover/tests.rs481
-rw-r--r--crates/ide/src/static_index.rs1
5 files changed, 478 insertions, 191 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 88eb3b127e..56bf1d2742 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -34,7 +34,10 @@ pub mod term_search;
mod display;
-use std::{mem::discriminant, ops::ControlFlow};
+use std::{
+ mem::discriminant,
+ ops::{ControlFlow, Not},
+};
use arrayvec::ArrayVec;
use base_db::{CrateDisplayName, CrateId, CrateOrigin};
@@ -2697,6 +2700,18 @@ impl Trait {
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)]> {
db.trait_data(self.id)
.macro_calls
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..51a7728345 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -273,7 +273,7 @@ pub(super) fn keyword(
let markup = process_markup(
sema.db,
Definition::Module(doc_owner),
- &markup(Some(docs.into()), description, None),
+ &markup(Some(docs.into()), description, None, None),
config,
);
Some(HoverResult { markup, actions })
@@ -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,34 +530,38 @@ 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();
- if let Some(notable_traits) = render_notable_trait_comment(db, notable_traits, edition) {
- 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');
+ 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(&notable_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();
desc.push_str(&label);
- if let Some(value) = value {
+ if let Some(value) = value() {
desc.push_str(" = ");
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(
@@ -626,7 +631,7 @@ pub(super) fn literal(
Some(s.into())
}
-fn render_notable_trait_comment(
+fn render_notable_trait(
db: &RootDatabase,
notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)],
edition: Edition,
@@ -635,7 +640,7 @@ fn render_notable_trait_comment(
let mut needs_impl_header = true;
for (trait_, assoc_types) in notable_traits {
desc.push_str(if mem::take(&mut needs_impl_header) {
- "// Implements notable traits: "
+ "Implements notable traits: "
} else {
", "
});
@@ -728,13 +733,12 @@ fn type_info(
)
.into()
} else {
- let mut desc =
- match render_notable_trait_comment(db, &notable_traits(db, &original), edition) {
- Some(desc) => desc + "\n",
- None => String::new(),
- };
- format_to!(desc, "{}", original.display(db, edition));
- Markup::fenced_block(&desc)
+ let mut desc = format!("```rust\n{}\n```", original.display(db, edition));
+ if let Some(extra) = render_notable_trait(db, &notable_traits(db, &original), edition) {
+ desc.push_str("\n___\n");
+ desc.push_str(&extra);
+ };
+ desc.into()
};
if let Some(actions) = HoverAction::goto_type_from_targets(db, targets, edition) {
res.actions.push(actions);
@@ -786,20 +790,16 @@ fn closure_ty(
};
let mut markup = format!("```rust\n{}", c.display_with_id(sema.db, edition));
+ 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())
+ }
+ format_to!(markup, "\n{}\n```", c.display_with_impl(sema.db, edition),);
if let Some(layout) =
render_memory_layout(config.memory_layout, || original.layout(sema.db), |_| None, |_| None)
{
- format_to!(markup, " {layout}");
+ format_to!(markup, "\n___\n{layout}");
}
- 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())
- }
- format_to!(
- markup,
- "\n{}\n```{adjusted}\n\n## Captures\n{}",
- c.display_with_impl(sema.db, edition),
- captures_rendered,
- );
+ format_to!(markup, "{adjusted}\n\n## Captures\n{}", captures_rendered,);
let mut res = HoverResult::default();
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))
}
-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();
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```", desc);
+ format_to!(buf, "```rust\n{}\n```", rust);
+
+ if let Some(extra) = extra {
+ buf.push_str(&extra);
+ }
if let Some(doc) = docs {
format_to!(buf, "\n___\n\n{}", doc);
@@ -862,7 +871,7 @@ fn render_memory_layout(
let config = config?;
let layout = layout().ok()?;
- let mut label = String::from("// ");
+ let mut label = String::new();
if let Some(render) = config.size {
let size = match tag(&layout) {
@@ -994,55 +1003,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..1fad3d6bd6 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
```
"#]],
@@ -348,9 +347,11 @@ fn main() {
expect![[r#"
*|*
```rust
- {closure#0} // size = 8, align = 8, niches = 1
+ {closure#0}
impl Fn(i32) -> i32
```
+ ___
+ size = 8, align = 8, niches = 1
## Captures
* `x` by immutable borrow
@@ -370,9 +371,11 @@ fn main() {
expect![[r#"
*|*
```rust
- {closure#0} // size = 0, align = 1
+ {closure#0}
impl Fn(i32) -> i32
```
+ ___
+ size = 0, align = 1
## Captures
This closure captures nothing
@@ -403,9 +406,11 @@ fn main() {
expect![[r#"
*|*
```rust
- {closure#0} // size = 16 (0x10), align = 8, niches = 1
+ {closure#0}
impl FnOnce()
```
+ ___
+ size = 16 (0x10), align = 8, niches = 1
## Captures
* `x.f1` by move
@@ -431,9 +436,11 @@ fn main() {
expect![[r#"
*|*
```rust
- {closure#0} // size = 8, align = 8, niches = 1
+ {closure#0}
impl FnMut()
```
+ ___
+ size = 8, align = 8, niches = 1
## Captures
* `x` by mutable borrow
@@ -455,9 +462,11 @@ fn main() {
"#,
expect![[r#"
```rust
- {closure#0} // size = 8, align = 8, niches = 1
+ {closure#0}
impl FnOnce() -> S2
```
+ ___
+ size = 8, align = 8, niches = 1
Coerced to: &impl FnOnce() -> S2
## Captures
@@ -551,9 +560,12 @@ fn main() {
*iter*
```rust
- // size = 8, align = 4
let mut iter: Iter<Scan<OtherStruct<OtherStruct<i32>>, impl Fn(&mut u32, &u32, &mut u32) -> Option<u32>, u32>>
```
+
+ ---
+
+ size = 8, align = 4
"#]],
);
}
@@ -793,9 +805,12 @@ struct Foo { fiel$0d_a: u8, field_b: i32, field_c: i16 }
```
```rust
- // size = 1, align = 1, offset = 6
field_a: u8
```
+
+ ---
+
+ size = 1, align = 1, offset = 6
"#]],
);
}
@@ -819,7 +834,6 @@ fn main() {
```
```rust
- // size = 4, align = 4, offset = 0
pub field_a: u32
```
"#]],
@@ -842,9 +856,12 @@ fn main() {
```
```rust
- // size = 4, align = 4, offset = 0
pub field_a: u32
```
+
+ ---
+
+ size = 4, align = 4, offset = 0
"#]],
);
}
@@ -867,7 +884,6 @@ fn main() {
```
```rust
- // size = 4, align = 4, offset = 0
pub 0: u32
```
"#]],
@@ -888,7 +904,6 @@ fn foo(foo: Foo) {
```
```rust
- // size = 4, align = 4, offset = 0
pub 0: u32
```
"#]],
@@ -909,11 +924,14 @@ struct Foo$0(pub u32) where u32: Copy;
```
```rust
- // size = 4, align = 4
struct Foo(pub u32)
where
u32: Copy,
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
}
@@ -932,11 +950,14 @@ struct Foo$0 { field: u32 }
```
```rust
- // size = 4, align = 4
struct Foo {
field: u32,
}
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
check(
@@ -951,7 +972,6 @@ struct Foo$0 where u32: Copy { field: u32 }
```
```rust
- // size = 4, align = 4
struct Foo
where
u32: Copy,
@@ -959,6 +979,10 @@ struct Foo$0 where u32: Copy { field: u32 }
field: u32,
}
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
}
@@ -978,13 +1002,16 @@ fn hover_record_struct_limit() {
```
```rust
- // size = 12 (0xC), align = 4
struct Foo {
a: u32,
b: i32,
c: i32,
}
```
+
+ ---
+
+ size = 12 (0xC), align = 4
"#]],
);
check_hover_fields_limit(
@@ -1000,11 +1027,14 @@ fn hover_record_struct_limit() {
```
```rust
- // size = 4, align = 4
struct Foo {
a: u32,
}
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
check_hover_fields_limit(
@@ -1020,7 +1050,6 @@ fn hover_record_struct_limit() {
```
```rust
- // size = 16 (0x10), align = 4
struct Foo {
a: u32,
b: i32,
@@ -1028,6 +1057,10 @@ fn hover_record_struct_limit() {
/* … */
}
```
+
+ ---
+
+ size = 16 (0x10), align = 4
"#]],
);
check_hover_fields_limit(
@@ -1043,9 +1076,12 @@ fn hover_record_struct_limit() {
```
```rust
- // size = 12 (0xC), align = 4
struct Foo
```
+
+ ---
+
+ size = 12 (0xC), align = 4
"#]],
);
check_hover_fields_limit(
@@ -1061,9 +1097,12 @@ fn hover_record_struct_limit() {
```
```rust
- // size = 12 (0xC), align = 4
struct Foo { /* … */ }
```
+
+ ---
+
+ size = 12 (0xC), align = 4
"#]],
);
@@ -1081,9 +1120,12 @@ fn hover_record_struct_limit() {
```
```rust
- // size = 0, align = 1
struct Foo {}
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -1103,9 +1145,12 @@ fn hover_record_variant_limit() {
```
```rust
- // size = 12 (0xC), align = 4
A { a: u32, b: i32, c: i32, }
```
+
+ ---
+
+ size = 12 (0xC), align = 4
"#]],
);
check_hover_fields_limit(
@@ -1121,9 +1166,12 @@ fn hover_record_variant_limit() {
```
```rust
- // size = 4, align = 4
A { a: u32, }
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
check_hover_fields_limit(
@@ -1139,9 +1187,12 @@ fn hover_record_variant_limit() {
```
```rust
- // size = 16 (0x10), align = 4
A { a: u32, b: i32, c: i32, /* … */ }
```
+
+ ---
+
+ size = 16 (0x10), align = 4
"#]],
);
check_hover_fields_limit(
@@ -1157,9 +1208,12 @@ fn hover_record_variant_limit() {
```
```rust
- // size = 12 (0xC), align = 4
A
```
+
+ ---
+
+ size = 12 (0xC), align = 4
"#]],
);
check_hover_fields_limit(
@@ -1175,9 +1229,12 @@ fn hover_record_variant_limit() {
```
```rust
- // size = 12 (0xC), align = 4
A { /* … */ }
```
+
+ ---
+
+ size = 12 (0xC), align = 4
"#]],
);
}
@@ -1195,12 +1252,15 @@ fn hover_enum_limit() {
```
```rust
- // size = 1, align = 1, niches = 254
enum Foo {
A,
B,
}
```
+
+ ---
+
+ size = 1, align = 1, niches = 254
"#]],
);
check_hover_enum_variants_limit(
@@ -1214,12 +1274,15 @@ fn hover_enum_limit() {
```
```rust
- // size = 1, align = 1, niches = 254
enum Foo {
A,
/* … */
}
```
+
+ ---
+
+ size = 1, align = 1, niches = 254
"#]],
);
check_hover_enum_variants_limit(
@@ -1233,9 +1296,12 @@ fn hover_enum_limit() {
```
```rust
- // size = 1, align = 1, niches = 254
enum Foo { /* … */ }
```
+
+ ---
+
+ size = 1, align = 1, niches = 254
"#]],
);
check_hover_enum_variants_limit(
@@ -1249,9 +1315,12 @@ fn hover_enum_limit() {
```
```rust
- // size = 1, align = 1, niches = 254
enum Foo
```
+
+ ---
+
+ size = 1, align = 1, niches = 254
"#]],
);
check_hover_enum_variants_limit(
@@ -1274,7 +1343,6 @@ fn hover_enum_limit() {
```
```rust
- // size = 12 (0xC), align = 4, niches = 4294967288
enum Enum {
Variant {},
Variant2 { /* … */ },
@@ -1286,6 +1354,10 @@ fn hover_enum_limit() {
/* … */
}
```
+
+ ---
+
+ size = 12 (0xC), align = 4, niches = 4294967288
"#]],
);
}
@@ -1303,12 +1375,15 @@ fn hover_union_limit() {
```
```rust
- // size = 4, align = 4
union Foo {
a: u32,
b: i32,
}
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
check_hover_fields_limit(
@@ -1322,12 +1397,15 @@ fn hover_union_limit() {
```
```rust
- // size = 4, align = 4
union Foo {
a: u32,
/* … */
}
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
check_hover_fields_limit(
@@ -1341,9 +1419,12 @@ fn hover_union_limit() {
```
```rust
- // size = 4, align = 4
union Foo { /* … */ }
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
check_hover_fields_limit(
@@ -1357,9 +1438,12 @@ fn hover_union_limit() {
```
```rust
- // size = 4, align = 4
union Foo
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
}
@@ -1378,11 +1462,14 @@ struct Foo$0 where u32: Copy;
```
```rust
- // size = 0, align = 1
struct Foo
where
u32: Copy,
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -1548,9 +1635,12 @@ fn main() {
*zz*
```rust
- // size = 8, align = 4
let zz: Test<i32>
```
+
+ ---
+
+ size = 8, align = 4
"#]],
);
check_hover_range(
@@ -1600,9 +1690,12 @@ fn main() { let b$0ar = Some(12); }
*bar*
```rust
- // size = 4, align = 4
let bar: Option<i32>
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
}
@@ -1670,7 +1763,6 @@ fn hover_for_local_variable() {
*foo*
```rust
- // size = 4, align = 4
foo: i32
```
"#]],
@@ -1685,9 +1777,12 @@ fn hover_for_local_variable_pat() {
*foo*
```rust
- // size = 4, align = 4
foo: i32
```
+
+ ---
+
+ size = 4, align = 4
"#]],
)
}
@@ -1700,7 +1795,6 @@ fn hover_local_var_edge() {
*foo*
```rust
- // size = 4, align = 4
foo: i32
```
"#]],
@@ -1715,9 +1809,12 @@ fn hover_for_param_edge() {
*foo*
```rust
- // size = 4, align = 4
foo: i32
```
+
+ ---
+
+ size = 4, align = 4
"#]],
)
}
@@ -1760,9 +1857,12 @@ fn main() { let foo_$0test = Thing::new(); }
*foo_test*
```rust
- // size = 4, align = 4
let foo_test: Thing
```
+
+ ---
+
+ size = 4, align = 4
"#]],
)
}
@@ -1985,7 +2085,6 @@ fn y() {
*x*
```rust
- // size = 4, align = 4
let x: i32
```
"#]],
@@ -2116,7 +2215,6 @@ fn foo(bar:u32) { let a = id!(ba$0r); }
*bar*
```rust
- // size = 4, align = 4
bar: u32
```
"#]],
@@ -2135,7 +2233,6 @@ fn foo(bar:u32) { let a = id!(ba$0r); }
*bar*
```rust
- // size = 4, align = 4
bar: u32
```
"#]],
@@ -2371,9 +2468,12 @@ fn test_hover_function_pointer_show_identifiers() {
```
```rust
- // size = 8, align = 8, niches = 1
type foo = fn(a: i32, b: i32) -> i32
```
+
+ ---
+
+ size = 8, align = 8, niches = 1
"#]],
);
}
@@ -2390,9 +2490,12 @@ fn test_hover_function_pointer_no_identifier() {
```
```rust
- // size = 8, align = 8, niches = 1
type foo = fn(i32, i32) -> i32
```
+
+ ---
+
+ size = 8, align = 8, niches = 1
"#]],
);
}
@@ -2537,7 +2640,6 @@ fn foo() { let bar = Ba$0r; }
```
```rust
- // size = 0, align = 1
struct Bar
```
@@ -2574,7 +2676,6 @@ fn foo() { let bar = Ba$0r; }
```
```rust
- // size = 0, align = 1
struct Bar
```
@@ -2604,7 +2705,6 @@ fn foo() { let bar = Ba$0r; }
```
```rust
- // size = 0, align = 1
struct Bar
```
@@ -2633,12 +2733,15 @@ pub struct B$0ar
```
```rust
- // size = 0, align = 1
pub struct Bar
```
---
+ size = 0, align = 1
+
+ ---
+
[external](https://www.google.com)
"#]],
);
@@ -2661,12 +2764,15 @@ pub struct B$0ar
```
```rust
- // size = 0, align = 1
pub struct Bar
```
---
+ size = 0, align = 1
+
+ ---
+
[baz](Baz)
"#]],
);
@@ -2751,9 +2857,12 @@ fn test_hover_layout_of_variant() {
```
```rust
- // size = 4, align = 2
Variant1(u8, u16)
```
+
+ ---
+
+ size = 4, align = 2
"#]],
);
}
@@ -2794,9 +2903,12 @@ struct S$0<T>(core::marker::PhantomData<T>);
```
```rust
- // size = 0, align = 1
struct S<T>(PhantomData<T>)
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -2816,12 +2928,15 @@ fn test_hover_layout_of_enum() {
```
```rust
- // size = 16 (0x10), align = 8, niches = 254
enum Foo {
Variant1( /* … */ ),
Variant2( /* … */ ),
}
```
+
+ ---
+
+ size = 16 (0x10), align = 8, niches = 254
"#]],
);
}
@@ -4133,9 +4248,12 @@ fn main() {
*f*
```rust
- // size = 8, align = 8, niches = 1
let f: &i32
```
+
+ ---
+
+ size = 8, align = 8, niches = 1
---
```rust
@@ -4143,9 +4261,12 @@ fn main() {
```
```rust
- // size = 4, align = 4, offset = 0
f: i32
```
+
+ ---
+
+ size = 4, align = 4, offset = 0
"#]],
);
}
@@ -4165,9 +4286,12 @@ struct S$0T<const C: usize = 1, T = Foo>(T);
```
```rust
- // size = 0, align = 1
struct ST<const C: usize = 1, T = Foo>(T)
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4187,9 +4311,12 @@ struct S$0T<const C: usize = {40 + 2}, T = Foo>(T);
```
```rust
- // size = 0, align = 1
struct ST<const C: usize = {const}, T = Foo>(T)
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4210,9 +4337,12 @@ struct S$0T<const C: usize = VAL, T = Foo>(T);
```
```rust
- // size = 0, align = 1
struct ST<const C: usize = VAL, T = Foo>(T)
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4231,9 +4361,12 @@ fn main() {
*value*
```rust
- // size = 0, align = 1
let value: Const<1>
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4252,9 +4385,12 @@ fn main() {
*value*
```rust
- // size = 0, align = 1
let value: Const<0>
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4273,9 +4409,12 @@ fn main() {
*value*
```rust
- // size = 0, align = 1
let value: Const<-1>
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4294,9 +4433,12 @@ fn main() {
*value*
```rust
- // size = 0, align = 1
let value: Const<true>
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4315,9 +4457,12 @@ fn main() {
*value*
```rust
- // size = 0, align = 1
let value: Const<'🦀'>
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4335,9 +4480,12 @@ impl Foo {
*self*
```rust
- // size = 8, align = 8, niches = 1
self: &Foo
```
+
+ ---
+
+ size = 8, align = 8, niches = 1
"#]],
);
}
@@ -4356,9 +4504,12 @@ impl Foo {
*self*
```rust
- // size = 0, align = 1
self: Arc<Foo>
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4755,9 +4906,12 @@ type Fo$0o2 = Foo<2>;
```
```rust
- // size = 0, align = 1
type Foo2 = Foo<2>
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -4798,12 +4952,15 @@ enum E {
```
```rust
- // size = 1, align = 1
A = 8
```
---
+ size = 1, align = 1
+
+ ---
+
This is a doc
"#]],
);
@@ -4824,12 +4981,15 @@ enum E {
```
```rust
- // size = 1, align = 1
A = 12 (0xC)
```
---
+ size = 1, align = 1
+
+ ---
+
This is a doc
"#]],
);
@@ -4851,12 +5011,15 @@ enum E {
```
```rust
- // size = 1, align = 1
B = 2
```
---
+ size = 1, align = 1
+
+ ---
+
This is a doc
"#]],
);
@@ -4878,12 +5041,15 @@ enum E {
```
```rust
- // size = 1, align = 1
B = 5
```
---
+ size = 1, align = 1
+
+ ---
+
This is a doc
"#]],
);
@@ -5750,7 +5916,6 @@ fn foo(e: E) {
```
```rust
- // size = 0, align = 1
A = 3
```
@@ -5799,9 +5964,12 @@ fn main() {
*tile4*
```rust
- // size = 32 (0x20), align = 4
let tile4: [u32; 8]
```
+
+ ---
+
+ size = 32 (0x20), align = 4
"#]],
);
}
@@ -6036,7 +6204,6 @@ pub fn gimme() -> theitem::TheItem {
```
```rust
- // size = 0, align = 1
pub struct TheItem
```
@@ -6185,7 +6352,6 @@ mod string {
```
```rust
- // size = 0, align = 1
struct String
```
@@ -6948,7 +7114,6 @@ foo_macro!(
```
```rust
- // size = 0, align = 1
pub struct Foo
```
@@ -6974,7 +7139,6 @@ pub struct Foo(i32);
```
```rust
- // size = 4, align = 4
pub struct Foo(i32)
```
@@ -7099,9 +7263,12 @@ enum Enum {
```
```rust
- // size = 4, align = 4
RecordV { field: u32, }
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
}
@@ -7122,9 +7289,12 @@ enum Enum {
```
```rust
- // size = 4, align = 4
field: u32
```
+
+ ---
+
+ size = 4, align = 4
"#]],
);
}
@@ -7175,7 +7345,6 @@ impl T$0 for () {}
```
```rust
- // Dyn Compatible: Yes
trait T {}
```
"#]],
@@ -7195,7 +7364,6 @@ impl T$0 for () {}
```
```rust
- // Dyn Compatible: Yes
trait T {}
```
"#]],
@@ -7219,9 +7387,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 +7410,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 +7437,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 +7464,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 +7940,6 @@ fn test() {
```
```rust
- // size = 4, align = 4, offset = 0
f: u32
```
"#]],
@@ -7804,9 +7959,12 @@ fn test() {
*s*
```rust
- // size = 0, align = 1
let s: S
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -7825,7 +7983,6 @@ fn test() {
*foo*
```rust
- // size = 4, align = 4
let foo: i32
```
"#]],
@@ -7846,7 +8003,6 @@ format_args!("{aaaaa$0}");
*aaaaa*
```rust
- // size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str
```
"#]],
@@ -7867,7 +8023,6 @@ format_args!("{$0aaaaa}");
*aaaaa*
```rust
- // size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str
```
"#]],
@@ -7888,7 +8043,6 @@ format_args!(r"{$0aaaaa}");
*aaaaa*
```rust
- // size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str
```
"#]],
@@ -7914,7 +8068,6 @@ foo!(r"{$0aaaaa}");
*aaaaa*
```rust
- // size = 16 (0x10), align = 8, niches = 1
let aaaaa: &str
```
"#]],
@@ -8386,10 +8539,16 @@ fn main(notable$0: u32) {}
*notable*
```rust
- // Implements notable traits: Notable<Assoc = &str, Assoc2 = char>
- // size = 4, align = 4
notable: u32
```
+
+ ---
+
+ Implements notable traits: Notable\<Assoc = &str, Assoc2 = char>
+
+ ---
+
+ size = 4, align = 4
"#]],
);
}
@@ -8418,8 +8577,6 @@ impl Iterator for S {
```
```rust
- // Implements notable traits: Notable, Future<Output = u32>, Iterator<Item = S>
- // size = 0, align = 1
struct S
```
"#]],
@@ -8478,9 +8635,12 @@ extern "C" {
```
```rust
- // size = 0, align = 1
type Ty
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -8506,9 +8666,10 @@ fn main() {
"#,
expect![[r#"
```rust
- // Implements notable traits: Notable, Future<Output = u32>, Iterator<Item = S>
S
- ```"#]],
+ ```
+ ___
+ Implements notable traits: Notable, Future<Output = u32>, Iterator<Item = S>"#]],
);
}
@@ -8618,11 +8779,14 @@ struct Pedro$0<'a> {
```
```rust
- // size = 16 (0x10), align = 8, niches = 1
struct Pedro<'a> {
hola: &str,
}
```
+
+ ---
+
+ size = 16 (0x10), align = 8, niches = 1
"#]],
)
}
@@ -8655,9 +8819,12 @@ fn main(a$0: T) {}
*a*
```rust
- // size = 0, align = 1
a: T
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -8678,7 +8845,6 @@ fn test() {
*f*
```rust
- // size = 0, align = 1
let f: fn bar<3>(bool)
```
"#]],
@@ -8706,9 +8872,12 @@ fn main() {
*x*
```rust
- // size = 0, align = 1
let x: fn f<S, i32>()
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
}
@@ -9037,12 +9206,15 @@ type A$0 = B;
```
```rust
- // size = 0, align = 1
type A = B
```
---
+ size = 0, align = 1
+
+ ---
+
*This is the documentation for* `struct B`
Docs for B
@@ -9067,12 +9239,15 @@ type A$0 = B;
```
```rust
- // size = 0, align = 1
type A = B
```
---
+ size = 0, align = 1
+
+ ---
+
*This is the documentation for* `struct C`
Docs for C
@@ -9098,12 +9273,15 @@ type A$0 = B;
```
```rust
- // size = 0, align = 1
type A = B
```
---
+ size = 0, align = 1
+
+ ---
+
*This is the documentation for* `struct C`
Docs for C
@@ -9127,9 +9305,12 @@ type A$0 = B;
```
```rust
- // size = 0, align = 1
type A = B
```
+
+ ---
+
+ size = 0, align = 1
"#]],
);
@@ -9159,7 +9340,6 @@ use a::A$0;
```
```rust
- // size = 0, align = 1
pub type A = B
```
@@ -9171,3 +9351,68 @@ use a::A$0;
"#]],
);
}
+
+#[test]
+fn dyn_compat() {
+ check(
+ r#"
+trait Compat$0 {}
+"#,
+ expect![[r#"
+ *Compat*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ trait Compat
+ ```
+
+ ---
+
+ Is Dyn compatible
+ "#]],
+ );
+ check(
+ r#"
+trait UnCompat$0 {
+ fn f<T>() {}
+}
+"#,
+ expect![[r#"
+ *UnCompat*
+
+ ```rust
+ test
+ ```
+
+ ```rust
+ trait UnCompat
+ ```
+
+ ---
+
+ Is not Dyn compatible due to having a method `f` that is not dispatchable due to missing a receiver
+ "#]],
+ );
+ 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,
)),