Skip to content

Commit e193950

Browse files
Special case ambiguity_error if all candidates have the same "kind"
1 parent e981738 commit e193950

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1016,7 +1016,7 @@ impl LinkCollector<'_, '_> {
10161016
} else {
10171017
// `[char]` when a `char` module is in scope
10181018
let candidates = vec![(res, res.def_id(self.cx.tcx)), (prim, None)];
1019-
ambiguity_error(self.cx, diag_info, path_str, candidates);
1019+
ambiguity_error(self.cx, &diag_info, path_str, &candidates);
10201020
return None;
10211021
}
10221022
}
@@ -1206,6 +1206,10 @@ impl LinkCollector<'_, '_> {
12061206
}
12071207
}
12081208

1209+
if candidates.len() > 1 && !ambiguity_error(self.cx, &diag, &key.path_str, &candidates) {
1210+
candidates = vec![candidates[0]];
1211+
}
1212+
12091213
if let &[(res, def_id)] = candidates.as_slice() {
12101214
let fragment = match (&key.extra_fragment, def_id) {
12111215
(Some(_), Some(def_id)) => {
@@ -1221,9 +1225,6 @@ impl LinkCollector<'_, '_> {
12211225
return r;
12221226
}
12231227

1224-
if !candidates.is_empty() {
1225-
ambiguity_error(self.cx, diag, &key.path_str, candidates);
1226-
}
12271228
if cache_errors {
12281229
self.visited_links.insert(key, None);
12291230
}
@@ -1898,21 +1899,30 @@ fn report_malformed_generics(
18981899
}
18991900

19001901
/// Report an ambiguity error, where there were multiple possible resolutions.
1902+
///
1903+
/// If all `candidates` have the same kind, it's not possible to disambiguate so in this case,
1904+
/// the function returns `false`. Otherwise, it'll emit the error and return `true`.
19011905
fn ambiguity_error(
19021906
cx: &DocContext<'_>,
1903-
diag_info: DiagnosticInfo<'_>,
1907+
diag_info: &DiagnosticInfo<'_>,
19041908
path_str: &str,
1905-
candidates: Vec<(Res, Option<DefId>)>,
1906-
) {
1909+
candidates: &[(Res, Option<DefId>)],
1910+
) -> bool {
19071911
let mut msg = format!("`{}` is ", path_str);
19081912
let kinds = candidates
1909-
.into_iter()
1913+
.iter()
19101914
.map(
19111915
|(res, def_id)| {
1912-
if let Some(def_id) = def_id { Res::from_def_id(cx.tcx, def_id) } else { res }
1916+
if let Some(def_id) = def_id { Res::from_def_id(cx.tcx, *def_id) } else { *res }
19131917
},
19141918
)
19151919
.collect::<Vec<_>>();
1920+
let descrs = kinds.iter().map(|res| res.descr()).collect::<FxHashSet<&'static str>>();
1921+
if descrs.len() == 1 {
1922+
// There is no way for users to disambiguate at this point, so better return the first
1923+
// candidate and not show a warning.
1924+
return false;
1925+
}
19161926

19171927
match kinds.as_slice() {
19181928
[res1, res2] => {
@@ -1936,7 +1946,7 @@ fn ambiguity_error(
19361946
}
19371947
}
19381948

1939-
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, &diag_info, |diag, sp| {
1949+
report_diagnostic(cx.tcx, BROKEN_INTRA_DOC_LINKS, &msg, diag_info, |diag, sp| {
19401950
if let Some(sp) = sp {
19411951
diag.span_label(sp, "ambiguous link");
19421952
} else {
@@ -1947,6 +1957,7 @@ fn ambiguity_error(
19471957
suggest_disambiguator(res, diag, path_str, diag_info.ori_link, sp);
19481958
}
19491959
});
1960+
true
19501961
}
19511962

19521963
/// In case of an ambiguity or mismatched disambiguator, suggest the correct

0 commit comments

Comments
 (0)