diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-04-19 13:51:57 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-04-19 13:51:57 +0000 |
| commit | 6991b517f2c1ba9eb75f98ca689378e8dfa1e87f (patch) | |
| tree | 9da882e4925f3b21f13f539b60fee7b007211a12 | |
| parent | deb939ac918a65c8875c488d43914a1c1aa5781b (diff) | |
| parent | 6142afeafda77a412b5565d91f222b8e085b0752 (diff) | |
| download | rust-6991b517f2c1ba9eb75f98ca689378e8dfa1e87f.tar.gz rust-6991b517f2c1ba9eb75f98ca689378e8dfa1e87f.zip | |
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>
| -rw-r--r-- | crates/ide/src/doc_links.rs | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index c5dc14a237a..cb5a8e19a9d 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs @@ -108,13 +108,13 @@ pub(crate) fn external_docs( let node = token.parent()?; let definition = match_ast! { match node { - ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)), - ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined(sema.db)), - _ => None, + ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db))?, + ast::Name(name) => NameClass::classify(&sema, &name).map(|d| d.referenced_or_defined(sema.db))?, + _ => return None, } }; - get_doc_link(db, definition?) + get_doc_link(db, definition) } /// 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 // This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented // https://github.com/rust-lang/rfcs/pull/2988 fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> { - // Get the outermost definition for the moduledef. This is used to resolve the public path to the type, + // Get the outermost definition for the module def. This is used to resolve the public path to the type, // then we can join the method, field, etc onto it if required. let target_def: ModuleDef = match definition { - Definition::ModuleDef(moddef) => match moddef { + Definition::ModuleDef(def) => match def { ModuleDef::Function(f) => f .as_assoc_item(db) .and_then(|assoc| match assoc.container(db) { AssocItemContainer::Trait(t) => Some(t.into()), - AssocItemContainer::Impl(impld) => { - impld.self_ty(db).as_adt().map(|adt| adt.into()) + AssocItemContainer::Impl(impl_) => { + impl_.self_ty(db).as_adt().map(|adt| adt.into()) } }) - .unwrap_or_else(|| f.clone().into()), - moddef => moddef, + .unwrap_or_else(|| def), + def => def, }, Definition::Field(f) => f.parent_def(db).into(), // FIXME: Handle macros @@ -236,17 +236,28 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> { let ns = ItemInNs::from(target_def); - let module = definition.module(db)?; - let krate = module.krate(); + let krate = match definition { + // Definition::module gives back the parent module, we don't want that as it fails for root modules + Definition::ModuleDef(ModuleDef::Module(module)) => module.krate(), + _ => definition.module(db)?.krate(), + }; let import_map = db.import_map(krate.into()); - let base = once(krate.display_name(db)?.to_string()) - .chain(import_map.path_of(ns)?.segments.iter().map(|name| name.to_string())) - .join("/") - + "/"; + + let mut base = krate.display_name(db)?.to_string(); + let is_root_module = matches!( + definition, + Definition::ModuleDef(ModuleDef::Module(module)) if krate.root_module(db) == module + ); + if !is_root_module { + base = once(base) + .chain(import_map.path_of(ns)?.segments.iter().map(|name| name.to_string())) + .join("/"); + } + base += "/"; let filename = get_symbol_filename(db, &target_def); let fragment = match definition { - Definition::ModuleDef(moddef) => match moddef { + Definition::ModuleDef(def) => match def { ModuleDef::Function(f) => { get_symbol_fragment(db, &FieldOrAssocItem::AssocItem(AssocItem::Function(f))) } @@ -533,6 +544,19 @@ mod tests { } #[test] + fn test_doc_url_crate() { + check( + r#" +//- /main.rs crate:main deps:test +use test$0::Foo; +//- /lib.rs crate:test +pub struct Foo; +"#, + expect![[r#"https://docs.rs/test/*/test/index.html"#]], + ); + } + + #[test] fn test_doc_url_struct() { check( r#" |
