From 44e48d75dd3e08d4fea4654b9e970a0bb4ce2d5b Mon Sep 17 00:00:00 2001 From: Khanh Duong Quoc Date: Tue, 22 Oct 2024 20:23:05 +0900 Subject: [PATCH] feat: render docs from aliased type when docs are missing --- crates/ide-db/src/defs.rs | 14 +++- crates/ide/src/hover/tests.rs | 153 ++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 1 deletion(-) diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs index 099f26eba7..0372a58281 100644 --- a/crates/ide-db/src/defs.rs +++ b/crates/ide-db/src/defs.rs @@ -179,7 +179,19 @@ impl Definition { Definition::Static(it) => it.docs(db), Definition::Trait(it) => it.docs(db), Definition::TraitAlias(it) => it.docs(db), - Definition::TypeAlias(it) => it.docs(db), + Definition::TypeAlias(it) => { + it.docs(db).or_else(|| { + // docs are missing, try to fall back to the docs of the aliased item. + let adt = it.ty(db).as_adt()?; + let docs = adt.docs(db)?; + let docs = format!( + "*This is the documentation for* `{}`\n\n{}", + adt.display(db, edition), + docs.as_str() + ); + Some(Documentation::new(docs)) + }) + } Definition::BuiltinType(it) => { famous_defs.and_then(|fd| { // std exposes prim_{} modules with docstrings on the root to document the builtins diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 81397b0785..ef835f5bef 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs @@ -9018,3 +9018,156 @@ foo!(BAR_$0); "#]], ); } + +#[test] +fn type_alias_without_docs() { + // Simple. + check( + r#" +/// Docs for B +struct B; + +type A$0 = B; +"#, + expect![[r#" + *A* + + ```rust + test + ``` + + ```rust + // size = 0, align = 1 + type A = B + ``` + + --- + + *This is the documentation for* `struct B` + + Docs for B + "#]], + ); + + // Nested. + check( + r#" +/// Docs for C +struct C; + +type B = C; + +type A$0 = B; +"#, + expect![[r#" + *A* + + ```rust + test + ``` + + ```rust + // size = 0, align = 1 + type A = B + ``` + + --- + + *This is the documentation for* `struct C` + + Docs for C + "#]], + ); + + // Showing the docs for aliased struct instead of intermediate type. + check( + r#" +/// Docs for C +struct C; + +/// Docs for B +type B = C; + +type A$0 = B; +"#, + expect![[r#" + *A* + + ```rust + test + ``` + + ```rust + // size = 0, align = 1 + type A = B + ``` + + --- + + *This is the documentation for* `struct C` + + Docs for C + "#]], + ); + + // No docs found. + check( + r#" +struct C; + +type B = C; + +type A$0 = B; +"#, + expect![[r#" + *A* + + ```rust + test + ``` + + ```rust + // size = 0, align = 1 + type A = B + ``` + "#]], + ); + + // Multiple nested crate. + check( + r#" +//- /lib.rs crate:c +/// Docs for C +pub struct C; + +//- /lib.rs crate:b deps:c +pub use c::C; +pub type B = C; + +//- /lib.rs crate:a deps:b +pub use b::B; +pub type A = B; + +//- /main.rs crate:main deps:a +use a::A$0; +"#, + expect![[r#" + *A* + + ```rust + a + ``` + + ```rust + // size = 0, align = 1 + pub type A = B + ``` + + --- + + *This is the documentation for* `pub struct C` + + Docs for C + "#]], + ); +}