about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume.gomez@huawei.com>2023-03-24 15:06:03 +0100
committerGuillaume Gomez <guillaume.gomez@huawei.com>2023-03-24 15:06:03 +0100
commit537fdbd75b13d278645fa223b0e4bee1c0e5dc19 (patch)
treef6a8b04027baa64378b364544522066727b1f402
parentec43cb3e9c208939e09b4208850aaa34bee0423c (diff)
downloadrust-537fdbd75b13d278645fa223b0e4bee1c0e5dc19.tar.gz
rust-537fdbd75b13d278645fa223b0e4bee1c0e5dc19.zip
Strenghten disambiguation in `ambiguity_error` and improve documentation
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 795116e2553..80895893ae8 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1015,8 +1015,8 @@ impl LinkCollector<'_, '_> {
                     res = prim;
                 } else {
                     // `[char]` when a `char` module is in scope
-                    let candidates = vec![(res, res.def_id(self.cx.tcx)), (prim, None)];
-                    ambiguity_error(self.cx, &diag_info, path_str, &candidates);
+                    let candidates = &[(res, res.def_id(self.cx.tcx)), (prim, None)];
+                    ambiguity_error(self.cx, &diag_info, path_str, candidates);
                     return None;
                 }
             }
@@ -1206,6 +1206,10 @@ impl LinkCollector<'_, '_> {
             }
         }
 
+        // If there are multiple items with the same "kind" (for example, both "associated types")
+        // and after removing duplicated kinds, only one remains, the `ambiguity_error` function
+        // won't emit an error. So at this point, we can just take the first candidate as it was
+        // the first retrieved and use it to generate the link.
         if candidates.len() > 1 && !ambiguity_error(self.cx, &diag, &key.path_str, &candidates) {
             candidates = vec![candidates[0]];
         }
@@ -1901,14 +1905,15 @@ fn report_malformed_generics(
 /// Report an ambiguity error, where there were multiple possible resolutions.
 ///
 /// If all `candidates` have the same kind, it's not possible to disambiguate so in this case,
-/// the function returns `false`. Otherwise, it'll emit the error and return `true`.
+/// the function won't emit an error and will return `false`. Otherwise, it'll emit the error and
+/// return `true`.
 fn ambiguity_error(
     cx: &DocContext<'_>,
     diag_info: &DiagnosticInfo<'_>,
     path_str: &str,
     candidates: &[(Res, Option<DefId>)],
 ) -> bool {
-    let mut msg = format!("`{}` is ", path_str);
+    let mut descrs = FxHashSet::default();
     let kinds = candidates
         .iter()
         .map(
@@ -1916,14 +1921,15 @@ fn ambiguity_error(
                 if let Some(def_id) = def_id { Res::from_def_id(cx.tcx, *def_id) } else { *res }
             },
         )
+        .filter(|res| descrs.insert(res.descr()))
         .collect::<Vec<_>>();
-    let descrs = kinds.iter().map(|res| res.descr()).collect::<FxHashSet<&'static str>>();
     if descrs.len() == 1 {
         // There is no way for users to disambiguate at this point, so better return the first
         // candidate and not show a warning.
         return false;
     }
 
+    let mut msg = format!("`{}` is ", path_str);
     match kinds.as_slice() {
         [res1, res2] => {
             msg += &format!(