@@ -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`.
19011905fn 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