Skip to content

Commit 921f63f

Browse files
committed
rustdoc: Early-resolve doc links in all requested namespaces
1 parent 579d268 commit 921f63f

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

src/librustdoc/passes/collect_intra_doc_links/early.rs

+37-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::clean::Attributes;
22
use crate::core::ResolverCaches;
33
use crate::passes::collect_intra_doc_links::preprocessed_markdown_links;
4-
use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink;
4+
use crate::passes::collect_intra_doc_links::{Disambiguator, PreprocessedMarkdownLink};
55

66
use rustc_ast::visit::{self, AssocCtxt, Visitor};
77
use rustc_ast::{self as ast, ItemKind};
@@ -209,26 +209,50 @@ impl EarlyDocLinkResolver<'_, '_> {
209209
self.resolve_doc_links(doc_attrs(attrs.iter()), module_id);
210210
}
211211

212+
fn resolve_and_cache(&mut self, path_str: &str, ns: Namespace, module_id: DefId) -> bool {
213+
self.doc_link_resolutions
214+
.entry((Symbol::intern(path_str), ns, module_id))
215+
.or_insert_with_key(|(path, ns, module_id)| {
216+
self.resolver.resolve_rustdoc_path(path.as_str(), *ns, *module_id)
217+
})
218+
.is_some()
219+
}
220+
212221
fn resolve_doc_links(&mut self, attrs: Attributes, module_id: DefId) {
213222
let mut need_traits_in_scope = false;
214223
for (doc_module, doc) in attrs.prepare_to_doc_link_resolution() {
215224
assert_eq!(doc_module, None);
216-
let links = self
217-
.markdown_links
218-
.entry(doc)
219-
.or_insert_with_key(|doc| preprocessed_markdown_links(doc));
225+
let mut tmp_links = mem::take(&mut self.markdown_links);
226+
let links =
227+
tmp_links.entry(doc).or_insert_with_key(|doc| preprocessed_markdown_links(doc));
220228
for PreprocessedMarkdownLink(pp_link, _) in links {
221229
if let Ok(pinfo) = pp_link {
222-
// FIXME: Resolve the path in all namespaces and resolve its prefixes too.
223-
let ns = TypeNS;
224-
self.doc_link_resolutions
225-
.entry((Symbol::intern(&pinfo.path_str), ns, module_id))
226-
.or_insert_with_key(|(path, ns, module_id)| {
227-
self.resolver.resolve_rustdoc_path(path.as_str(), *ns, *module_id)
228-
});
229-
need_traits_in_scope = true;
230+
// The logic here is a conservative approximation for path resolution in
231+
// `resolve_with_disambiguator`.
232+
if let Some(ns) = pinfo.disambiguator.map(Disambiguator::ns) {
233+
if self.resolve_and_cache(&pinfo.path_str, ns, module_id) {
234+
continue;
235+
}
236+
}
237+
238+
// Resolve all namespaces due to no disambiguator or for diagnostics.
239+
let mut any_resolved = false;
240+
let mut need_assoc = false;
241+
for ns in [TypeNS, ValueNS, MacroNS] {
242+
if self.resolve_and_cache(&pinfo.path_str, ns, module_id) {
243+
any_resolved = true;
244+
} else if ns != MacroNS {
245+
need_assoc = true;
246+
}
247+
}
248+
249+
// FIXME: Resolve all prefixes for type-relative resolution or for diagnostics.
250+
if (need_assoc || !any_resolved) && pinfo.path_str.contains("::") {
251+
need_traits_in_scope = true;
252+
}
230253
}
231254
}
255+
self.markdown_links = tmp_links;
232256
}
233257

234258
if need_traits_in_scope {

0 commit comments

Comments
 (0)