aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/attrs.rs41
-rw-r--r--crates/hir/src/doc_links.rs36
2 files changed, 43 insertions, 34 deletions
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index 36027d183..e5a539cb8 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -1,7 +1,6 @@
1//! Attributes & documentation for hir types. 1//! Attributes & documentation for hir types.
2use hir_def::{ 2use hir_def::{
3 attr::Attrs, 3 attr::Attrs,
4 db::DefDatabase,
5 docs::Documentation, 4 docs::Documentation,
6 resolver::{HasResolver, Resolver}, 5 resolver::{HasResolver, Resolver},
7 AdtId, AttrDefId, FunctionId, GenericDefId, ModuleId, StaticId, TraitId, VariantId, 6 AdtId, AttrDefId, FunctionId, GenericDefId, ModuleId, StaticId, TraitId, VariantId,
@@ -62,18 +61,20 @@ macro_rules! impl_has_attrs_adt {
62impl_has_attrs_adt![Struct, Union, Enum]; 61impl_has_attrs_adt![Struct, Union, Enum];
63 62
64impl Resolvable for ModuleDef { 63impl Resolvable for ModuleDef {
65 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { 64 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
66 Some(match self { 65 Some(match self {
67 ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db), 66 ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db.upcast()),
68 ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db), 67 ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db.upcast()),
69 ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db), 68 ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db.upcast()),
70 ModuleDef::EnumVariant(ev) => { 69 ModuleDef::EnumVariant(ev) => {
71 GenericDefId::from(GenericDef::from(ev.clone())).resolver(db) 70 GenericDefId::from(GenericDef::from(ev.clone())).resolver(db.upcast())
72 } 71 }
73 ModuleDef::Const(c) => GenericDefId::from(GenericDef::from(c.clone())).resolver(db), 72 ModuleDef::Const(c) => {
74 ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db), 73 GenericDefId::from(GenericDef::from(c.clone())).resolver(db.upcast())
75 ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db), 74 }
76 ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db), 75 ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db.upcast()),
76 ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db.upcast()),
77 ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db.upcast()),
77 // FIXME: This should be a resolver relative to `std/core` 78 // FIXME: This should be a resolver relative to `std/core`
78 ModuleDef::BuiltinType(_t) => None?, 79 ModuleDef::BuiltinType(_t) => None?,
79 }) 80 })
@@ -85,8 +86,8 @@ impl Resolvable for ModuleDef {
85} 86}
86 87
87impl Resolvable for TypeParam { 88impl Resolvable for TypeParam {
88 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { 89 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
89 Some(ModuleId::from(self.module(db)).resolver(db)) 90 Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
90 } 91 }
91 92
92 fn try_into_module_def(self) -> Option<ModuleDef> { 93 fn try_into_module_def(self) -> Option<ModuleDef> {
@@ -95,8 +96,8 @@ impl Resolvable for TypeParam {
95} 96}
96 97
97impl Resolvable for MacroDef { 98impl Resolvable for MacroDef {
98 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { 99 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
99 Some(ModuleId::from(self.module(db)?).resolver(db)) 100 Some(ModuleId::from(self.module(db)?).resolver(db.upcast()))
100 } 101 }
101 102
102 fn try_into_module_def(self) -> Option<ModuleDef> { 103 fn try_into_module_def(self) -> Option<ModuleDef> {
@@ -105,8 +106,8 @@ impl Resolvable for MacroDef {
105} 106}
106 107
107impl Resolvable for Field { 108impl Resolvable for Field {
108 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { 109 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
109 Some(VariantId::from(self.parent_def(db)).resolver(db)) 110 Some(VariantId::from(self.parent_def(db)).resolver(db.upcast()))
110 } 111 }
111 112
112 fn try_into_module_def(self) -> Option<ModuleDef> { 113 fn try_into_module_def(self) -> Option<ModuleDef> {
@@ -115,8 +116,8 @@ impl Resolvable for Field {
115} 116}
116 117
117impl Resolvable for ImplDef { 118impl Resolvable for ImplDef {
118 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { 119 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
119 Some(ModuleId::from(self.module(db)).resolver(db)) 120 Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
120 } 121 }
121 122
122 fn try_into_module_def(self) -> Option<ModuleDef> { 123 fn try_into_module_def(self) -> Option<ModuleDef> {
@@ -125,8 +126,8 @@ impl Resolvable for ImplDef {
125} 126}
126 127
127impl Resolvable for Local { 128impl Resolvable for Local {
128 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { 129 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
129 Some(ModuleId::from(self.module(db)).resolver(db)) 130 Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
130 } 131 }
131 132
132 fn try_into_module_def(self) -> Option<ModuleDef> { 133 fn try_into_module_def(self) -> Option<ModuleDef> {
diff --git a/crates/hir/src/doc_links.rs b/crates/hir/src/doc_links.rs
index a77758675..ddaffbec2 100644
--- a/crates/hir/src/doc_links.rs
+++ b/crates/hir/src/doc_links.rs
@@ -2,22 +2,33 @@
2 2
3use std::iter::once; 3use std::iter::once;
4 4
5use hir_def::{db::DefDatabase, resolver::Resolver}; 5use hir_def::resolver::Resolver;
6use itertools::Itertools; 6use itertools::Itertools;
7use syntax::ast::Path; 7use syntax::ast::Path;
8use url::Url; 8use url::Url;
9 9
10use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef}; 10use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef};
11 11
12pub fn resolve_doc_link<T: Resolvable + Clone, D: DefDatabase + HirDatabase>( 12pub fn resolve_doc_link<T: Resolvable + Clone>(
13 db: &D, 13 db: &dyn HirDatabase,
14 definition: &T, 14 definition: &T,
15 link_text: &str, 15 link_text: &str,
16 link_target: &str, 16 link_target: &str,
17) -> Option<(String, String)> { 17) -> Option<(String, String)> {
18 try_resolve_intra(db, definition, link_text, &link_target).or_else(|| { 18 let resolver = definition.resolver(db)?;
19 let definition = definition.clone().try_into_module_def()?; 19 let module_def = definition.clone().try_into_module_def();
20 try_resolve_path(db, &definition, &link_target) 20 resolve_doc_link_impl(db, &resolver, module_def, link_text, link_target)
21}
22
23fn resolve_doc_link_impl(
24 db: &dyn HirDatabase,
25 resolver: &Resolver,
26 module_def: Option<ModuleDef>,
27 link_text: &str,
28 link_target: &str,
29) -> Option<(String, String)> {
30 try_resolve_intra(db, &resolver, link_text, &link_target).or_else(|| {
31 try_resolve_path(db, &module_def?, &link_target)
21 .map(|target| (target, link_text.to_string())) 32 .map(|target| (target, link_text.to_string()))
22 }) 33 })
23} 34}
@@ -25,9 +36,9 @@ pub fn resolve_doc_link<T: Resolvable + Clone, D: DefDatabase + HirDatabase>(
25/// Try to resolve path to local documentation via intra-doc-links (i.e. `super::gateway::Shard`). 36/// Try to resolve path to local documentation via intra-doc-links (i.e. `super::gateway::Shard`).
26/// 37///
27/// See [RFC1946](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md). 38/// See [RFC1946](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md).
28fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>( 39fn try_resolve_intra(
29 db: &D, 40 db: &dyn HirDatabase,
30 definition: &T, 41 resolver: &Resolver,
31 link_text: &str, 42 link_text: &str,
32 link_target: &str, 43 link_target: &str,
33) -> Option<(String, String)> { 44) -> Option<(String, String)> {
@@ -41,10 +52,7 @@ fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>(
41 let path = Path::parse(doclink.path).ok()?; 52 let path = Path::parse(doclink.path).ok()?;
42 let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap(); 53 let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
43 54
44 // Resolve it relative to symbol's location (according to the RFC this should consider small scopes) 55 let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
45 let resolver = definition.resolver(db)?;
46
47 let resolved = resolver.resolve_module_path_in_items(db, &modpath);
48 let (defid, namespace) = match doclink.namespace { 56 let (defid, namespace) = match doclink.namespace {
49 // FIXME: .or(resolved.macros) 57 // FIXME: .or(resolved.macros)
50 None => resolved 58 None => resolved
@@ -225,6 +233,6 @@ impl Namespace {
225 233
226/// Sealed trait used solely for the generic bound on [`resolve_doc_link`]. 234/// Sealed trait used solely for the generic bound on [`resolve_doc_link`].
227pub trait Resolvable { 235pub trait Resolvable {
228 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver>; 236 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver>;
229 fn try_into_module_def(self) -> Option<ModuleDef>; 237 fn try_into_module_def(self) -> Option<ModuleDef>;
230} 238}