@@ -307,8 +307,12 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
307307 fmt:: from_fn ( |w| {
308308 write ! ( w, "{}" , document( cx, item, None , HeadingOffset :: H2 ) ) ?;
309309
310- let mut not_stripped_items =
311- items. iter ( ) . filter ( |i| !i. is_stripped ( ) ) . enumerate ( ) . collect :: < Vec < _ > > ( ) ;
310+ let mut not_stripped_items: FxHashMap < ItemType , Vec < ( usize , & clean:: Item ) > > =
311+ FxHashMap :: default ( ) ;
312+
313+ for ( index, item) in items. iter ( ) . filter ( |i| !i. is_stripped ( ) ) . enumerate ( ) {
314+ not_stripped_items. entry ( item. type_ ( ) ) . or_default ( ) . push ( ( index, item) ) ;
315+ }
312316
313317 // the order of item types in the listing
314318 fn reorder ( ty : ItemType ) -> u8 {
@@ -331,11 +335,6 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
331335 }
332336
333337 fn cmp ( i1 : & clean:: Item , i2 : & clean:: Item , tcx : TyCtxt < ' _ > ) -> Ordering {
334- let rty1 = reorder ( i1. type_ ( ) ) ;
335- let rty2 = reorder ( i2. type_ ( ) ) ;
336- if rty1 != rty2 {
337- return rty1. cmp ( & rty2) ;
338- }
339338 let is_stable1 =
340339 i1. stability ( tcx) . as_ref ( ) . map ( |s| s. level . is_stable ( ) ) . unwrap_or ( true ) ;
341340 let is_stable2 =
@@ -356,8 +355,12 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
356355 let tcx = cx. tcx ( ) ;
357356
358357 match cx. shared . module_sorting {
359- ModuleSorting :: Alphabetical => {
360- not_stripped_items. sort_by ( |( _, i1) , ( _, i2) | cmp ( i1, i2, tcx) ) ;
358+ ModuleSorting :: Alphabetical =>
359+ {
360+ #[ allow( rustc:: potential_query_instability) ]
361+ for items in not_stripped_items. values_mut ( ) {
362+ items. sort_by ( |( _, i1) , ( _, i2) | cmp ( i1, i2, tcx) ) ;
363+ }
361364 }
362365 ModuleSorting :: DeclarationOrder => { }
363366 }
@@ -380,155 +383,154 @@ fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> i
380383 // can be identical even if the elements are different (mostly in imports).
381384 // So in case this is an import, we keep everything by adding a "unique id"
382385 // (which is the position in the vector).
383- not_stripped_items. dedup_by_key ( |( idx, i) | {
384- (
385- i. item_id ,
386- if i. name . is_some ( ) { Some ( full_path ( cx, i) ) } else { None } ,
387- i. type_ ( ) ,
388- if i. is_import ( ) { * idx } else { 0 } ,
389- )
390- } ) ;
386+ #[ allow( rustc:: potential_query_instability) ]
387+ for items in not_stripped_items. values_mut ( ) {
388+ items. dedup_by_key ( |( idx, i) | {
389+ (
390+ i. item_id ,
391+ if i. name . is_some ( ) { Some ( full_path ( cx, i) ) } else { None } ,
392+ i. type_ ( ) ,
393+ if i. is_import ( ) { * idx } else { 0 } ,
394+ )
395+ } ) ;
396+ }
391397
392398 debug ! ( "{not_stripped_items:?}" ) ;
393- let mut last_section = None ;
394399
395- for ( _, myitem) in & not_stripped_items {
396- let my_section = item_ty_to_section ( myitem. type_ ( ) ) ;
397- if Some ( my_section) != last_section {
398- if last_section. is_some ( ) {
399- w. write_str ( ITEM_TABLE_CLOSE ) ?;
400- }
401- last_section = Some ( my_section) ;
402- let section_id = my_section. id ( ) ;
403- let tag =
404- if section_id == "reexports" { REEXPORTS_TABLE_OPEN } else { ITEM_TABLE_OPEN } ;
405- write ! (
406- w,
407- "{}" ,
408- write_section_heading( my_section. name( ) , & cx. derive_id( section_id) , None , tag)
409- ) ?;
410- }
400+ #[ allow( rustc:: potential_query_instability) ]
401+ let mut types = not_stripped_items. keys ( ) . copied ( ) . collect :: < Vec < _ > > ( ) ;
402+ types. sort_unstable_by ( |a, b| reorder ( * a) . cmp ( & reorder ( * b) ) ) ;
411403
412- match myitem. kind {
413- clean:: ExternCrateItem { ref src } => {
414- use crate :: html:: format:: print_anchor;
415-
416- match * src {
417- Some ( src) => {
418- write ! (
419- w,
420- "<dt><code>{}extern crate {} as {};" ,
421- visibility_print_with_space( myitem, cx) ,
422- print_anchor( myitem. item_id. expect_def_id( ) , src, cx) ,
423- EscapeBodyTextWithWbr ( myitem. name. unwrap( ) . as_str( ) )
424- ) ?;
425- }
426- None => {
427- write ! (
428- w,
429- "<dt><code>{}extern crate {};" ,
430- visibility_print_with_space( myitem, cx) ,
431- print_anchor(
432- myitem. item_id. expect_def_id( ) ,
433- myitem. name. unwrap( ) ,
434- cx
435- )
436- ) ?;
437- }
438- }
439- w. write_str ( "</code></dt>" ) ?;
440- }
404+ for type_ in types {
405+ let my_section = item_ty_to_section ( type_) ;
406+ let tag = if my_section == super :: ItemSection :: Reexports {
407+ REEXPORTS_TABLE_OPEN
408+ } else {
409+ ITEM_TABLE_OPEN
410+ } ;
411+ write ! (
412+ w,
413+ "{}" ,
414+ write_section_heading( my_section. name( ) , & cx. derive_id( my_section. id( ) ) , None , tag)
415+ ) ?;
441416
442- clean :: ImportItem ( ref import ) => {
443- let stab_tags = import . source . did . map_or_else ( String :: new , |import_def_id| {
444- print_extra_info_tags ( tcx , myitem , item , Some ( import_def_id ) ) . to_string ( )
445- } ) ;
417+ for ( _ , myitem ) in & not_stripped_items [ & type_ ] {
418+ match myitem . kind {
419+ clean :: ExternCrateItem { ref src } => {
420+ use crate :: html :: format :: print_anchor ;
446421
447- let id = match import. kind {
448- clean:: ImportKind :: Simple ( s) => {
449- format ! ( " id=\" {}\" " , cx. derive_id( format!( "reexport.{s}" ) ) )
422+ match * src {
423+ Some ( src) => {
424+ write ! (
425+ w,
426+ "<dt><code>{}extern crate {} as {};" ,
427+ visibility_print_with_space( myitem, cx) ,
428+ print_anchor( myitem. item_id. expect_def_id( ) , src, cx) ,
429+ EscapeBodyTextWithWbr ( myitem. name. unwrap( ) . as_str( ) )
430+ ) ?;
431+ }
432+ None => {
433+ write ! (
434+ w,
435+ "<dt><code>{}extern crate {};" ,
436+ visibility_print_with_space( myitem, cx) ,
437+ print_anchor(
438+ myitem. item_id. expect_def_id( ) ,
439+ myitem. name. unwrap( ) ,
440+ cx
441+ )
442+ ) ?;
443+ }
450444 }
451- clean:: ImportKind :: Glob => String :: new ( ) ,
452- } ;
453- write ! (
454- w,
455- "<dt{id}>\
456- <code>"
457- ) ?;
458- render_attributes_in_code ( w, myitem, "" , cx) ;
459- write ! (
460- w,
461- "{vis}{imp}</code>{stab_tags}\
462- </dt>",
463- vis = visibility_print_with_space( myitem, cx) ,
464- imp = import. print( cx)
465- ) ?;
466- }
467-
468- _ => {
469- if myitem. name . is_none ( ) {
470- continue ;
471445 }
472-
473- let unsafety_flag = match myitem. kind {
474- clean:: FunctionItem ( _) | clean:: ForeignFunctionItem ( ..)
475- if myitem. fn_header ( tcx) . unwrap ( ) . safety
476- == hir:: HeaderSafety :: Normal ( hir:: Safety :: Unsafe ) =>
477- {
478- "<sup title=\" unsafe function\" >⚠</sup>"
479- }
480- clean:: ForeignStaticItem ( _, hir:: Safety :: Unsafe ) => {
481- "<sup title=\" unsafe static\" >⚠</sup>"
482- }
483- _ => "" ,
484- } ;
485-
486- let visibility_and_hidden = match myitem. visibility ( tcx) {
487- Some ( ty:: Visibility :: Restricted ( _) ) => {
488- if myitem. is_doc_hidden ( ) {
489- // Don't separate with a space when there are two of them
490- "<span title=\" Restricted Visibility\" > 🔒</span><span title=\" Hidden item\" >👻</span> "
491- } else {
492- "<span title=\" Restricted Visibility\" > 🔒</span> "
446+ clean:: ImportItem ( ref import) => {
447+ let stab_tags =
448+ import. source . did . map_or_else ( String :: new, |import_def_id| {
449+ print_extra_info_tags ( tcx, myitem, item, Some ( import_def_id) )
450+ . to_string ( )
451+ } ) ;
452+ let id = match import. kind {
453+ clean:: ImportKind :: Simple ( s) => {
454+ format ! ( " id=\" {}\" " , cx. derive_id( format!( "reexport.{s}" ) ) )
493455 }
456+ clean:: ImportKind :: Glob => String :: new ( ) ,
457+ } ;
458+ write ! (
459+ w,
460+ "<dt{id}>\
461+ <code>"
462+ ) ?;
463+ render_attributes_in_code ( w, myitem, "" , cx) ;
464+ write ! (
465+ w,
466+ "{vis}{imp}</code>{stab_tags}\
467+ </dt>",
468+ vis = visibility_print_with_space( myitem, cx) ,
469+ imp = import. print( cx)
470+ ) ?;
471+ }
472+ _ => {
473+ if myitem. name . is_none ( ) {
474+ continue ;
494475 }
495- _ if myitem. is_doc_hidden ( ) => {
496- "<span title=\" Hidden item\" > 👻</span> "
497- }
498- _ => "" ,
499- } ;
500476
501- let docs =
502- MarkdownSummaryLine ( & myitem. doc_value ( ) , & myitem. links ( cx) ) . into_string ( ) ;
503- let ( docs_before, docs_after) =
504- if docs. is_empty ( ) { ( "" , "" ) } else { ( "<dd>" , "</dd>" ) } ;
505- write ! (
506- w,
507- "<dt>\
508- <a class=\" {class}\" href=\" {href}\" title=\" {title1} {title2}\" >\
509- {name}\
510- </a>\
511- {visibility_and_hidden}\
512- {unsafety_flag}\
513- {stab_tags}\
514- </dt>\
515- {docs_before}{docs}{docs_after}",
516- name = EscapeBodyTextWithWbr ( myitem. name. unwrap( ) . as_str( ) ) ,
517- visibility_and_hidden = visibility_and_hidden,
518- stab_tags = print_extra_info_tags( tcx, myitem, item, None ) ,
519- class = myitem. type_( ) ,
520- unsafety_flag = unsafety_flag,
521- href = print_item_path( myitem. type_( ) , myitem. name. unwrap( ) . as_str( ) ) ,
522- title1 = myitem. type_( ) ,
523- title2 = full_path( cx, myitem) ,
524- ) ?;
477+ let unsafety_flag = match myitem. kind {
478+ clean:: FunctionItem ( _) | clean:: ForeignFunctionItem ( ..)
479+ if myitem. fn_header ( tcx) . unwrap ( ) . safety
480+ == hir:: HeaderSafety :: Normal ( hir:: Safety :: Unsafe ) =>
481+ {
482+ "<sup title=\" unsafe function\" >⚠</sup>"
483+ }
484+ clean:: ForeignStaticItem ( _, hir:: Safety :: Unsafe ) => {
485+ "<sup title=\" unsafe static\" >⚠</sup>"
486+ }
487+ _ => "" ,
488+ } ;
489+ let visibility_and_hidden = match myitem. visibility ( tcx) {
490+ Some ( ty:: Visibility :: Restricted ( _) ) => {
491+ if myitem. is_doc_hidden ( ) {
492+ // Don't separate with a space when there are two of them
493+ "<span title=\" Restricted Visibility\" > 🔒</span><span title=\" Hidden item\" >👻</span> "
494+ } else {
495+ "<span title=\" Restricted Visibility\" > 🔒</span> "
496+ }
497+ }
498+ _ if myitem. is_doc_hidden ( ) => {
499+ "<span title=\" Hidden item\" > 👻</span> "
500+ }
501+ _ => "" ,
502+ } ;
503+
504+ let docs = MarkdownSummaryLine ( & myitem. doc_value ( ) , & myitem. links ( cx) )
505+ . into_string ( ) ;
506+ let ( docs_before, docs_after) =
507+ if docs. is_empty ( ) { ( "" , "" ) } else { ( "<dd>" , "</dd>" ) } ;
508+ write ! (
509+ w,
510+ "<dt>\
511+ <a class=\" {class}\" href=\" {href}\" title=\" {title1} {title2}\" >\
512+ {name}\
513+ </a>\
514+ {visibility_and_hidden}\
515+ {unsafety_flag}\
516+ {stab_tags}\
517+ </dt>\
518+ {docs_before}{docs}{docs_after}",
519+ name = EscapeBodyTextWithWbr ( myitem. name. unwrap( ) . as_str( ) ) ,
520+ visibility_and_hidden = visibility_and_hidden,
521+ stab_tags = print_extra_info_tags( tcx, myitem, item, None ) ,
522+ class = type_,
523+ unsafety_flag = unsafety_flag,
524+ href = print_item_path( type_, myitem. name. unwrap( ) . as_str( ) ) ,
525+ title1 = myitem. type_( ) ,
526+ title2 = full_path( cx, myitem) ,
527+ ) ?;
528+ }
525529 }
526530 }
527- }
528-
529- if last_section. is_some ( ) {
530531 w. write_str ( ITEM_TABLE_CLOSE ) ?;
531532 }
533+
532534 Ok ( ( ) )
533535 } )
534536}
0 commit comments