aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/doc_links.rs
diff options
context:
space:
mode:
authorZac Pullar-Strecker <[email protected]>2020-09-03 08:55:24 +0100
committerZac Pullar-Strecker <[email protected]>2020-10-08 03:04:21 +0100
commitc648884397bfdb779c447fa31964dc1fce94bd95 (patch)
tree276467ffe91360d31f285ce04bf16c0753c61a10 /crates/ide/src/doc_links.rs
parent62b76e7004bc215a375e41bd204b2eab5acdf9c2 (diff)
Differentiate method/tymethod by determining 'defaultness'
Currently a method only has defaultness if it is a provided trait method, but this will change when specialisation is available and may need to become a concept known to hir. I opted to go for a 'fewest changes' approach given specialisation is still under development.
Diffstat (limited to 'crates/ide/src/doc_links.rs')
-rw-r--r--crates/ide/src/doc_links.rs19
1 files changed, 14 insertions, 5 deletions
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs
index 512c42c4d..2f6c59c40 100644
--- a/crates/ide/src/doc_links.rs
+++ b/crates/ide/src/doc_links.rs
@@ -13,7 +13,7 @@ use ide_db::{defs::Definition, RootDatabase};
13 13
14use hir::{ 14use hir::{
15 db::{DefDatabase, HirDatabase}, 15 db::{DefDatabase, HirDatabase},
16 Adt, AsName, AssocItem, Crate, Field, HasAttrs, ItemInNs, ModuleDef, 16 Adt, AsName, AssocItem, Crate, Field, HasAttrs, ItemInNs, MethodOwner, ModuleDef,
17}; 17};
18use ide_db::{ 18use ide_db::{
19 defs::{classify_name, classify_name_ref, Definition}, 19 defs::{classify_name, classify_name_ref, Definition},
@@ -117,7 +117,7 @@ fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> {
117 let target_def: ModuleDef = match definition { 117 let target_def: ModuleDef = match definition {
118 Definition::ModuleDef(moddef) => match moddef { 118 Definition::ModuleDef(moddef) => match moddef {
119 ModuleDef::Function(f) => { 119 ModuleDef::Function(f) => {
120 f.parent_def(db).map(|mowner| mowner.into()).unwrap_or_else(|| f.clone().into()) 120 f.method_owner(db).map(|mowner| mowner.into()).unwrap_or_else(|| f.clone().into())
121 } 121 }
122 moddef => moddef, 122 moddef => moddef,
123 }, 123 },
@@ -401,9 +401,18 @@ fn get_symbol_fragment(db: &dyn HirDatabase, field_or_assoc: &FieldOrAssocItem)
401 Some(match field_or_assoc { 401 Some(match field_or_assoc {
402 FieldOrAssocItem::Field(field) => format!("#structfield.{}", field.name(db)), 402 FieldOrAssocItem::Field(field) => format!("#structfield.{}", field.name(db)),
403 FieldOrAssocItem::AssocItem(assoc) => match assoc { 403 FieldOrAssocItem::AssocItem(assoc) => match assoc {
404 // TODO: Rustdoc sometimes uses tymethod instead of method. This case needs to be investigated. 404 AssocItem::Function(function) => {
405 AssocItem::Function(function) => format!("#method.{}", function.name(db)), 405 let is_trait_method =
406 // TODO: This might be the old method for documenting associated constants, i32::MAX uses a separate page... 406 matches!(function.method_owner(db), Some(MethodOwner::Trait(..)));
407 // This distinction may get more complicated when specialisation is available.
408 // In particular this decision is made based on whether a method 'has defaultness'.
409 // Currently this is only the case for provided trait methods.
410 if is_trait_method && !function.has_body(db) {
411 format!("#tymethod.{}", function.name(db))
412 } else {
413 format!("#method.{}", function.name(db))
414 }
415 }
407 AssocItem::Const(constant) => format!("#associatedconstant.{}", constant.name(db)?), 416 AssocItem::Const(constant) => format!("#associatedconstant.{}", constant.name(db)?),
408 AssocItem::TypeAlias(ty) => format!("#associatedtype.{}", ty.name(db)), 417 AssocItem::TypeAlias(ty) => format!("#associatedtype.{}", ty.name(db)),
409 }, 418 },