|
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