From cd9ecdf467d8e06a68400785b3dac83d561449ee Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 25 Aug 2020 14:57:26 +0200 Subject: [PATCH] Remove monomorphisation from doclinks resolving code --- crates/hir/src/attrs.rs | 41 +++++++++++++++++++------------------ crates/hir/src/doc_links.rs | 36 +++++++++++++++++++------------- 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 36027d183e..e5a539cb8d 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -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 @@ macro_rules! impl_has_attrs_adt { impl_has_attrs_adt![Struct, Union, Enum]; impl Resolvable for ModuleDef { - fn resolver(&self, db: &D) -> Option { + fn resolver(&self, db: &dyn HirDatabase) -> Option { 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 @@ impl Resolvable for ModuleDef { } impl Resolvable for TypeParam { - fn resolver(&self, db: &D) -> Option { - Some(ModuleId::from(self.module(db)).resolver(db)) + fn resolver(&self, db: &dyn HirDatabase) -> Option { + Some(ModuleId::from(self.module(db)).resolver(db.upcast())) } fn try_into_module_def(self) -> Option { @@ -95,8 +96,8 @@ impl Resolvable for TypeParam { } impl Resolvable for MacroDef { - fn resolver(&self, db: &D) -> Option { - Some(ModuleId::from(self.module(db)?).resolver(db)) + fn resolver(&self, db: &dyn HirDatabase) -> Option { + Some(ModuleId::from(self.module(db)?).resolver(db.upcast())) } fn try_into_module_def(self) -> Option { @@ -105,8 +106,8 @@ impl Resolvable for MacroDef { } impl Resolvable for Field { - fn resolver(&self, db: &D) -> Option { - Some(VariantId::from(self.parent_def(db)).resolver(db)) + fn resolver(&self, db: &dyn HirDatabase) -> Option { + Some(VariantId::from(self.parent_def(db)).resolver(db.upcast())) } fn try_into_module_def(self) -> Option { @@ -115,8 +116,8 @@ impl Resolvable for Field { } impl Resolvable for ImplDef { - fn resolver(&self, db: &D) -> Option { - Some(ModuleId::from(self.module(db)).resolver(db)) + fn resolver(&self, db: &dyn HirDatabase) -> Option { + Some(ModuleId::from(self.module(db)).resolver(db.upcast())) } fn try_into_module_def(self) -> Option { @@ -125,8 +126,8 @@ impl Resolvable for ImplDef { } impl Resolvable for Local { - fn resolver(&self, db: &D) -> Option { - Some(ModuleId::from(self.module(db)).resolver(db)) + fn resolver(&self, db: &dyn HirDatabase) -> Option { + Some(ModuleId::from(self.module(db)).resolver(db.upcast())) } fn try_into_module_def(self) -> Option { diff --git a/crates/hir/src/doc_links.rs b/crates/hir/src/doc_links.rs index a77758675a..ddaffbec25 100644 --- a/crates/hir/src/doc_links.rs +++ b/crates/hir/src/doc_links.rs @@ -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( - db: &D, +pub fn resolve_doc_link( + 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, + 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( /// 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( - 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( 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 @@ impl Namespace { /// Sealed trait used solely for the generic bound on [`resolve_doc_link`]. pub trait Resolvable { - fn resolver(&self, db: &D) -> Option; + fn resolver(&self, db: &dyn HirDatabase) -> Option; fn try_into_module_def(self) -> Option; }