Skip to content

Commit da102d0

Browse files
committed
feat: render docs from aliased type when type has no docs
1 parent 687b72c commit da102d0

File tree

3 files changed

+179
-4
lines changed

3 files changed

+179
-4
lines changed

crates/ide/src/hover.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ pub(crate) fn hover_for_definition(
406406
let notable_traits = def_ty.map(|ty| notable_traits(db, &ty)).unwrap_or_default();
407407

408408
let markup = render::definition(
409-
sema.db,
409+
sema,
410410
def,
411411
famous_defs.as_ref(),
412412
&notable_traits,

crates/ide/src/hover/render.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ use hir::{
1010
use ide_db::{
1111
base_db::SourceDatabase,
1212
defs::Definition,
13-
documentation::HasDocs,
13+
documentation::{Documentation, HasDocs},
1414
famous_defs::FamousDefs,
1515
generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
16+
helpers::get_definition,
1617
syntax_helpers::prettify_macro_expansion,
1718
RootDatabase,
1819
};
@@ -414,7 +415,7 @@ pub(super) fn path(
414415
}
415416

416417
pub(super) fn definition(
417-
db: &RootDatabase,
418+
sema @ &Semantics { db, .. }: &Semantics<'_, RootDatabase>,
418419
def: Definition,
419420
famous_defs: Option<&FamousDefs<'_, '_>>,
420421
notable_traits: &[(Trait, Vec<(Option<Type>, Name)>)],
@@ -455,7 +456,7 @@ pub(super) fn definition(
455456
}
456457
_ => def.label(db, edition),
457458
};
458-
let docs = def.docs(db, famous_defs, edition);
459+
let docs = get_docs(sema, def, famous_defs, edition);
459460
let value = (|| match def {
460461
Definition::Variant(it) => {
461462
if !it.parent_enum(db).is_data_carrying(db) {
@@ -824,6 +825,35 @@ fn definition_mod_path(db: &RootDatabase, def: &Definition, edition: Edition) ->
824825
.map(|module| path(db, module, definition_owner_name(db, def, edition), edition))
825826
}
826827

828+
fn get_docs(
829+
sema @ &Semantics { db, .. }: &Semantics<'_, RootDatabase>,
830+
def: Definition,
831+
famous_defs: Option<&FamousDefs<'_, '_>>,
832+
edition: Edition,
833+
) -> Option<Documentation> {
834+
let mut docs = def.docs(db, famous_defs, edition);
835+
let mut def = def;
836+
837+
// Searching for type alias without docs attr.
838+
while let Definition::TypeAlias(type_alias) = def {
839+
if docs.is_some() {
840+
break;
841+
}
842+
843+
let source = sema.source(type_alias)?;
844+
let type_alias = source.value.ty()?;
845+
846+
// Only take the first token, avoid searching docs for type parameters.
847+
// E.g. `type Y = Box<X>`
848+
let token = type_alias.syntax().first_token()?;
849+
850+
def = get_definition(sema, token)?;
851+
docs = def.docs(db, famous_defs, edition);
852+
}
853+
854+
docs
855+
}
856+
827857
fn markup(docs: Option<String>, desc: String, mod_path: Option<String>) -> Markup {
828858
let mut buf = String::new();
829859

crates/ide/src/hover/tests.rs

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9018,3 +9018,148 @@ foo!(BAR_$0);
90189018
"#]],
90199019
);
90209020
}
9021+
9022+
#[test]
9023+
fn type_alias_without_docs() {
9024+
// Simple.
9025+
check(
9026+
r#"
9027+
/// Docs for B
9028+
struct B;
9029+
9030+
type A$0 = B;
9031+
"#,
9032+
expect![[r#"
9033+
*A*
9034+
9035+
```rust
9036+
test
9037+
```
9038+
9039+
```rust
9040+
// size = 0, align = 1
9041+
type A = B
9042+
```
9043+
9044+
---
9045+
9046+
Docs for B
9047+
"#]],
9048+
);
9049+
9050+
// Nested.
9051+
check(
9052+
r#"
9053+
/// Docs for C
9054+
struct C;
9055+
9056+
type B = C;
9057+
9058+
type A$0 = B;
9059+
"#,
9060+
expect![[r#"
9061+
*A*
9062+
9063+
```rust
9064+
test
9065+
```
9066+
9067+
```rust
9068+
// size = 0, align = 1
9069+
type A = B
9070+
```
9071+
9072+
---
9073+
9074+
Docs for C
9075+
"#]],
9076+
);
9077+
9078+
// Show the first found docs.
9079+
check(
9080+
r#"
9081+
/// Docs for C
9082+
struct C;
9083+
9084+
/// Docs for B
9085+
type B = C;
9086+
9087+
type A$0 = B;
9088+
"#,
9089+
expect![[r#"
9090+
*A*
9091+
9092+
```rust
9093+
test
9094+
```
9095+
9096+
```rust
9097+
// size = 0, align = 1
9098+
type A = B
9099+
```
9100+
9101+
---
9102+
9103+
Docs for B
9104+
"#]],
9105+
);
9106+
9107+
// No docs found.
9108+
check(
9109+
r#"
9110+
struct C;
9111+
9112+
type B = C;
9113+
9114+
type A$0 = B;
9115+
"#,
9116+
expect![[r#"
9117+
*A*
9118+
9119+
```rust
9120+
test
9121+
```
9122+
9123+
```rust
9124+
// size = 0, align = 1
9125+
type A = B
9126+
```
9127+
"#]],
9128+
);
9129+
9130+
// Multiple nested crate.
9131+
check(
9132+
r#"
9133+
//- /lib.rs crate:c
9134+
/// Docs for C
9135+
pub struct C;
9136+
9137+
//- /lib.rs crate:b deps:c
9138+
pub use c::C;
9139+
pub type B = C;
9140+
9141+
//- /lib.rs crate:a deps:b
9142+
pub use b::B;
9143+
pub type A = B;
9144+
9145+
//- /main.rs crate:main deps:a
9146+
use a::A$0;
9147+
"#,
9148+
expect![[r#"
9149+
*A*
9150+
9151+
```rust
9152+
a
9153+
```
9154+
9155+
```rust
9156+
// size = 0, align = 1
9157+
pub type A = B
9158+
```
9159+
9160+
---
9161+
9162+
Docs for C
9163+
"#]],
9164+
);
9165+
}

0 commit comments

Comments
 (0)