@@ -247,7 +247,9 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut String)
247247 item_vars. render_into ( buf) . unwrap ( ) ;
248248
249249 match & item. kind {
250- clean:: ModuleItem ( ref m) => item_module ( buf, cx, item, & m. items ) ,
250+ clean:: ModuleItem ( ref m) => {
251+ write_str ( buf, format_args ! ( "{}" , item_module( cx, item, & m. items) ) )
252+ }
251253 clean:: FunctionItem ( ref f) | clean:: ForeignFunctionItem ( ref f, _) => {
252254 item_function ( buf, cx, item, f)
253255 }
@@ -309,198 +311,198 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display {
309311 fn item_and_cx ( & self ) -> ( & ' a clean:: Item , & ' a Context < ' cx > ) ;
310312}
311313
312- fn item_module ( w : & mut String , cx : & Context < ' _ > , item : & clean:: Item , items : & [ clean:: Item ] ) {
313- write_str ( w, format_args ! ( "{}" , document( cx, item, None , HeadingOffset :: H2 ) ) ) ;
314-
315- let mut not_stripped_items =
316- items. iter ( ) . filter ( |i| !i. is_stripped ( ) ) . enumerate ( ) . collect :: < Vec < _ > > ( ) ;
317-
318- // the order of item types in the listing
319- fn reorder ( ty : ItemType ) -> u8 {
320- match ty {
321- ItemType :: ExternCrate => 0 ,
322- ItemType :: Import => 1 ,
323- ItemType :: Primitive => 2 ,
324- ItemType :: Module => 3 ,
325- ItemType :: Macro => 4 ,
326- ItemType :: Struct => 5 ,
327- ItemType :: Enum => 6 ,
328- ItemType :: Constant => 7 ,
329- ItemType :: Static => 8 ,
330- ItemType :: Trait => 9 ,
331- ItemType :: Function => 10 ,
332- ItemType :: TypeAlias => 12 ,
333- ItemType :: Union => 13 ,
334- _ => 14 + ty as u8 ,
314+ fn item_module < ' a , ' tcx > (
315+ cx : & ' a Context < ' tcx > ,
316+ item : & ' a clean:: Item ,
317+ items : & ' a [ clean:: Item ] ,
318+ ) -> impl fmt:: Display + ' a + Captures < ' tcx > {
319+ fmt:: from_fn ( |w| {
320+ write ! ( w, "{}" , document( cx, item, None , HeadingOffset :: H2 ) ) ?;
321+
322+ let mut not_stripped_items =
323+ items. iter ( ) . filter ( |i| !i. is_stripped ( ) ) . enumerate ( ) . collect :: < Vec < _ > > ( ) ;
324+
325+ // the order of item types in the listing
326+ fn reorder ( ty : ItemType ) -> u8 {
327+ match ty {
328+ ItemType :: ExternCrate => 0 ,
329+ ItemType :: Import => 1 ,
330+ ItemType :: Primitive => 2 ,
331+ ItemType :: Module => 3 ,
332+ ItemType :: Macro => 4 ,
333+ ItemType :: Struct => 5 ,
334+ ItemType :: Enum => 6 ,
335+ ItemType :: Constant => 7 ,
336+ ItemType :: Static => 8 ,
337+ ItemType :: Trait => 9 ,
338+ ItemType :: Function => 10 ,
339+ ItemType :: TypeAlias => 12 ,
340+ ItemType :: Union => 13 ,
341+ _ => 14 + ty as u8 ,
342+ }
335343 }
336- }
337344
338- fn cmp ( i1 : & clean:: Item , i2 : & clean:: Item , tcx : TyCtxt < ' _ > ) -> Ordering {
339- let rty1 = reorder ( i1. type_ ( ) ) ;
340- let rty2 = reorder ( i2. type_ ( ) ) ;
341- if rty1 != rty2 {
342- return rty1. cmp ( & rty2) ;
343- }
344- let is_stable1 = i1. stability ( tcx) . as_ref ( ) . map ( |s| s. level . is_stable ( ) ) . unwrap_or ( true ) ;
345- let is_stable2 = i2. stability ( tcx) . as_ref ( ) . map ( |s| s. level . is_stable ( ) ) . unwrap_or ( true ) ;
346- if is_stable1 != is_stable2 {
347- // true is bigger than false in the standard bool ordering,
348- // but we actually want stable items to come first
349- return is_stable2. cmp ( & is_stable1) ;
350- }
351- let lhs = i1. name . unwrap_or ( kw:: Empty ) ;
352- let rhs = i2. name . unwrap_or ( kw:: Empty ) ;
353- compare_names ( lhs. as_str ( ) , rhs. as_str ( ) )
354- }
355-
356- let tcx = cx. tcx ( ) ;
357-
358- match cx. shared . module_sorting {
359- ModuleSorting :: Alphabetical => {
360- not_stripped_items. sort_by ( |( _, i1) , ( _, i2) | cmp ( i1, i2, tcx) ) ;
345+ fn cmp ( i1 : & clean:: Item , i2 : & clean:: Item , tcx : TyCtxt < ' _ > ) -> Ordering {
346+ let rty1 = reorder ( i1. type_ ( ) ) ;
347+ let rty2 = reorder ( i2. type_ ( ) ) ;
348+ if rty1 != rty2 {
349+ return rty1. cmp ( & rty2) ;
350+ }
351+ let is_stable1 =
352+ i1. stability ( tcx) . as_ref ( ) . map ( |s| s. level . is_stable ( ) ) . unwrap_or ( true ) ;
353+ let is_stable2 =
354+ i2. stability ( tcx) . as_ref ( ) . map ( |s| s. level . is_stable ( ) ) . unwrap_or ( true ) ;
355+ if is_stable1 != is_stable2 {
356+ // true is bigger than false in the standard bool ordering,
357+ // but we actually want stable items to come first
358+ return is_stable2. cmp ( & is_stable1) ;
359+ }
360+ let lhs = i1. name . unwrap_or ( kw:: Empty ) ;
361+ let rhs = i2. name . unwrap_or ( kw:: Empty ) ;
362+ compare_names ( lhs. as_str ( ) , rhs. as_str ( ) )
361363 }
362- ModuleSorting :: DeclarationOrder => { }
363- }
364- // This call is to remove re-export duplicates in cases such as:
365- //
366- // ```
367- // pub(crate) mod foo {
368- // pub(crate) mod bar {
369- // pub(crate) trait Double { fn foo(); }
370- // }
371- // }
372- //
373- // pub(crate) use foo::bar::*;
374- // pub(crate) use foo::*;
375- // ```
376- //
377- // `Double` will appear twice in the generated docs.
378- //
379- // FIXME: This code is quite ugly and could be improved. Small issue: DefId
380- // can be identical even if the elements are different (mostly in imports).
381- // So in case this is an import, we keep everything by adding a "unique id"
382- // (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- } ) ;
391364
392- debug ! ( "{not_stripped_items:?}" ) ;
393- let mut last_section = None ;
365+ let tcx = cx. tcx ( ) ;
394366
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. push_str ( ITEM_TABLE_CLOSE ) ;
367+ match cx. shared . module_sorting {
368+ ModuleSorting :: Alphabetical => {
369+ not_stripped_items. sort_by ( |( _, i1) , ( _, i2) | cmp ( i1, i2, tcx) ) ;
400370 }
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_str (
406- w,
407- format_args ! (
371+ ModuleSorting :: DeclarationOrder => { }
372+ }
373+ // This call is to remove re-export duplicates in cases such as:
374+ //
375+ // ```
376+ // pub(crate) mod foo {
377+ // pub(crate) mod bar {
378+ // pub(crate) trait Double { fn foo(); }
379+ // }
380+ // }
381+ //
382+ // pub(crate) use foo::bar::*;
383+ // pub(crate) use foo::*;
384+ // ```
385+ //
386+ // `Double` will appear twice in the generated docs.
387+ //
388+ // FIXME: This code is quite ugly and could be improved. Small issue: DefId
389+ // can be identical even if the elements are different (mostly in imports).
390+ // So in case this is an import, we keep everything by adding a "unique id"
391+ // (which is the position in the vector).
392+ not_stripped_items. dedup_by_key ( |( idx, i) | {
393+ (
394+ i. item_id ,
395+ if i. name . is_some ( ) { Some ( full_path ( cx, i) ) } else { None } ,
396+ i. type_ ( ) ,
397+ if i. is_import ( ) { * idx } else { 0 } ,
398+ )
399+ } ) ;
400+
401+ debug ! ( "{not_stripped_items:?}" ) ;
402+ let mut last_section = None ;
403+
404+ for ( _, myitem) in & not_stripped_items {
405+ let my_section = item_ty_to_section ( myitem. type_ ( ) ) ;
406+ if Some ( my_section) != last_section {
407+ if last_section. is_some ( ) {
408+ w. write_str ( ITEM_TABLE_CLOSE ) ?;
409+ }
410+ last_section = Some ( my_section) ;
411+ let section_id = my_section. id ( ) ;
412+ let tag =
413+ if section_id == "reexports" { REEXPORTS_TABLE_OPEN } else { ITEM_TABLE_OPEN } ;
414+ write ! (
415+ w,
408416 "{}" ,
409417 write_section_heading( my_section. name( ) , & cx. derive_id( section_id) , None , tag)
410- ) ,
411- ) ;
412- }
418+ ) ?;
419+ }
413420
414- match myitem. kind {
415- clean:: ExternCrateItem { ref src } => {
416- use crate :: html:: format:: anchor;
421+ match myitem. kind {
422+ clean:: ExternCrateItem { ref src } => {
423+ use crate :: html:: format:: anchor;
417424
418- match * src {
419- Some ( src) => {
420- write_str (
421- w,
422- format_args ! (
425+ match * src {
426+ Some ( src) => {
427+ write ! (
428+ w,
423429 "<dt><code>{}extern crate {} as {};" ,
424430 visibility_print_with_space( myitem, cx) ,
425431 anchor( myitem. item_id. expect_def_id( ) , src, cx) ,
426432 EscapeBodyTextWithWbr ( myitem. name. unwrap( ) . as_str( ) )
427- ) ,
428- ) ;
429- }
430- None => {
431- write_str (
432- w,
433- format_args ! (
433+ ) ?;
434+ }
435+ None => {
436+ write ! (
437+ w,
434438 "<dt><code>{}extern crate {};" ,
435439 visibility_print_with_space( myitem, cx) ,
436440 anchor( myitem. item_id. expect_def_id( ) , myitem. name. unwrap( ) , cx)
437- ) ,
438- ) ;
441+ ) ? ;
442+ }
439443 }
444+ w. write_str ( "</code></dt>" ) ?;
440445 }
441- w. push_str ( "</code></dt>" ) ;
442- }
443446
444- clean:: ImportItem ( ref import) => {
445- let stab_tags = import. source . did . map_or_else ( String :: new, |import_def_id| {
446- extra_info_tags ( tcx, myitem, item, Some ( import_def_id) ) . to_string ( )
447- } ) ;
447+ clean:: ImportItem ( ref import) => {
448+ let stab_tags = import. source . did . map_or_else ( String :: new, |import_def_id| {
449+ extra_info_tags ( tcx, myitem, item, Some ( import_def_id) ) . to_string ( )
450+ } ) ;
448451
449- let id = match import. kind {
450- clean:: ImportKind :: Simple ( s) => {
451- format ! ( " id=\" {}\" " , cx. derive_id( format!( "reexport.{s}" ) ) )
452- }
453- clean:: ImportKind :: Glob => String :: new ( ) ,
454- } ;
455- write_str (
456- w,
457- format_args ! (
452+ let id = match import. kind {
453+ clean:: ImportKind :: Simple ( s) => {
454+ format ! ( " id=\" {}\" " , cx. derive_id( format!( "reexport.{s}" ) ) )
455+ }
456+ clean:: ImportKind :: Glob => String :: new ( ) ,
457+ } ;
458+ write ! (
459+ w,
458460 "<dt{id}>\
459461 <code>{vis}{imp}</code>{stab_tags}\
460462 </dt>",
461463 vis = visibility_print_with_space( myitem, cx) ,
462464 imp = import. print( cx)
463- ) ,
464- ) ;
465- }
466-
467- _ => {
468- if myitem. name . is_none ( ) {
469- continue ;
465+ ) ?;
470466 }
471467
472- let unsafety_flag = match myitem. kind {
473- clean:: FunctionItem ( _) | clean:: ForeignFunctionItem ( ..)
474- if myitem. fn_header ( tcx) . unwrap ( ) . is_unsafe ( ) =>
475- {
476- "<sup title=\" unsafe function\" >⚠</sup>"
477- }
478- clean:: ForeignStaticItem ( _, hir:: Safety :: Unsafe ) => {
479- "<sup title=\" unsafe static\" >⚠</sup>"
468+ _ => {
469+ if myitem. name . is_none ( ) {
470+ continue ;
480471 }
481- _ => "" ,
482- } ;
483-
484- let visibility_and_hidden = match myitem. visibility ( tcx) {
485- Some ( ty:: Visibility :: Restricted ( _) ) => {
486- if myitem. is_doc_hidden ( ) {
487- // Don't separate with a space when there are two of them
488- "<span title=\" Restricted Visibility\" > 🔒</span><span title=\" Hidden item\" >👻</span> "
489- } else {
490- "<span title=\" Restricted Visibility\" > 🔒</span> "
472+
473+ let unsafety_flag = match myitem. kind {
474+ clean:: FunctionItem ( _) | clean:: ForeignFunctionItem ( ..)
475+ if myitem. fn_header ( tcx) . unwrap ( ) . is_unsafe ( ) =>
476+ {
477+ "<sup title=\" unsafe function\" >⚠</sup>"
491478 }
492- }
493- _ if myitem. is_doc_hidden ( ) => "<span title=\" Hidden item\" > 👻</span> " ,
494- _ => "" ,
495- } ;
496-
497- let docs =
498- MarkdownSummaryLine ( & myitem. doc_value ( ) , & myitem. links ( cx) ) . into_string ( ) ;
499- let ( docs_before, docs_after) =
500- if docs. is_empty ( ) { ( "" , "" ) } else { ( "<dd>" , "</dd>" ) } ;
501- write_str (
502- w,
503- format_args ! (
479+ clean:: ForeignStaticItem ( _, hir:: Safety :: Unsafe ) => {
480+ "<sup title=\" unsafe static\" >⚠</sup>"
481+ }
482+ _ => "" ,
483+ } ;
484+
485+ let visibility_and_hidden = match myitem. visibility ( tcx) {
486+ Some ( ty:: Visibility :: Restricted ( _) ) => {
487+ if myitem. is_doc_hidden ( ) {
488+ // Don't separate with a space when there are two of them
489+ "<span title=\" Restricted Visibility\" > 🔒</span><span title=\" Hidden item\" >👻</span> "
490+ } else {
491+ "<span title=\" Restricted Visibility\" > 🔒</span> "
492+ }
493+ }
494+ _ if myitem. is_doc_hidden ( ) => {
495+ "<span title=\" Hidden item\" > 👻</span> "
496+ }
497+ _ => "" ,
498+ } ;
499+
500+ let docs =
501+ MarkdownSummaryLine ( & myitem. doc_value ( ) , & myitem. links ( cx) ) . into_string ( ) ;
502+ let ( docs_before, docs_after) =
503+ if docs. is_empty ( ) { ( "" , "" ) } else { ( "<dd>" , "</dd>" ) } ;
504+ write ! (
505+ w,
504506 "<dt>\
505507 <a class=\" {class}\" href=\" {href}\" title=\" {title}\" >{name}</a>\
506508 {visibility_and_hidden}\
@@ -515,15 +517,16 @@ fn item_module(w: &mut String, cx: &Context<'_>, item: &clean::Item, items: &[cl
515517 unsafety_flag = unsafety_flag,
516518 href = item_path( myitem. type_( ) , myitem. name. unwrap( ) . as_str( ) ) ,
517519 title = format_args!( "{} {}" , myitem. type_( ) , full_path( cx, myitem) ) ,
518- ) ,
519- ) ;
520+ ) ? ;
521+ }
520522 }
521523 }
522- }
523524
524- if last_section. is_some ( ) {
525- w. push_str ( ITEM_TABLE_CLOSE ) ;
526- }
525+ if last_section. is_some ( ) {
526+ w. write_str ( ITEM_TABLE_CLOSE ) ?;
527+ }
528+ Ok ( ( ) )
529+ } )
527530}
528531
529532/// Render the stability, deprecation and portability tags that are displayed in the item's summary
0 commit comments