Merge #7348
7348: Fix broken link in intra-doc r=edwin0cheng a=sasurau4 Fix #5546 The intra-doc link doesn't work fine for trait associated method. Co-authored-by: Daiki Ihara <sasurau4@gmail.com>
This commit is contained in:
commit
1b96c79ab5
@ -2,6 +2,7 @@
|
||||
use hir_def::{
|
||||
attr::{Attrs, Documentation},
|
||||
path::ModPath,
|
||||
per_ns::PerNs,
|
||||
resolver::HasResolver,
|
||||
AttrDefId, GenericParamId, ModuleDefId,
|
||||
};
|
||||
@ -112,6 +113,11 @@ fn resolve_doc_path(
|
||||
let path = ast::Path::parse(link).ok()?;
|
||||
let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
|
||||
let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
|
||||
if resolved == PerNs::none() {
|
||||
if let Some(trait_id) = resolver.resolve_module_path_in_trait_items(db.upcast(), &modpath) {
|
||||
return Some(ModuleDefId::TraitId(trait_id));
|
||||
};
|
||||
}
|
||||
let def = match ns {
|
||||
Some(Namespace::Types) => resolved.take_types()?,
|
||||
Some(Namespace::Values) => resolved.take_values()?,
|
||||
|
@ -146,6 +146,19 @@ impl Resolver {
|
||||
self.resolve_module_path(db, path, BuiltinShadowMode::Module)
|
||||
}
|
||||
|
||||
pub fn resolve_module_path_in_trait_items(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
path: &ModPath,
|
||||
) -> Option<TraitId> {
|
||||
let (item_map, module) = self.module_scope()?;
|
||||
let (module_res, ..) = item_map.resolve_path(db, module, &path, BuiltinShadowMode::Module);
|
||||
match module_res.take_types()? {
|
||||
ModuleDefId::TraitId(it) => Some(it),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_path_in_type_ns(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
|
@ -221,14 +221,31 @@ fn rewrite_intra_doc_link(
|
||||
}?;
|
||||
let krate = resolved.module(db)?.krate();
|
||||
let canonical_path = resolved.canonical_path(db)?;
|
||||
let new_target = get_doc_url(db, &krate)?
|
||||
let mut new_url = get_doc_url(db, &krate)?
|
||||
.join(&format!("{}/", krate.display_name(db)?))
|
||||
.ok()?
|
||||
.join(&canonical_path.replace("::", "/"))
|
||||
.ok()?
|
||||
.join(&get_symbol_filename(db, &resolved)?)
|
||||
.ok()?
|
||||
.into_string();
|
||||
.ok()?;
|
||||
|
||||
if let ModuleDef::Trait(t) = resolved {
|
||||
let items = t.items(db);
|
||||
if let Some(field_or_assoc_item) = items.iter().find_map(|assoc_item| {
|
||||
if let Some(name) = assoc_item.name(db) {
|
||||
if link.to_string() == format!("{}::{}", canonical_path, name) {
|
||||
return Some(FieldOrAssocItem::AssocItem(*assoc_item));
|
||||
}
|
||||
}
|
||||
None
|
||||
}) {
|
||||
if let Some(fragment) = get_symbol_fragment(db, &field_or_assoc_item) {
|
||||
new_url = new_url.join(&fragment).ok()?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let new_target = new_url.into_string();
|
||||
let new_title = strip_prefixes_suffixes(title);
|
||||
Some((new_target, new_title.to_string()))
|
||||
}
|
||||
|
@ -1826,6 +1826,35 @@ pub struct B$0ar
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_hover_intra_link_reference_to_trait_method() {
|
||||
check(
|
||||
r#"
|
||||
pub trait Foo {
|
||||
fn buzz() -> usize;
|
||||
}
|
||||
/// [Foo][buzz]
|
||||
///
|
||||
/// [buzz]: Foo::buzz
|
||||
pub struct B$0ar
|
||||
"#,
|
||||
expect![[r#"
|
||||
*Bar*
|
||||
|
||||
```rust
|
||||
test
|
||||
```
|
||||
|
||||
```rust
|
||||
pub struct Bar
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
[Foo](https://docs.rs/test/*/test/trait.Foo.html#tymethod.buzz)
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hover_external_url() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user