@@ -472,15 +472,27 @@ impl clean::GenericArgs {
472
472
}
473
473
}
474
474
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 > {
476
488
let cache = & cx. cache ( ) ;
477
489
let relative_to = & cx. current ;
478
490
fn to_module_fqp ( shortty : ItemType , fqp : & [ String ] ) -> & [ String ] {
479
491
if shortty == ItemType :: Module { & fqp[ ..] } else { & fqp[ ..fqp. len ( ) - 1 ] }
480
492
}
481
493
482
494
if !did. is_local ( ) && !cache. access_levels . is_public ( did) && !cache. document_private {
483
- return None ;
495
+ return Err ( HrefError :: Private ) ;
484
496
}
485
497
486
498
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
489
501
href_relative_parts ( module_fqp, relative_to)
490
502
} ) ,
491
503
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
+ }
508
523
}
509
524
} ;
510
525
let last = & fqp. last ( ) . unwrap ( ) [ ..] ;
@@ -518,7 +533,7 @@ crate fn href(did: DefId, cx: &Context<'_>) -> Option<(String, ItemType, Vec<Str
518
533
url_parts. push ( & filename) ;
519
534
}
520
535
}
521
- Some ( ( url_parts. join ( "/" ) , shortty, fqp. to_vec ( ) ) )
536
+ Ok ( ( url_parts. join ( "/" ) , shortty, fqp. to_vec ( ) ) )
522
537
}
523
538
524
539
/// Both paths should only be modules.
@@ -567,7 +582,7 @@ fn resolved_path<'a, 'cx: 'a>(
567
582
write ! ( w, "{}{:#}" , & last. name, last. args. print( cx) ) ?;
568
583
} else {
569
584
let path = if use_absolute {
570
- if let Some ( ( _, _, fqp) ) = href ( did, cx) {
585
+ if let Ok ( ( _, _, fqp) ) = href ( did, cx) {
571
586
format ! (
572
587
"{}::{}" ,
573
588
fqp[ ..fqp. len( ) - 1 ] . join( "::" ) ,
@@ -675,7 +690,7 @@ crate fn anchor<'a, 'cx: 'a>(
675
690
) -> impl fmt:: Display + ' a {
676
691
let parts = href ( did. into ( ) , cx) ;
677
692
display_fn ( move |f| {
678
- if let Some ( ( url, short_ty, fqp) ) = parts {
693
+ if let Ok ( ( url, short_ty, fqp) ) = parts {
679
694
write ! (
680
695
f,
681
696
r#"<a class="{}" href="{}" title="{} {}">{}</a>"# ,
@@ -907,7 +922,7 @@ fn fmt_type<'cx>(
907
922
// look at).
908
923
box clean:: ResolvedPath { did, .. } => {
909
924
match href ( did. into ( ) , cx) {
910
- Some ( ( ref url, _, ref path) ) if !f. alternate ( ) => {
925
+ Ok ( ( ref url, _, ref path) ) if !f. alternate ( ) => {
911
926
write ! (
912
927
f,
913
928
"<a class=\" type\" href=\" {url}#{shortty}.{name}\" \
0 commit comments