Skip to content

Commit 6991b51

Browse files
bors[bot]Veykril
andauthored
Merge #8577
8577: Support crates/module roots in external_docs r=Veykril a=Veykril Fixes #8575 bors r+ Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
2 parents deb939a + 6142afe commit 6991b51

File tree

1 file changed

+41
-17
lines changed

1 file changed

+41
-17
lines changed

crates/ide/src/doc_links.rs

Lines changed: 41 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@ pub(crate) fn external_docs(
108108
let node = token.parent()?;
109109
let definition = match_ast! {
110110
match node {
111-
ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)),
112-
ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined(sema.db)),
113-
_ => None,
111+
ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db))?,
112+
ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined(sema.db))?,
113+
_ => return None,
114114
}
115115
};
116116

117-
get_doc_link(db, definition?)
117+
get_doc_link(db, definition)
118118
}
119119

120120
/// Extracts all links from a given markdown text.
@@ -214,20 +214,20 @@ fn broken_link_clone_cb<'a, 'b>(link: BrokenLink<'a>) -> Option<(CowStr<'b>, Cow
214214
// This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented
215215
// https://github.com/rust-lang/rfcs/pull/2988
216216
fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
217-
// Get the outermost definition for the moduledef. This is used to resolve the public path to the type,
217+
// Get the outermost definition for the module def. This is used to resolve the public path to the type,
218218
// then we can join the method, field, etc onto it if required.
219219
let target_def: ModuleDef = match definition {
220-
Definition::ModuleDef(moddef) => match moddef {
220+
Definition::ModuleDef(def) => match def {
221221
ModuleDef::Function(f) => f
222222
.as_assoc_item(db)
223223
.and_then(|assoc| match assoc.container(db) {
224224
AssocItemContainer::Trait(t) => Some(t.into()),
225-
AssocItemContainer::Impl(impld) => {
226-
impld.self_ty(db).as_adt().map(|adt| adt.into())
225+
AssocItemContainer::Impl(impl_) => {
226+
impl_.self_ty(db).as_adt().map(|adt| adt.into())
227227
}
228228
})
229-
.unwrap_or_else(|| f.clone().into()),
230-
moddef => moddef,
229+
.unwrap_or_else(|| def),
230+
def => def,
231231
},
232232
Definition::Field(f) => f.parent_def(db).into(),
233233
// FIXME: Handle macros
@@ -236,17 +236,28 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
236236

237237
let ns = ItemInNs::from(target_def);
238238

239-
let module = definition.module(db)?;
240-
let krate = module.krate();
239+
let krate = match definition {
240+
// Definition::module gives back the parent module, we don't want that as it fails for root modules
241+
Definition::ModuleDef(ModuleDef::Module(module)) => module.krate(),
242+
_ => definition.module(db)?.krate(),
243+
};
241244
let import_map = db.import_map(krate.into());
242-
let base = once(krate.display_name(db)?.to_string())
243-
.chain(import_map.path_of(ns)?.segments.iter().map(|name| name.to_string()))
244-
.join("/")
245-
+ "/";
245+
246+
let mut base = krate.display_name(db)?.to_string();
247+
let is_root_module = matches!(
248+
definition,
249+
Definition::ModuleDef(ModuleDef::Module(module)) if krate.root_module(db) == module
250+
);
251+
if !is_root_module {
252+
base = once(base)
253+
.chain(import_map.path_of(ns)?.segments.iter().map(|name| name.to_string()))
254+
.join("/");
255+
}
256+
base += "/";
246257

247258
let filename = get_symbol_filename(db, &target_def);
248259
let fragment = match definition {
249-
Definition::ModuleDef(moddef) => match moddef {
260+
Definition::ModuleDef(def) => match def {
250261
ModuleDef::Function(f) => {
251262
get_symbol_fragment(db, &FieldOrAssocItem::AssocItem(AssocItem::Function(f)))
252263
}
@@ -532,6 +543,19 @@ mod tests {
532543
expect.assert_eq(&url)
533544
}
534545

546+
#[test]
547+
fn test_doc_url_crate() {
548+
check(
549+
r#"
550+
//- /main.rs crate:main deps:test
551+
use test$0::Foo;
552+
//- /lib.rs crate:test
553+
pub struct Foo;
554+
"#,
555+
expect![[r#"https://docs.rs/test/*/test/index.html"#]],
556+
);
557+
}
558+
535559
#[test]
536560
fn test_doc_url_struct() {
537561
check(

0 commit comments

Comments
 (0)