mirror of
				https://github.com/rust-lang/rust-analyzer.git
				synced 2025-11-03 13:13:18 +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
					
				@ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user