@@ -472,15 +472,27 @@ impl clean::GenericArgs {
472472 }
473473}
474474
475- crate fn href ( did : DefId , cx : & Context < ' _ > ) -> Option < ( String , ItemType , Vec < String > ) > {
475+ // Possible errors when computing href link source for a `DefId`
476+ crate enum HrefError {
477+ /// This item is known to rustdoc, but from a crate that does not have documentation generated.
478+ ///
479+ /// This can only happen for non-local items.
480+ DocumentationNotBuilt ,
481+ /// This can only happen for non-local items when `--document-private-items` is not passed.
482+ Private ,
483+ // Not in external cache, href link should be in same page
484+ NotInExternalCache ,
485+ }
486+
487+ crate fn href ( did : DefId , cx : & Context < ' _ > ) -> Result < ( String , ItemType , Vec < String > ) , HrefError > {
476488 let cache = & cx. cache ( ) ;
477489 let relative_to = & cx. current ;
478490 fn to_module_fqp ( shortty : ItemType , fqp : & [ String ] ) -> & [ String ] {
479491 if shortty == ItemType :: Module { & fqp[ ..] } else { & fqp[ ..fqp. len ( ) - 1 ] }
480492 }
481493
482494 if !did. is_local ( ) && !cache. access_levels . is_public ( did) && !cache. document_private {
483- return None ;
495+ return Err ( HrefError :: Private ) ;
484496 }
485497
486498 let ( fqp, shortty, mut url_parts) = match cache. paths . get ( & did) {
@@ -489,22 +501,25 @@ crate fn href(did: DefId, cx: &Context<'_>) -> Option<(String, ItemType, Vec<Str
489501 href_relative_parts ( module_fqp, relative_to)
490502 } ) ,
491503 None => {
492- let & ( ref fqp, shortty) = cache. external_paths . get ( & did) ?;
493- let module_fqp = to_module_fqp ( shortty, fqp) ;
494- (
495- fqp,
496- shortty,
497- match cache. extern_locations [ & did. krate ] {
498- ExternalLocation :: Remote ( ref s) => {
499- let s = s. trim_end_matches ( '/' ) ;
500- let mut s = vec ! [ & s[ ..] ] ;
501- s. extend ( module_fqp[ ..] . iter ( ) . map ( String :: as_str) ) ;
502- s
503- }
504- ExternalLocation :: Local => href_relative_parts ( module_fqp, relative_to) ,
505- ExternalLocation :: Unknown => return None ,
506- } ,
507- )
504+ if let Some ( & ( ref fqp, shortty) ) = cache. external_paths . get ( & did) {
505+ let module_fqp = to_module_fqp ( shortty, fqp) ;
506+ (
507+ fqp,
508+ shortty,
509+ match cache. extern_locations [ & did. krate ] {
510+ ExternalLocation :: Remote ( ref s) => {
511+ let s = s. trim_end_matches ( '/' ) ;
512+ let mut s = vec ! [ & s[ ..] ] ;
513+ s. extend ( module_fqp[ ..] . iter ( ) . map ( String :: as_str) ) ;
514+ s
515+ }
516+ ExternalLocation :: Local => href_relative_parts ( module_fqp, relative_to) ,
517+ ExternalLocation :: Unknown => return Err ( HrefError :: DocumentationNotBuilt ) ,
518+ } ,
519+ )
520+ } else {
521+ return Err ( HrefError :: NotInExternalCache ) ;
522+ }
508523 }
509524 } ;
510525 let last = & fqp. last ( ) . unwrap ( ) [ ..] ;
@@ -518,7 +533,7 @@ crate fn href(did: DefId, cx: &Context<'_>) -> Option<(String, ItemType, Vec<Str
518533 url_parts. push ( & filename) ;
519534 }
520535 }
521- Some ( ( url_parts. join ( "/" ) , shortty, fqp. to_vec ( ) ) )
536+ Ok ( ( url_parts. join ( "/" ) , shortty, fqp. to_vec ( ) ) )
522537}
523538
524539/// Both paths should only be modules.
@@ -567,7 +582,7 @@ fn resolved_path<'a, 'cx: 'a>(
567582 write ! ( w, "{}{:#}" , & last. name, last. args. print( cx) ) ?;
568583 } else {
569584 let path = if use_absolute {
570- if let Some ( ( _, _, fqp) ) = href ( did, cx) {
585+ if let Ok ( ( _, _, fqp) ) = href ( did, cx) {
571586 format ! (
572587 "{}::{}" ,
573588 fqp[ ..fqp. len( ) - 1 ] . join( "::" ) ,
@@ -675,7 +690,7 @@ crate fn anchor<'a, 'cx: 'a>(
675690) -> impl fmt:: Display + ' a {
676691 let parts = href ( did. into ( ) , cx) ;
677692 display_fn ( move |f| {
678- if let Some ( ( url, short_ty, fqp) ) = parts {
693+ if let Ok ( ( url, short_ty, fqp) ) = parts {
679694 write ! (
680695 f,
681696 r#"<a class="{}" href="{}" title="{} {}">{}</a>"# ,
@@ -907,7 +922,7 @@ fn fmt_type<'cx>(
907922 // look at).
908923 box clean:: ResolvedPath { did, .. } => {
909924 match href ( did. into ( ) , cx) {
910- Some ( ( ref url, _, ref path) ) if !f. alternate ( ) => {
925+ Ok ( ( ref url, _, ref path) ) if !f. alternate ( ) => {
911926 write ! (
912927 f,
913928 "<a class=\" type\" href=\" {url}#{shortty}.{name}\" \
0 commit comments