88//! not be used external to this module.
99
1010use std:: borrow:: Cow ;
11- use std:: cell:: Cell ;
1211use std:: cmp:: Ordering ;
1312use std:: fmt:: { self , Display , Write } ;
1413use std:: iter:: { self , once} ;
1514
16- use itertools:: Itertools ;
1715use rustc_abi:: ExternAbi ;
1816use rustc_attr_parsing:: { ConstStability , StabilityLevel , StableSince } ;
1917use rustc_data_structures:: captures:: Captures ;
@@ -35,6 +33,7 @@ use crate::formats::cache::Cache;
3533use crate :: formats:: item_type:: ItemType ;
3634use crate :: html:: escape:: { Escape , EscapeBodyText } ;
3735use crate :: html:: render:: Context ;
36+ use crate :: join:: Join as _;
3837use crate :: passes:: collect_intra_doc_links:: UrlFragment ;
3938
4039pub ( crate ) trait Print {
@@ -146,36 +145,18 @@ impl Buffer {
146145 }
147146}
148147
149- pub ( crate ) fn comma_sep < T : Display > (
150- items : impl Iterator < Item = T > ,
151- space_after_comma : bool ,
152- ) -> impl Display {
153- let items = Cell :: new ( Some ( items) ) ;
154- fmt:: from_fn ( move |f| {
155- for ( i, item) in items. take ( ) . unwrap ( ) . enumerate ( ) {
156- if i != 0 {
157- write ! ( f, ",{}" , if space_after_comma { " " } else { "" } ) ?;
158- }
159- item. fmt ( f) ?;
160- }
161- Ok ( ( ) )
162- } )
163- }
164-
165148pub ( crate ) fn print_generic_bounds < ' a , ' tcx : ' a > (
166149 bounds : & ' a [ clean:: GenericBound ] ,
167150 cx : & ' a Context < ' tcx > ,
168151) -> impl Display + ' a + Captures < ' tcx > {
169152 fmt:: from_fn ( move |f| {
170- let mut bounds_dup = FxHashSet :: default ( ) ;
153+ ( || {
154+ let mut bounds_dup = FxHashSet :: default ( ) ;
171155
172- for ( i, bound) in bounds. iter ( ) . filter ( |b| bounds_dup. insert ( * b) ) . enumerate ( ) {
173- if i > 0 {
174- f. write_str ( " + " ) ?;
175- }
176- bound. print ( cx) . fmt ( f) ?;
177- }
178- Ok ( ( ) )
156+ bounds. iter ( ) . filter ( move |b| bounds_dup. insert ( * b) ) . map ( |bound| bound. print ( cx) )
157+ } )
158+ . join ( " + " )
159+ . fmt ( f)
179160 } )
180161}
181162
@@ -190,12 +171,7 @@ impl clean::GenericParamDef {
190171
191172 if !outlives. is_empty ( ) {
192173 f. write_str ( ": " ) ?;
193- for ( i, lt) in outlives. iter ( ) . enumerate ( ) {
194- if i != 0 {
195- f. write_str ( " + " ) ?;
196- }
197- write ! ( f, "{}" , lt. print( ) ) ?;
198- }
174+ write ! ( f, "{}" , ( || outlives. iter( ) . map( |lt| lt. print( ) ) ) . join( " + " ) ) ?;
199175 }
200176
201177 Ok ( ( ) )
@@ -245,10 +221,11 @@ impl clean::Generics {
245221 return Ok ( ( ) ) ;
246222 }
247223
224+ let real_params = ( || real_params. clone ( ) . map ( |g| g. print ( cx) ) ) . join ( ", " ) ;
248225 if f. alternate ( ) {
249- write ! ( f, "<{:#}>" , comma_sep ( real_params. map ( |g| g . print ( cx ) ) , true ) )
226+ write ! ( f, "<{:#}>" , real_params)
250227 } else {
251- write ! ( f, "<{}>" , comma_sep ( real_params. map ( |g| g . print ( cx ) ) , true ) )
228+ write ! ( f, "<{}>" , real_params)
252229 }
253230 } )
254231 }
@@ -270,10 +247,12 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
270247 ending : Ending ,
271248) -> impl Display + ' a + Captures < ' tcx > {
272249 fmt:: from_fn ( move |f| {
273- let mut where_predicates = gens
274- . where_predicates
275- . iter ( )
276- . map ( |pred| {
250+ if gens. where_predicates . is_empty ( ) {
251+ return Ok ( ( ) ) ;
252+ }
253+
254+ let where_predicates = || {
255+ gens. where_predicates . iter ( ) . map ( |pred| {
277256 fmt:: from_fn ( move |f| {
278257 if f. alternate ( ) {
279258 f. write_str ( " " ) ?;
@@ -312,13 +291,9 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
312291 }
313292 } )
314293 } )
315- . peekable ( ) ;
316-
317- if where_predicates. peek ( ) . is_none ( ) {
318- return Ok ( ( ) ) ;
319- }
294+ } ;
320295
321- let where_preds = comma_sep ( where_predicates, false ) ;
296+ let where_preds = where_predicates. join ( "," ) ;
322297 let clause = if f. alternate ( ) {
323298 if ending == Ending :: Newline {
324299 format ! ( " where{where_preds}," )
@@ -415,12 +390,7 @@ impl clean::GenericBound {
415390 } else {
416391 f. write_str ( "use<" ) ?;
417392 }
418- for ( i, arg) in args. iter ( ) . enumerate ( ) {
419- if i > 0 {
420- write ! ( f, ", " ) ?;
421- }
422- arg. fmt ( f) ?;
423- }
393+ ( || args. iter ( ) ) . join ( ", " ) . fmt ( f) ?;
424394 if f. alternate ( ) { f. write_str ( ">" ) } else { f. write_str ( ">" ) }
425395 }
426396 } )
@@ -524,11 +494,7 @@ pub(crate) enum HrefError {
524494// Panics if `syms` is empty.
525495pub ( crate ) fn join_with_double_colon ( syms : & [ Symbol ] ) -> String {
526496 let mut s = String :: with_capacity ( estimate_item_path_byte_length ( syms. len ( ) ) ) ;
527- s. push_str ( syms[ 0 ] . as_str ( ) ) ;
528- for sym in & syms[ 1 ..] {
529- s. push_str ( "::" ) ;
530- s. push_str ( sym. as_str ( ) ) ;
531- }
497+ write ! ( s, "{}" , ( || syms. iter( ) ) . join( "::" ) ) . unwrap ( ) ;
532498 s
533499}
534500
@@ -572,20 +538,20 @@ fn generate_macro_def_id_path(
572538 }
573539
574540 if let Some ( last) = path. last_mut ( ) {
575- * last = Symbol :: intern ( & format ! ( "macro.{}.html" , last . as_str ( ) ) ) ;
541+ * last = Symbol :: intern ( & format ! ( "macro.{last }.html" ) ) ;
576542 }
577543
578544 let url = match cache. extern_locations [ & def_id. krate ] {
579545 ExternalLocation :: Remote ( ref s) => {
580546 // `ExternalLocation::Remote` always end with a `/`.
581- format ! ( "{s}{path}" , path = path . iter ( ) . map ( |p| p . as_str ( ) ) . join( "/" ) )
547+ format ! ( "{s}{path}" , path = ( || path . iter ( ) ) . join( "/" ) )
582548 }
583549 ExternalLocation :: Local => {
584550 // `root_path` always end with a `/`.
585551 format ! (
586552 "{root_path}{path}" ,
587553 root_path = root_path. unwrap_or( "" ) ,
588- path = path . iter ( ) . map ( |p| p . as_str ( ) ) . join( "/" )
554+ path = ( || path . iter ( ) ) . join( "/" )
589555 )
590556 }
591557 ExternalLocation :: Unknown => {
@@ -682,9 +648,8 @@ fn make_href(
682648 url_parts. push ( "index.html" ) ;
683649 }
684650 _ => {
685- let prefix = shortty. as_str ( ) ;
686651 let last = fqp. last ( ) . unwrap ( ) ;
687- url_parts. push_fmt ( format_args ! ( "{prefix }.{last}.html" ) ) ;
652+ url_parts. push_fmt ( format_args ! ( "{shortty }.{last}.html" ) ) ;
688653 }
689654 }
690655 Ok ( ( url_parts. finish ( ) , shortty, fqp. to_vec ( ) ) )
@@ -950,12 +915,7 @@ fn tybounds<'a, 'tcx: 'a>(
950915 cx : & ' a Context < ' tcx > ,
951916) -> impl Display + ' a + Captures < ' tcx > {
952917 fmt:: from_fn ( move |f| {
953- for ( i, bound) in bounds. iter ( ) . enumerate ( ) {
954- if i > 0 {
955- write ! ( f, " + " ) ?;
956- }
957- bound. print ( cx) . fmt ( f) ?;
958- }
918+ ( || bounds. iter ( ) . map ( |bound| bound. print ( cx) ) ) . join ( " + " ) . fmt ( f) ?;
959919 if let Some ( lt) = lt {
960920 // We don't need to check `alternate` since we can be certain that
961921 // the lifetime doesn't contain any characters which need escaping.
@@ -974,7 +934,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
974934 if !params. is_empty ( ) {
975935 f. write_str ( keyword) ?;
976936 f. write_str ( if f. alternate ( ) { "<" } else { "<" } ) ?;
977- comma_sep ( params. iter ( ) . map ( |lt| lt. print ( cx) ) , true ) . fmt ( f) ?;
937+ ( || params. iter ( ) . map ( |lt| lt. print ( cx) ) ) . join ( ", " ) . fmt ( f) ?;
978938 f. write_str ( if f. alternate ( ) { "> " } else { "> " } ) ?;
979939 }
980940 Ok ( ( ) )
@@ -1025,9 +985,7 @@ fn fmt_type(
1025985 clean:: Primitive ( clean:: PrimitiveType :: Never ) => {
1026986 primitive_link ( f, PrimitiveType :: Never , format_args ! ( "!" ) , cx)
1027987 }
1028- clean:: Primitive ( prim) => {
1029- primitive_link ( f, prim, format_args ! ( "{}" , prim. as_sym( ) . as_str( ) ) , cx)
1030- }
988+ clean:: Primitive ( prim) => primitive_link ( f, prim, format_args ! ( "{}" , prim. as_sym( ) ) , cx) ,
1031989 clean:: BareFunction ( ref decl) => {
1032990 print_higher_ranked_params_with_space ( & decl. generic_params , cx, "for" ) . fmt ( f) ?;
1033991 decl. safety . print_with_space ( ) . fmt ( f) ?;
@@ -1067,18 +1025,13 @@ fn fmt_type(
10671025 primitive_link (
10681026 f,
10691027 PrimitiveType :: Tuple ,
1070- format_args ! ( "({})" , generic_names . iter ( ) . map ( |s| s . as_str ( ) ) . join( ", " ) ) ,
1028+ format_args ! ( "({})" , ( || generic_names . iter ( ) ) . join( ", " ) ) ,
10711029 cx,
10721030 )
10731031 } else {
1074- write ! ( f, "(" ) ?;
1075- for ( i, item) in many. iter ( ) . enumerate ( ) {
1076- if i != 0 {
1077- write ! ( f, ", " ) ?;
1078- }
1079- item. print ( cx) . fmt ( f) ?;
1080- }
1081- write ! ( f, ")" )
1032+ f. write_str ( "(" ) ?;
1033+ ( || many. iter ( ) . map ( |item| item. print ( cx) ) ) . join ( ", " ) . fmt ( f) ?;
1034+ f. write_str ( ")" )
10821035 }
10831036 }
10841037 } ,
@@ -1407,14 +1360,16 @@ impl clean::Arguments {
14071360 cx : & ' a Context < ' tcx > ,
14081361 ) -> impl Display + ' a + Captures < ' tcx > {
14091362 fmt:: from_fn ( move |f| {
1410- for ( i, input) in self . values . iter ( ) . enumerate ( ) {
1411- write ! ( f, "{}: " , input. name) ?;
1412- input. type_ . print ( cx) . fmt ( f) ?;
1413- if i + 1 < self . values . len ( ) {
1414- write ! ( f, ", " ) ?;
1415- }
1416- }
1417- Ok ( ( ) )
1363+ ( || {
1364+ self . values . iter ( ) . map ( |input| {
1365+ fmt:: from_fn ( |f| {
1366+ write ! ( f, "{}: " , input. name) ?;
1367+ input. type_ . print ( cx) . fmt ( f)
1368+ } )
1369+ } )
1370+ } )
1371+ . join ( ", " )
1372+ . fmt ( f)
14181373 } )
14191374 }
14201375}
@@ -1723,12 +1678,7 @@ impl clean::ImportSource {
17231678 }
17241679 let name = self . path . last ( ) ;
17251680 if let hir:: def:: Res :: PrimTy ( p) = self . path . res {
1726- primitive_link (
1727- f,
1728- PrimitiveType :: from ( p) ,
1729- format_args ! ( "{}" , name. as_str( ) ) ,
1730- cx,
1731- ) ?;
1681+ primitive_link ( f, PrimitiveType :: from ( p) , format_args ! ( "{name}" ) , cx) ?;
17321682 } else {
17331683 f. write_str ( name. as_str ( ) ) ?;
17341684 }
0 commit comments