7
7
//! some of them support an alternate format that emits text, but that should
8
8
//! not be used external to this module.
9
9
10
- use std:: borrow:: Cow ;
11
10
use std:: cmp:: Ordering ;
12
11
use std:: fmt:: { self , Display , Write } ;
13
12
use std:: iter:: { self , once} ;
14
13
use std:: slice;
15
14
16
- use itertools:: Either ;
15
+ use itertools:: { Either , Itertools } ;
17
16
use rustc_abi:: ExternAbi ;
18
17
use rustc_attr_data_structures:: { ConstStability , StabilityLevel , StableSince } ;
19
18
use rustc_data_structures:: fx:: FxHashSet ;
@@ -483,12 +482,12 @@ fn generate_item_def_id_path(
483
482
let mut is_remote = false ;
484
483
485
484
let url_parts = url_parts ( cx. cache ( ) , def_id, module_fqp, & cx. current , & mut is_remote) ?;
486
- let ( url_parts, shortty , fqp ) = make_href ( root_path, shortty, url_parts, & fqp, is_remote) ? ;
487
- if def_id = = original_def_id {
488
- return Ok ( ( url_parts , shortty , fqp ) ) ;
489
- }
490
- let kind = ItemType :: from_def_kind ( original_def_kind , Some ( def_kind ) ) ;
491
- Ok ( ( format ! ( "{ url_parts}#{kind}.{}" , tcx . item_name ( original_def_id ) ) , shortty, fqp) )
485
+ let mut url_parts = make_href ( root_path, shortty, url_parts, & fqp, is_remote) ;
486
+ if def_id ! = original_def_id {
487
+ let kind = ItemType :: from_def_kind ( original_def_kind , Some ( def_kind ) ) ;
488
+ url_parts = format ! ( "{url_parts}#{kind}.{}" , tcx . item_name ( original_def_id ) )
489
+ } ;
490
+ Ok ( ( url_parts, shortty, fqp) )
492
491
}
493
492
494
493
fn to_module_fqp ( shortty : ItemType , fqp : & [ Symbol ] ) -> & [ Symbol ] {
@@ -510,7 +509,7 @@ fn url_parts(
510
509
builder. extend ( module_fqp. iter ( ) . copied ( ) ) ;
511
510
Ok ( builder)
512
511
}
513
- ExternalLocation :: Local => Ok ( href_relative_parts ( module_fqp, relative_to) . collect ( ) ) ,
512
+ ExternalLocation :: Local => Ok ( href_relative_parts ( module_fqp, relative_to) ) ,
514
513
ExternalLocation :: Unknown => Err ( HrefError :: DocumentationNotBuilt ) ,
515
514
}
516
515
}
@@ -521,7 +520,7 @@ fn make_href(
521
520
mut url_parts : UrlPartsBuilder ,
522
521
fqp : & [ Symbol ] ,
523
522
is_remote : bool ,
524
- ) -> Result < ( String , ItemType , Vec < Symbol > ) , HrefError > {
523
+ ) -> String {
525
524
if !is_remote && let Some ( root_path) = root_path {
526
525
let root = root_path. trim_end_matches ( '/' ) ;
527
526
url_parts. push_front ( root) ;
@@ -536,7 +535,7 @@ fn make_href(
536
535
url_parts. push_fmt ( format_args ! ( "{shortty}.{last}.html" ) ) ;
537
536
}
538
537
}
539
- Ok ( ( url_parts. finish ( ) , shortty , fqp . to_vec ( ) ) )
538
+ url_parts. finish ( )
540
539
}
541
540
542
541
pub ( crate ) fn href_with_root_path (
@@ -587,7 +586,7 @@ pub(crate) fn href_with_root_path(
587
586
Some ( & ( ref fqp, shortty) ) => ( fqp, shortty, {
588
587
let module_fqp = to_module_fqp ( shortty, fqp. as_slice ( ) ) ;
589
588
debug ! ( ?fqp, ?shortty, ?module_fqp) ;
590
- href_relative_parts ( module_fqp, relative_to) . collect ( )
589
+ href_relative_parts ( module_fqp, relative_to)
591
590
} ) ,
592
591
None => {
593
592
// Associated items are handled differently with "jump to def". The anchor is generated
@@ -606,7 +605,8 @@ pub(crate) fn href_with_root_path(
606
605
}
607
606
}
608
607
} ;
609
- make_href ( root_path, shortty, url_parts, fqp, is_remote)
608
+ let url_parts = make_href ( root_path, shortty, url_parts, & fqp, is_remote) ;
609
+ Ok ( ( url_parts, shortty, fqp. clone ( ) ) )
610
610
}
611
611
612
612
pub ( crate ) fn href (
@@ -619,34 +619,30 @@ pub(crate) fn href(
619
619
/// Both paths should only be modules.
620
620
/// This is because modules get their own directories; that is, `std::vec` and `std::vec::Vec` will
621
621
/// both need `../iter/trait.Iterator.html` to get at the iterator trait.
622
- pub ( crate ) fn href_relative_parts < ' fqp > (
623
- fqp : & ' fqp [ Symbol ] ,
624
- relative_to_fqp : & [ Symbol ] ,
625
- ) -> Box < dyn Iterator < Item = Symbol > + ' fqp > {
622
+ pub ( crate ) fn href_relative_parts ( fqp : & [ Symbol ] , relative_to_fqp : & [ Symbol ] ) -> UrlPartsBuilder {
626
623
for ( i, ( f, r) ) in fqp. iter ( ) . zip ( relative_to_fqp. iter ( ) ) . enumerate ( ) {
627
624
// e.g. linking to std::iter from std::vec (`dissimilar_part_count` will be 1)
628
625
if f != r {
629
626
let dissimilar_part_count = relative_to_fqp. len ( ) - i;
630
627
let fqp_module = & fqp[ i..] ;
631
- return Box :: new (
632
- iter:: repeat_n ( sym:: dotdot, dissimilar_part_count)
633
- . chain ( fqp_module. iter ( ) . copied ( ) ) ,
634
- ) ;
628
+ return iter:: repeat_n ( sym:: dotdot, dissimilar_part_count)
629
+ . chain ( fqp_module. iter ( ) . copied ( ) )
630
+ . collect ( ) ;
635
631
}
636
632
}
637
633
match relative_to_fqp. len ( ) . cmp ( & fqp. len ( ) ) {
638
634
Ordering :: Less => {
639
635
// e.g. linking to std::sync::atomic from std::sync
640
- Box :: new ( fqp[ relative_to_fqp. len ( ) ..fqp. len ( ) ] . iter ( ) . copied ( ) )
636
+ fqp[ relative_to_fqp. len ( ) ..fqp. len ( ) ] . iter ( ) . copied ( ) . collect ( )
641
637
}
642
638
Ordering :: Greater => {
643
639
// e.g. linking to std::sync from std::sync::atomic
644
640
let dissimilar_part_count = relative_to_fqp. len ( ) - fqp. len ( ) ;
645
- Box :: new ( iter:: repeat_n ( sym:: dotdot, dissimilar_part_count) )
641
+ iter:: repeat_n ( sym:: dotdot, dissimilar_part_count) . collect ( )
646
642
}
647
643
Ordering :: Equal => {
648
644
// linking to the same module
649
- Box :: new ( iter :: empty ( ) )
645
+ UrlPartsBuilder :: new ( )
650
646
}
651
647
}
652
648
}
@@ -708,13 +704,13 @@ fn resolved_path(
708
704
f,
709
705
"{path}::{anchor}" ,
710
706
path = join_with_double_colon( & fqp[ ..fqp. len( ) - 1 ] ) ,
711
- anchor = anchor ( did, * fqp. last( ) . unwrap( ) , cx)
707
+ anchor = print_anchor ( did, * fqp. last( ) . unwrap( ) , cx)
712
708
)
713
709
} else {
714
710
write ! ( f, "{}" , last. name)
715
711
}
716
712
} else {
717
- write ! ( f, "{}" , anchor ( did, last. name, cx) )
713
+ write ! ( f, "{}" , print_anchor ( did, last. name, cx) )
718
714
}
719
715
} ) ;
720
716
write ! ( w, "{path}{args}" , args = last. args. print( cx) ) ?;
@@ -800,7 +796,7 @@ fn primitive_link_fragment(
800
796
Ok ( ( ) )
801
797
}
802
798
803
- fn tybounds (
799
+ fn print_tybounds (
804
800
bounds : & [ clean:: PolyTrait ] ,
805
801
lt : & Option < clean:: Lifetime > ,
806
802
cx : & Context < ' _ > ,
@@ -832,7 +828,7 @@ fn print_higher_ranked_params_with_space(
832
828
} )
833
829
}
834
830
835
- pub ( crate ) fn anchor ( did : DefId , text : Symbol , cx : & Context < ' _ > ) -> impl Display {
831
+ pub ( crate ) fn print_anchor ( did : DefId , text : Symbol , cx : & Context < ' _ > ) -> impl Display {
836
832
fmt:: from_fn ( move |f| {
837
833
let parts = href ( did, cx) ;
838
834
if let Ok ( ( url, short_ty, fqp) ) = parts {
@@ -866,7 +862,7 @@ fn fmt_type(
866
862
}
867
863
clean:: DynTrait ( bounds, lt) => {
868
864
f. write_str ( "dyn " ) ?;
869
- tybounds ( bounds, lt, cx) . fmt ( f)
865
+ print_tybounds ( bounds, lt, cx) . fmt ( f)
870
866
}
871
867
clean:: Infer => write ! ( f, "_" ) ,
872
868
clean:: Primitive ( clean:: PrimitiveType :: Never ) => {
@@ -1122,16 +1118,16 @@ impl clean::Impl {
1122
1118
write ! ( f, "!" ) ?;
1123
1119
}
1124
1120
if self . kind . is_fake_variadic ( )
1125
- && let generics = ty. generics ( )
1126
- && let & [ inner_type] = generics. as_ref ( ) . map_or ( & [ ] [ .. ] , |v| & v [ .. ] )
1121
+ && let Some ( generics) = ty. generics ( )
1122
+ && let Ok ( inner_type) = generics. exactly_one ( )
1127
1123
{
1128
1124
let last = ty. last ( ) ;
1129
1125
if f. alternate ( ) {
1130
1126
write ! ( f, "{}<" , last) ?;
1131
1127
self . print_type ( inner_type, f, use_absolute, cx) ?;
1132
1128
write ! ( f, ">" ) ?;
1133
1129
} else {
1134
- write ! ( f, "{}<" , anchor ( ty. def_id( ) , last, cx) ) ?;
1130
+ write ! ( f, "{}<" , print_anchor ( ty. def_id( ) , last, cx) ) ?;
1135
1131
self . print_type ( inner_type, f, use_absolute, cx) ?;
1136
1132
write ! ( f, ">" ) ?;
1137
1133
}
@@ -1202,11 +1198,10 @@ impl clean::Impl {
1202
1198
}
1203
1199
} else if let clean:: Type :: Path { path } = type_
1204
1200
&& let Some ( generics) = path. generics ( )
1205
- && generics . len ( ) == 1
1201
+ && let Ok ( ty ) = generics . exactly_one ( )
1206
1202
&& self . kind . is_fake_variadic ( )
1207
1203
{
1208
- let ty = generics[ 0 ] ;
1209
- let wrapper = anchor ( path. def_id ( ) , path. last ( ) , cx) ;
1204
+ let wrapper = print_anchor ( path. def_id ( ) , path. last ( ) , cx) ;
1210
1205
if f. alternate ( ) {
1211
1206
write ! ( f, "{wrapper:#}<" ) ?;
1212
1207
} else {
@@ -1394,50 +1389,47 @@ impl clean::FnDecl {
1394
1389
}
1395
1390
1396
1391
pub ( crate ) fn visibility_print_with_space ( item : & clean:: Item , cx : & Context < ' _ > ) -> impl Display {
1397
- use std:: fmt:: Write as _;
1398
- let vis: Cow < ' static , str > = match item. visibility ( cx. tcx ( ) ) {
1399
- None => "" . into ( ) ,
1400
- Some ( ty:: Visibility :: Public ) => "pub " . into ( ) ,
1401
- Some ( ty:: Visibility :: Restricted ( vis_did) ) => {
1402
- // FIXME(camelid): This may not work correctly if `item_did` is a module.
1403
- // However, rustdoc currently never displays a module's
1404
- // visibility, so it shouldn't matter.
1405
- let parent_module = find_nearest_parent_module ( cx. tcx ( ) , item. item_id . expect_def_id ( ) ) ;
1406
-
1407
- if vis_did. is_crate_root ( ) {
1408
- "pub(crate) " . into ( )
1409
- } else if parent_module == Some ( vis_did) {
1410
- // `pub(in foo)` where `foo` is the parent module
1411
- // is the same as no visibility modifier
1412
- "" . into ( )
1413
- } else if parent_module. and_then ( |parent| find_nearest_parent_module ( cx. tcx ( ) , parent) )
1414
- == Some ( vis_did)
1415
- {
1416
- "pub(super) " . into ( )
1417
- } else {
1418
- let path = cx. tcx ( ) . def_path ( vis_did) ;
1419
- debug ! ( "path={path:?}" ) ;
1420
- // modified from `resolved_path()` to work with `DefPathData`
1421
- let last_name = path. data . last ( ) . unwrap ( ) . data . get_opt_name ( ) . unwrap ( ) ;
1422
- let anchor = anchor ( vis_did, last_name, cx) ;
1423
-
1424
- let mut s = "pub(in " . to_owned ( ) ;
1425
- for seg in & path. data [ ..path. data . len ( ) - 1 ] {
1426
- let _ = write ! ( s, "{}::" , seg. data. get_opt_name( ) . unwrap( ) ) ;
1427
- }
1428
- let _ = write ! ( s, "{anchor}) " ) ;
1429
- s. into ( )
1430
- }
1431
- }
1432
- } ;
1433
-
1434
- let is_doc_hidden = item. is_doc_hidden ( ) ;
1435
1392
fmt:: from_fn ( move |f| {
1436
- if is_doc_hidden {
1393
+ if item . is_doc_hidden ( ) {
1437
1394
f. write_str ( "#[doc(hidden)] " ) ?;
1438
1395
}
1439
1396
1440
- f. write_str ( & vis)
1397
+ match item. visibility ( cx. tcx ( ) ) {
1398
+ None => { }
1399
+ Some ( ty:: Visibility :: Public ) => f. write_str ( "pub " ) ?,
1400
+ Some ( ty:: Visibility :: Restricted ( vis_did) ) => {
1401
+ // FIXME(camelid): This may not work correctly if `item_did` is a module.
1402
+ // However, rustdoc currently never displays a module's
1403
+ // visibility, so it shouldn't matter.
1404
+ let parent_module =
1405
+ find_nearest_parent_module ( cx. tcx ( ) , item. item_id . expect_def_id ( ) ) ;
1406
+
1407
+ if vis_did. is_crate_root ( ) {
1408
+ f. write_str ( "pub(crate) " ) ?;
1409
+ } else if parent_module == Some ( vis_did) {
1410
+ // `pub(in foo)` where `foo` is the parent module
1411
+ // is the same as no visibility modifier; do nothing
1412
+ } else if parent_module
1413
+ . and_then ( |parent| find_nearest_parent_module ( cx. tcx ( ) , parent) )
1414
+ == Some ( vis_did)
1415
+ {
1416
+ f. write_str ( "pub(super) " ) ?;
1417
+ } else {
1418
+ let path = cx. tcx ( ) . def_path ( vis_did) ;
1419
+ debug ! ( "path={path:?}" ) ;
1420
+ // modified from `resolved_path()` to work with `DefPathData`
1421
+ let last_name = path. data . last ( ) . unwrap ( ) . data . get_opt_name ( ) . unwrap ( ) ;
1422
+ let anchor = print_anchor ( vis_did, last_name, cx) ;
1423
+
1424
+ f. write_str ( "pub(in " ) ?;
1425
+ for seg in & path. data [ ..path. data . len ( ) - 1 ] {
1426
+ write ! ( f, "{}::" , seg. data. get_opt_name( ) . unwrap( ) ) ?;
1427
+ }
1428
+ write ! ( f, "{anchor}) " ) ?;
1429
+ }
1430
+ }
1431
+ }
1432
+ Ok ( ( ) )
1441
1433
} )
1442
1434
}
1443
1435
0 commit comments