|
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