|
3 | 3 | use std::iter::once;
|
4 | 4 |
|
5 | 5 | use itertools::Itertools;
|
6 |
| -use pulldown_cmark_to_cmark::{cmark_with_options, Options as CmarkOptions}; |
7 | 6 | use pulldown_cmark::{CowStr, Event, LinkType, Options, Parser, Tag};
|
| 7 | +use pulldown_cmark_to_cmark::{cmark_with_options, Options as CmarkOptions}; |
8 | 8 | use url::Url;
|
9 | 9 |
|
10 | 10 | use hir::{
|
11 | 11 | db::{DefDatabase, HirDatabase},
|
12 |
| - Adt, AsName, AssocItem, Crate, Field, HasAttrs, ItemInNs, ModuleDef, AssocItemContainer, AsAssocItem |
| 12 | + Adt, AsAssocItem, AsName, AssocItem, AssocItemContainer, Crate, Field, HasAttrs, ItemInNs, |
| 13 | + ModuleDef, |
13 | 14 | };
|
14 | 15 | use ide_db::{
|
15 | 16 | defs::{classify_name, classify_name_ref, Definition},
|
@@ -97,18 +98,23 @@ pub fn remove_links(markdown: &str) -> String {
|
97 | 98 | // BUG: For Option::Some
|
98 | 99 | // Returns https://doc.rust-lang.org/nightly/core/prelude/v1/enum.Option.html#variant.Some
|
99 | 100 | // Instead of https://doc.rust-lang.org/nightly/core/option/enum.Option.html
|
100 |
| -// This could be worked around by turning the `EnumVariant` into `Enum` before attempting resolution, |
101 |
| -// but it's really just working around the problem. Ideally we need to implement a slightly different |
102 |
| -// version of import map which follows the same process as rustdoc. Otherwise there'll always be some |
103 |
| -// edge cases where we select the wrong import path. |
| 101 | +// |
| 102 | +// This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented |
| 103 | +// https://github.com/rust-lang/rfcs/pull/2988 |
104 | 104 | fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
|
105 | 105 | // Get the outermost definition for the moduledef. This is used to resolve the public path to the type,
|
106 | 106 | // then we can join the method, field, etc onto it if required.
|
107 | 107 | let target_def: ModuleDef = match definition {
|
108 | 108 | Definition::ModuleDef(moddef) => match moddef {
|
109 |
| - ModuleDef::Function(f) => { |
110 |
| - f.method_owner(db).map(|mowner| mowner.into()).unwrap_or_else(|| f.clone().into()) |
111 |
| - } |
| 109 | + ModuleDef::Function(f) => f |
| 110 | + .as_assoc_item(db) |
| 111 | + .and_then(|assoc| match assoc.container(db) { |
| 112 | + AssocItemContainer::Trait(t) => Some(t.into()), |
| 113 | + AssocItemContainer::ImplDef(impld) => { |
| 114 | + impld.target_ty(db).as_adt().map(|adt| adt.into()) |
| 115 | + } |
| 116 | + }) |
| 117 | + .unwrap_or_else(|| f.clone().into()), |
112 | 118 | moddef => moddef,
|
113 | 119 | },
|
114 | 120 | Definition::Field(f) => f.parent_def(db).into(),
|
@@ -211,7 +217,10 @@ fn rewrite_url_link(db: &RootDatabase, def: ModuleDef, target: &str) -> Option<S
|
211 | 217 | }
|
212 | 218 |
|
213 | 219 | /// Retrieve a link to documentation for the given symbol.
|
214 |
| -pub(crate) fn external_docs(db: &RootDatabase, position: &FilePosition) -> Option<DocumentationLink> { |
| 220 | +pub(crate) fn external_docs( |
| 221 | + db: &RootDatabase, |
| 222 | + position: &FilePosition, |
| 223 | +) -> Option<DocumentationLink> { |
215 | 224 | let sema = Semantics::new(db);
|
216 | 225 | let file = sema.parse(position.file_id).syntax().clone();
|
217 | 226 | let token = pick_best(file.token_at_offset(position.offset))?;
|
@@ -392,8 +401,10 @@ fn get_symbol_fragment(db: &dyn HirDatabase, field_or_assoc: &FieldOrAssocItem)
|
392 | 401 | FieldOrAssocItem::Field(field) => format!("#structfield.{}", field.name(db)),
|
393 | 402 | FieldOrAssocItem::AssocItem(assoc) => match assoc {
|
394 | 403 | AssocItem::Function(function) => {
|
395 |
| - let is_trait_method = |
396 |
| - matches!(function.as_assoc_item(db).map(|assoc| assoc.container(db)), Some(AssocItemContainer::Trait(..))); |
| 404 | + let is_trait_method = matches!( |
| 405 | + function.as_assoc_item(db).map(|assoc| assoc.container(db)), |
| 406 | + Some(AssocItemContainer::Trait(..)) |
| 407 | + ); |
397 | 408 | // This distinction may get more complicated when specialisation is available.
|
398 | 409 | // Rustdoc makes this decision based on whether a method 'has defaultness'.
|
399 | 410 | // Currently this is only the case for provided trait methods.
|
|
0 commit comments