diff options
-rw-r--r-- | crates/hir/src/code_model.rs | 39 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ide/src/doc_links.rs | 35 | ||||
-rw-r--r-- | crates/ide/src/hover.rs | 2 |
4 files changed, 27 insertions, 53 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 9989b9b56..650b4fa40 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -35,7 +35,7 @@ use hir_ty::{ | |||
35 | traits::SolutionVariables, | 35 | traits::SolutionVariables, |
36 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, | 36 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, |
37 | InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty, | 37 | InEnvironment, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitEnvironment, Ty, |
38 | TyDefId, TyKind, TypeCtor, TyLoweringContext, | 38 | TyDefId, TyKind, TypeCtor, |
39 | }; | 39 | }; |
40 | use rustc_hash::FxHashSet; | 40 | use rustc_hash::FxHashSet; |
41 | use stdx::impl_from; | 41 | use stdx::impl_from; |
@@ -186,15 +186,6 @@ impl_from!( | |||
186 | for ModuleDef | 186 | for ModuleDef |
187 | ); | 187 | ); |
188 | 188 | ||
189 | impl From<MethodOwner> for ModuleDef { | ||
190 | fn from(mowner: MethodOwner) -> Self { | ||
191 | match mowner { | ||
192 | MethodOwner::Trait(t) => t.into(), | ||
193 | MethodOwner::Adt(t) => t.into(), | ||
194 | } | ||
195 | } | ||
196 | } | ||
197 | |||
198 | impl From<VariantDef> for ModuleDef { | 189 | impl From<VariantDef> for ModuleDef { |
199 | fn from(var: VariantDef) -> Self { | 190 | fn from(var: VariantDef) -> Self { |
200 | match var { | 191 | match var { |
@@ -778,36 +769,8 @@ impl Function { | |||
778 | pub fn has_body(self, db: &dyn HirDatabase) -> bool { | 769 | pub fn has_body(self, db: &dyn HirDatabase) -> bool { |
779 | db.function_data(self.id).has_body | 770 | db.function_data(self.id).has_body |
780 | } | 771 | } |
781 | |||
782 | /// If this function is a method, the trait or type where it is declared. | ||
783 | pub fn method_owner(self, db: &dyn HirDatabase) -> Option<MethodOwner> { | ||
784 | match self.as_assoc_item(db).map(|assoc| assoc.container(db)) { | ||
785 | Some(AssocItemContainer::Trait(t)) => Some(t.into()), | ||
786 | Some(AssocItemContainer::ImplDef(imp)) => { | ||
787 | let resolver = ModuleId::from(imp.module(db)).resolver(db.upcast()); | ||
788 | let ctx = TyLoweringContext::new(db, &resolver); | ||
789 | let adt = Ty::from_hir( | ||
790 | &ctx, | ||
791 | &imp.target_trait(db).unwrap_or_else(|| imp.target_type(db)), | ||
792 | ) | ||
793 | .as_adt() | ||
794 | .map(|t| t.0) | ||
795 | .unwrap(); | ||
796 | Some(Adt::from(adt).into()) | ||
797 | } | ||
798 | None => None, | ||
799 | } | ||
800 | } | ||
801 | } | 772 | } |
802 | 773 | ||
803 | #[derive(Debug)] | ||
804 | pub enum MethodOwner { | ||
805 | Trait(Trait), | ||
806 | Adt(Adt), | ||
807 | } | ||
808 | |||
809 | impl_from!(Trait, Adt for MethodOwner); | ||
810 | |||
811 | // Note: logically, this belongs to `hir_ty`, but we are not using it there yet. | 774 | // Note: logically, this belongs to `hir_ty`, but we are not using it there yet. |
812 | pub enum Access { | 775 | pub enum Access { |
813 | Shared, | 776 | Shared, |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 687abe6ca..4094a76cb 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -35,8 +35,8 @@ pub use crate::{ | |||
35 | code_model::{ | 35 | code_model::{ |
36 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, | 36 | Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const, |
37 | Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function, | 37 | Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function, |
38 | GenericDef, HasVisibility, ImplDef, Local, MacroDef, MethodOwner, Module, ModuleDef, | 38 | GenericDef, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, Static, |
39 | ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, | 39 | Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, |
40 | }, | 40 | }, |
41 | has_source::HasSource, | 41 | has_source::HasSource, |
42 | semantics::{original_range, PathResolution, Semantics, SemanticsScope}, | 42 | semantics::{original_range, PathResolution, Semantics, SemanticsScope}, |
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 5ef708647..06af36b73 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs | |||
@@ -3,13 +3,14 @@ | |||
3 | use std::iter::once; | 3 | use std::iter::once; |
4 | 4 | ||
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | use pulldown_cmark_to_cmark::{cmark_with_options, Options as CmarkOptions}; | ||
7 | use pulldown_cmark::{CowStr, Event, LinkType, Options, Parser, Tag}; | 6 | use pulldown_cmark::{CowStr, Event, LinkType, Options, Parser, Tag}; |
7 | use pulldown_cmark_to_cmark::{cmark_with_options, Options as CmarkOptions}; | ||
8 | use url::Url; | 8 | use url::Url; |
9 | 9 | ||
10 | use hir::{ | 10 | use hir::{ |
11 | db::{DefDatabase, HirDatabase}, | 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 | use ide_db::{ | 15 | use ide_db::{ |
15 | defs::{classify_name, classify_name_ref, Definition}, | 16 | defs::{classify_name, classify_name_ref, Definition}, |
@@ -97,18 +98,23 @@ pub fn remove_links(markdown: &str) -> String { | |||
97 | // BUG: For Option::Some | 98 | // BUG: For Option::Some |
98 | // Returns https://doc.rust-lang.org/nightly/core/prelude/v1/enum.Option.html#variant.Some | 99 | // Returns https://doc.rust-lang.org/nightly/core/prelude/v1/enum.Option.html#variant.Some |
99 | // Instead of https://doc.rust-lang.org/nightly/core/option/enum.Option.html | 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 | // |
101 | // but it's really just working around the problem. Ideally we need to implement a slightly different | 102 | // This should cease to be a problem if RFC2988 (Stable Rustdoc URLs) is implemented |
102 | // version of import map which follows the same process as rustdoc. Otherwise there'll always be some | 103 | // https://github.com/rust-lang/rfcs/pull/2988 |
103 | // edge cases where we select the wrong import path. | ||
104 | fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> { | 104 | fn get_doc_link(db: &RootDatabase, definition: Definition) -> Option<String> { |
105 | // Get the outermost definition for the moduledef. This is used to resolve the public path to the type, | 105 | // Get the outermost definition for the moduledef. This is used to resolve the public path to the type, |
106 | // then we can join the method, field, etc onto it if required. | 106 | // then we can join the method, field, etc onto it if required. |
107 | let target_def: ModuleDef = match definition { | 107 | let target_def: ModuleDef = match definition { |
108 | Definition::ModuleDef(moddef) => match moddef { | 108 | Definition::ModuleDef(moddef) => match moddef { |
109 | ModuleDef::Function(f) => { | 109 | ModuleDef::Function(f) => f |
110 | f.method_owner(db).map(|mowner| mowner.into()).unwrap_or_else(|| f.clone().into()) | 110 | .as_assoc_item(db) |
111 | } | 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 | moddef => moddef, | 118 | moddef => moddef, |
113 | }, | 119 | }, |
114 | Definition::Field(f) => f.parent_def(db).into(), | 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 | /// Retrieve a link to documentation for the given symbol. | 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 | let sema = Semantics::new(db); | 224 | let sema = Semantics::new(db); |
216 | let file = sema.parse(position.file_id).syntax().clone(); | 225 | let file = sema.parse(position.file_id).syntax().clone(); |
217 | let token = pick_best(file.token_at_offset(position.offset))?; | 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 | FieldOrAssocItem::Field(field) => format!("#structfield.{}", field.name(db)), | 401 | FieldOrAssocItem::Field(field) => format!("#structfield.{}", field.name(db)), |
393 | FieldOrAssocItem::AssocItem(assoc) => match assoc { | 402 | FieldOrAssocItem::AssocItem(assoc) => match assoc { |
394 | AssocItem::Function(function) => { | 403 | AssocItem::Function(function) => { |
395 | let is_trait_method = | 404 | let is_trait_method = matches!( |
396 | matches!(function.as_assoc_item(db).map(|assoc| assoc.container(db)), Some(AssocItemContainer::Trait(..))); | 405 | function.as_assoc_item(db).map(|assoc| assoc.container(db)), |
406 | Some(AssocItemContainer::Trait(..)) | ||
407 | ); | ||
397 | // This distinction may get more complicated when specialisation is available. | 408 | // This distinction may get more complicated when specialisation is available. |
398 | // Rustdoc makes this decision based on whether a method 'has defaultness'. | 409 | // Rustdoc makes this decision based on whether a method 'has defaultness'. |
399 | // Currently this is only the case for provided trait methods. | 410 | // Currently this is only the case for provided trait methods. |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index a53359d03..6290b35bd 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -14,8 +14,8 @@ use test_utils::mark; | |||
14 | 14 | ||
15 | use crate::{ | 15 | use crate::{ |
16 | display::{macro_label, ShortLabel, ToNav, TryToNav}, | 16 | display::{macro_label, ShortLabel, ToNav, TryToNav}, |
17 | markdown_remove::remove_markdown, | ||
18 | doc_links::{remove_links, rewrite_links}, | 17 | doc_links::{remove_links, rewrite_links}, |
18 | markdown_remove::remove_markdown, | ||
19 | markup::Markup, | 19 | markup::Markup, |
20 | runnables::runnable, | 20 | runnables::runnable, |
21 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, | 21 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, |