mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #5875
5875: Remove monomorphisation from doclinks resolving code
r=matklad a=matklad
bors r+
🤖
Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
81a3404d8f
2 changed files with 43 additions and 34 deletions
|
@ -1,7 +1,6 @@
|
||||||
//! Attributes & documentation for hir types.
|
//! Attributes & documentation for hir types.
|
||||||
use hir_def::{
|
use hir_def::{
|
||||||
attr::Attrs,
|
attr::Attrs,
|
||||||
db::DefDatabase,
|
|
||||||
docs::Documentation,
|
docs::Documentation,
|
||||||
resolver::{HasResolver, Resolver},
|
resolver::{HasResolver, Resolver},
|
||||||
AdtId, AttrDefId, FunctionId, GenericDefId, ModuleId, StaticId, TraitId, VariantId,
|
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_has_attrs_adt![Struct, Union, Enum];
|
||||||
|
|
||||||
impl Resolvable for ModuleDef {
|
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 {
|
Some(match self {
|
||||||
ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db),
|
ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db.upcast()),
|
||||||
ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db),
|
ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db.upcast()),
|
||||||
ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db),
|
ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db.upcast()),
|
||||||
ModuleDef::EnumVariant(ev) => {
|
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::Const(c) => {
|
||||||
ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db),
|
GenericDefId::from(GenericDef::from(c.clone())).resolver(db.upcast())
|
||||||
ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db),
|
}
|
||||||
ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db),
|
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`
|
// FIXME: This should be a resolver relative to `std/core`
|
||||||
ModuleDef::BuiltinType(_t) => None?,
|
ModuleDef::BuiltinType(_t) => None?,
|
||||||
})
|
})
|
||||||
|
@ -85,8 +86,8 @@ impl Resolvable for ModuleDef {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resolvable for TypeParam {
|
impl Resolvable for TypeParam {
|
||||||
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
|
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
|
||||||
Some(ModuleId::from(self.module(db)).resolver(db))
|
Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_into_module_def(self) -> Option<ModuleDef> {
|
fn try_into_module_def(self) -> Option<ModuleDef> {
|
||||||
|
@ -95,8 +96,8 @@ impl Resolvable for TypeParam {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resolvable for MacroDef {
|
impl Resolvable for MacroDef {
|
||||||
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
|
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
|
||||||
Some(ModuleId::from(self.module(db)?).resolver(db))
|
Some(ModuleId::from(self.module(db)?).resolver(db.upcast()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_into_module_def(self) -> Option<ModuleDef> {
|
fn try_into_module_def(self) -> Option<ModuleDef> {
|
||||||
|
@ -105,8 +106,8 @@ impl Resolvable for MacroDef {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resolvable for Field {
|
impl Resolvable for Field {
|
||||||
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
|
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
|
||||||
Some(VariantId::from(self.parent_def(db)).resolver(db))
|
Some(VariantId::from(self.parent_def(db)).resolver(db.upcast()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_into_module_def(self) -> Option<ModuleDef> {
|
fn try_into_module_def(self) -> Option<ModuleDef> {
|
||||||
|
@ -115,8 +116,8 @@ impl Resolvable for Field {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resolvable for ImplDef {
|
impl Resolvable for ImplDef {
|
||||||
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
|
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
|
||||||
Some(ModuleId::from(self.module(db)).resolver(db))
|
Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_into_module_def(self) -> Option<ModuleDef> {
|
fn try_into_module_def(self) -> Option<ModuleDef> {
|
||||||
|
@ -125,8 +126,8 @@ impl Resolvable for ImplDef {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resolvable for Local {
|
impl Resolvable for Local {
|
||||||
fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
|
fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
|
||||||
Some(ModuleId::from(self.module(db)).resolver(db))
|
Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_into_module_def(self) -> Option<ModuleDef> {
|
fn try_into_module_def(self) -> Option<ModuleDef> {
|
||||||
|
|
|
@ -2,22 +2,33 @@
|
||||||
|
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
|
|
||||||
use hir_def::{db::DefDatabase, resolver::Resolver};
|
use hir_def::resolver::Resolver;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use syntax::ast::Path;
|
use syntax::ast::Path;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef};
|
use crate::{db::HirDatabase, Adt, AsName, Crate, Hygiene, ItemInNs, ModPath, ModuleDef};
|
||||||
|
|
||||||
pub fn resolve_doc_link<T: Resolvable + Clone, D: DefDatabase + HirDatabase>(
|
pub fn resolve_doc_link<T: Resolvable + Clone>(
|
||||||
db: &D,
|
db: &dyn HirDatabase,
|
||||||
definition: &T,
|
definition: &T,
|
||||||
link_text: &str,
|
link_text: &str,
|
||||||
link_target: &str,
|
link_target: &str,
|
||||||
) -> Option<(String, String)> {
|
) -> Option<(String, String)> {
|
||||||
try_resolve_intra(db, definition, link_text, &link_target).or_else(|| {
|
let resolver = definition.resolver(db)?;
|
||||||
let definition = definition.clone().try_into_module_def()?;
|
let module_def = definition.clone().try_into_module_def();
|
||||||
try_resolve_path(db, &definition, &link_target)
|
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()))
|
.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`).
|
/// 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).
|
/// 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>(
|
fn try_resolve_intra(
|
||||||
db: &D,
|
db: &dyn HirDatabase,
|
||||||
definition: &T,
|
resolver: &Resolver,
|
||||||
link_text: &str,
|
link_text: &str,
|
||||||
link_target: &str,
|
link_target: &str,
|
||||||
) -> Option<(String, String)> {
|
) -> Option<(String, String)> {
|
||||||
|
@ -41,10 +52,7 @@ fn try_resolve_intra<T: Resolvable, D: DefDatabase + HirDatabase>(
|
||||||
let path = Path::parse(doclink.path).ok()?;
|
let path = Path::parse(doclink.path).ok()?;
|
||||||
let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
|
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 resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
|
||||||
let resolver = definition.resolver(db)?;
|
|
||||||
|
|
||||||
let resolved = resolver.resolve_module_path_in_items(db, &modpath);
|
|
||||||
let (defid, namespace) = match doclink.namespace {
|
let (defid, namespace) = match doclink.namespace {
|
||||||
// FIXME: .or(resolved.macros)
|
// FIXME: .or(resolved.macros)
|
||||||
None => resolved
|
None => resolved
|
||||||
|
@ -225,6 +233,6 @@ impl Namespace {
|
||||||
|
|
||||||
/// Sealed trait used solely for the generic bound on [`resolve_doc_link`].
|
/// Sealed trait used solely for the generic bound on [`resolve_doc_link`].
|
||||||
pub trait Resolvable {
|
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>;
|
fn try_into_module_def(self) -> Option<ModuleDef>;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue