|
1 | 1 | use crate::clean::Attributes; |
2 | 2 | use crate::core::ResolverCaches; |
3 | 3 | 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}; |
5 | 5 |
|
6 | 6 | use rustc_ast::visit::{self, AssocCtxt, Visitor}; |
7 | 7 | use rustc_ast::{self as ast, ItemKind}; |
@@ -209,26 +209,50 @@ impl EarlyDocLinkResolver<'_, '_> { |
209 | 209 | self.resolve_doc_links(doc_attrs(attrs.iter()), module_id); |
210 | 210 | } |
211 | 211 |
|
| 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 | + |
212 | 221 | fn resolve_doc_links(&mut self, attrs: Attributes, module_id: DefId) { |
213 | 222 | let mut need_traits_in_scope = false; |
214 | 223 | for (doc_module, doc) in attrs.prepare_to_doc_link_resolution() { |
215 | 224 | 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)); |
220 | 228 | for PreprocessedMarkdownLink(pp_link, _) in links { |
221 | 229 | 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 | + } |
230 | 253 | } |
231 | 254 | } |
| 255 | + self.markdown_links = tmp_links; |
232 | 256 | } |
233 | 257 |
|
234 | 258 | if need_traits_in_scope { |
|
0 commit comments