]> git.lizzy.rs Git - rust.git/commitdiff
Remove monomorphisation from doclinks resolving code
authorAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 25 Aug 2020 12:57:26 +0000 (14:57 +0200)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 25 Aug 2020 12:58:22 +0000 (14:58 +0200)
crates/hir/src/attrs.rs
crates/hir/src/doc_links.rs

index 36027d183e155b2fdb680ebe4d367eb39dadb9d0..e5a539cb8d66e537ac1675604b1d308310e83e2d 100644 (file)
@@ -1,7 +1,6 @@
 //! Attributes & documentation for hir types.
 use hir_def::{
     attr::Attrs,
-    db::DefDatabase,
     docs::Documentation,
     resolver::{HasResolver, Resolver},
     AdtId, AttrDefId, FunctionId, GenericDefId, ModuleId, StaticId, TraitId, VariantId,
@@ -62,18 +61,20 @@ fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
 impl_has_attrs_adt![Struct, Union, Enum];
 
 impl Resolvable for ModuleDef {
-    fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
+    fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
         Some(match self {
-            ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db),
-            ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db),
-            ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db),
+            ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db.upcast()),
+            ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db.upcast()),
+            ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db.upcast()),
             ModuleDef::EnumVariant(ev) => {
-                GenericDefId::from(GenericDef::from(ev.clone())).resolver(db)
+                GenericDefId::from(GenericDef::from(ev.clone())).resolver(db.upcast())
             }
-            ModuleDef::Const(c) => GenericDefId::from(GenericDef::from(c.clone())).resolver(db),
-            ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db),
-            ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db),
-            ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db),
+            ModuleDef::Const(c) => {
+                GenericDefId::from(GenericDef::from(c.clone())).resolver(db.upcast())
+            }
+            ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db.upcast()),
+            ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db.upcast()),
+            ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db.upcast()),
             // FIXME: This should be a resolver relative to `std/core`
             ModuleDef::BuiltinType(_t) => None?,
         })
@@ -85,8 +86,8 @@ fn try_into_module_def(self) -> Option<ModuleDef> {
 }
 
 impl Resolvable for TypeParam {
-    fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
-        Some(ModuleId::from(self.module(db)).resolver(db))
+    fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
+        Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
     }
 
     fn try_into_module_def(self) -> Option<ModuleDef> {
@@ -95,8 +96,8 @@ fn try_into_module_def(self) -> Option<ModuleDef> {
 }
 
 impl Resolvable for MacroDef {
-    fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
-        Some(ModuleId::from(self.module(db)?).resolver(db))
+    fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
+        Some(ModuleId::from(self.module(db)?).resolver(db.upcast()))
     }
 
     fn try_into_module_def(self) -> Option<ModuleDef> {
@@ -105,8 +106,8 @@ fn try_into_module_def(self) -> Option<ModuleDef> {
 }
 
 impl Resolvable for Field {
-    fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
-        Some(VariantId::from(self.parent_def(db)).resolver(db))
+    fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
+        Some(VariantId::from(self.parent_def(db)).resolver(db.upcast()))
     }
 
     fn try_into_module_def(self) -> Option<ModuleDef> {
@@ -115,8 +116,8 @@ fn try_into_module_def(self) -> Option<ModuleDef> {
 }
 
 impl Resolvable for ImplDef {
-    fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
-        Some(ModuleId::from(self.module(db)).resolver(db))
+    fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
+        Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
     }
 
     fn try_into_module_def(self) -> Option<ModuleDef> {
@@ -125,8 +126,8 @@ fn try_into_module_def(self) -> Option<ModuleDef> {
 }
 
 impl Resolvable for Local {
-    fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
-        Some(ModuleId::from(self.module(db)).resolver(db))
+    fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
+        Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
     }
 
     fn try_into_module_def(self) -> Option<ModuleDef> {
index a77758675a0c7f054c629de2ed443216243ab776..ddaffbec25547229aedbacf3451cfc98fb41e787 100644 (file)
@@ -2,22 +2,33 @@
 
 use std::iter::once;
 
-use hir_def::{db::DefDatabase, resolver::Resolver};
+use hir_def::resolver::Resolver;
 use itertools::Itertools;
 use syntax::ast::Path;
 use url::Url;
 
 use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef};
 
-pub fn resolve_doc_link<T: Resolvable + Clone, D: DefDatabase + HirDatabase>(
-    db: &D,
+pub fn resolve_doc_link<T: Resolvable + Clone>(
+    db: &dyn HirDatabase,
     definition: &T,
     link_text: &str,
     link_target: &str,
 ) -> Option<(String, String)> {
-    try_resolve_intra(db, definition, link_text, &link_target).or_else(|| {
-        let definition = definition.clone().try_into_module_def()?;
-        try_resolve_path(db, &definition, &link_target)
+    let resolver = definition.resolver(db)?;
+    let module_def = definition.clone().try_into_module_def();
+    resolve_doc_link_impl(db, &resolver, module_def, link_text, link_target)
+}
+
+fn resolve_doc_link_impl(
+    db: &dyn HirDatabase,
+    resolver: &Resolver,
+    module_def: Option<ModuleDef>,
+    link_text: &str,
+    link_target: &str,
+) -> Option<(String, String)> {
+    try_resolve_intra(db, &resolver, link_text, &link_target).or_else(|| {
+        try_resolve_path(db, &module_def?, &link_target)
             .map(|target| (target, link_text.to_string()))
     })
 }
@@ -25,9 +36,9 @@ pub fn resolve_doc_link<T: Resolvable + Clone, D: DefDatabase + HirDatabase>(
 /// Try to resolve path to local documentation via intra-doc-links (i.e. `super::gateway::Shard`).
 ///
 /// See [RFC1946](https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md).
-fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>(
-    db: &D,
-    definition: &T,
+fn try_resolve_intra(
+    db: &dyn HirDatabase,
+    resolver: &Resolver,
     link_text: &str,
     link_target: &str,
 ) -> Option<(String, String)> {
@@ -41,10 +52,7 @@ fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>(
     let path = Path::parse(doclink.path).ok()?;
     let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
 
-    // Resolve it relative to symbol's location (according to the RFC this should consider small scopes)
-    let resolver = definition.resolver(db)?;
-
-    let resolved = resolver.resolve_module_path_in_items(db, &modpath);
+    let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
     let (defid, namespace) = match doclink.namespace {
         // FIXME: .or(resolved.macros)
         None => resolved
@@ -225,6 +233,6 @@ fn from_intra_spec(s: &str) -> Option<Self> {
 
 /// Sealed trait used solely for the generic bound on [`resolve_doc_link`].
 pub trait Resolvable {
-    fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver>;
+    fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver>;
     fn try_into_module_def(self) -> Option<ModuleDef>;
 }