22
33// FIXME(15321): solve CI failures, then replace with `#![expect()]`.
44#![ allow( missing_docs, reason = "Not all docs are written yet, see #3492." ) ]
5- #![ cfg_attr( any( docsrs, docsrs_dep) , feature( doc_auto_cfg , rustdoc_internals) ) ]
5+ #![ cfg_attr( any( docsrs, docsrs_dep) , feature( doc_cfg , rustdoc_internals) ) ]
66
77use proc_macro:: TokenStream ;
88use proc_macro2:: { Literal , Span as Span2 , TokenStream as TokenStream2 } ;
@@ -28,13 +28,6 @@ impl Parse for AllTuples {
2828 let macro_ident = input. parse :: < Ident > ( ) ?;
2929 input. parse :: < Comma > ( ) ?;
3030 let start = input. parse :: < LitInt > ( ) ?. base10_parse ( ) ?;
31- input. parse :: < Comma > ( ) ?;
32- let end = input. parse :: < LitInt > ( ) ?. base10_parse ( ) ?;
33- input. parse :: < Comma > ( ) ?;
34- let mut idents = vec ! [ input. parse:: <Ident >( ) ?] ;
35- while input. parse :: < Comma > ( ) . is_ok ( ) {
36- idents. push ( input. parse :: < Ident > ( ) ?) ;
37- }
3831
3932 if start > 1 && fake_variadic {
4033 return Err ( Error :: new (
@@ -43,6 +36,14 @@ impl Parse for AllTuples {
4336 ) ) ;
4437 }
4538
39+ input. parse :: < Comma > ( ) ?;
40+ let end = input. parse :: < LitInt > ( ) ?. base10_parse ( ) ?;
41+ input. parse :: < Comma > ( ) ?;
42+ let mut idents = vec ! [ input. parse:: <Ident >( ) ?] ;
43+ while input. parse :: < Comma > ( ) . is_ok ( ) {
44+ idents. push ( input. parse :: < Ident > ( ) ?) ;
45+ }
46+
4647 Ok ( AllTuples {
4748 fake_variadic,
4849 macro_ident,
@@ -83,6 +84,7 @@ impl Parse for AllTuples {
8384/// };
8485/// }
8586///
87+ /// // start from 0 element to 15 elements
8688/// all_tuples!(impl_wrapped_in_foo, 0, 15, T);
8789/// // impl_wrapped_in_foo!();
8890/// // impl_wrapped_in_foo!(T0);
@@ -119,12 +121,19 @@ impl Parse for AllTuples {
119121/// }
120122/// }
121123///
124+ /// // start from 1 element to 15 elements
122125/// all_tuples!(impl_append, 1, 15, P, p);
123126/// // impl_append!((P0, p0));
124127/// // impl_append!((P0, p0), (P1, p1));
125128/// // impl_append!((P0, p0), (P1, p1), (P2, p2));
126129/// // ..
127130/// // impl_append!((P0, p0) .. (P14, p14));
131+ ///
132+ /// // start from 16 elements to 20
133+ /// all_tuples!(impl_append, 16, 20, P, p);
134+ /// // impl_append!((P0, p0) .. (P15, p15));
135+ /// // ..
136+ /// // impl_append!((P0, p0) .. (P19, p19));
128137/// ```
129138///
130139/// **`#[doc(fake_variadic)]`**
@@ -164,8 +173,7 @@ impl Parse for AllTuples {
164173#[ proc_macro]
165174pub fn all_tuples ( input : TokenStream ) -> TokenStream {
166175 let input = parse_macro_input ! ( input as AllTuples ) ;
167- let len = 1 + input. end - input. start ;
168- let ident_tuples = ( 0 ..=len)
176+ let ident_tuples = ( 0 ..input. end )
169177 . map ( |i| {
170178 let idents = input
171179 . idents
@@ -175,13 +183,9 @@ pub fn all_tuples(input: TokenStream) -> TokenStream {
175183 } )
176184 . collect :: < Vec < _ > > ( ) ;
177185 let macro_ident = & input. macro_ident ;
178- let invocations = ( input. start ..=input. end ) . map ( |i| {
179- let ident_tuples = choose_ident_tuples ( & input, & ident_tuples, i) ;
180- let attrs = if input. fake_variadic {
181- fake_variadic_attrs ( len, i)
182- } else {
183- TokenStream2 :: default ( )
184- } ;
186+ let invocations = ( input. start ..=input. end ) . map ( |n| {
187+ let ident_tuples = choose_ident_tuples ( & input, & ident_tuples, n) ;
188+ let attrs = attrs ( & input, n) ;
185189 quote ! {
186190 #macro_ident!( #attrs #ident_tuples) ;
187191 }
@@ -225,6 +229,11 @@ pub fn all_tuples(input: TokenStream) -> TokenStream {
225229/// // impl_squawk!((0, T0), (1, T1));
226230/// // ..
227231/// // impl_squawk!((0, T0) .. (14, T14));
232+ ///
233+ /// all_tuples_enumerated!(impl_squawk, 16, 20, T);
234+ /// // impl_append!((0, T0) .. (15, T15));
235+ /// // ..
236+ /// // impl_append!((0, T0) .. (19, T19));
228237/// ```
229238///
230239/// With multiple parameters, the result is similar, but with the additional parameters
@@ -235,28 +244,28 @@ pub fn all_tuples(input: TokenStream) -> TokenStream {
235244/// // impl_squawk!((0, P0, p0), (1, P1, p1));
236245/// // ..
237246/// // impl_squawk!((0, P0, p0) .. (14, P14, p14));
247+ ///
248+ /// all_tuples_enumerated!(impl_append, 16, 20, P, p);
249+ /// // impl_append!((0, P0, p0) .. (15, P15, p15));
250+ /// // ..
251+ /// // impl_append!((0, P0, p0) .. (19, P19, p19));
238252/// ```
239253#[ proc_macro]
240254pub fn all_tuples_enumerated ( input : TokenStream ) -> TokenStream {
241255 let input = parse_macro_input ! ( input as AllTuples ) ;
242- let len = 1 + input. end - input. start ;
243- let ident_tuples = ( 0 ..=len)
256+ let ident_tuples = ( 0 ..input. end )
244257 . map ( |i| {
245258 let idents = input
246259 . idents
247260 . iter ( )
248261 . map ( |ident| format_ident ! ( "{}{}" , ident, i) ) ;
249- to_ident_tuple_enumerated ( idents, input . idents . len ( ) )
262+ to_ident_tuple_enumerated ( idents, i )
250263 } )
251264 . collect :: < Vec < _ > > ( ) ;
252265 let macro_ident = & input. macro_ident ;
253- let invocations = ( input. start ..=input. end ) . map ( |i| {
254- let ident_tuples = choose_ident_tuples_enumerated ( & input, & ident_tuples, i) ;
255- let attrs = if input. fake_variadic {
256- fake_variadic_attrs ( len, i)
257- } else {
258- TokenStream2 :: default ( )
259- } ;
266+ let invocations = ( input. start ..=input. end ) . map ( |n| {
267+ let ident_tuples = choose_ident_tuples_enumerated ( & input, & ident_tuples, n) ;
268+ let attrs = attrs ( & input, n) ;
260269 quote ! {
261270 #macro_ident!( #attrs #ident_tuples) ;
262271 }
@@ -306,6 +315,11 @@ pub fn all_tuples_enumerated(input: TokenStream) -> TokenStream {
306315/// // impl_wrapped_in_foo!(2, T0, T1);
307316/// // ..
308317/// // impl_wrapped_in_foo!(15, T0 .. T14);
318+ ///
319+ /// all_tuples_with_size!(impl_wrapped_in_foo, 16, 20, T);
320+ /// // impl_wrapped_in_foo!(16, T0 .. T15);
321+ /// // ..
322+ /// // impl_wrapped_in_foo!(20, T0 .. T19);
309323/// ```
310324///
311325/// ## Multiple parameters
@@ -342,6 +356,11 @@ pub fn all_tuples_enumerated(input: TokenStream) -> TokenStream {
342356/// // impl_append!(3, (P0, p0), (P1, p1), (P2, p2));
343357/// // ..
344358/// // impl_append!(15, (P0, p0) .. (P14, p14));
359+ ///
360+ /// all_tuples_with_size!(impl_append, 16, 20, P, p);
361+ /// // impl_append!(16, (P0, p0) .. (P15, p15));
362+ /// // ..
363+ /// // impl_append!(20, (P0, p0) .. (P19, p19));
345364/// ```
346365///
347366/// **`#[doc(fake_variadic)]`**
@@ -381,8 +400,7 @@ pub fn all_tuples_enumerated(input: TokenStream) -> TokenStream {
381400#[ proc_macro]
382401pub fn all_tuples_with_size ( input : TokenStream ) -> TokenStream {
383402 let input = parse_macro_input ! ( input as AllTuples ) ;
384- let len = 1 + input. end - input. start ;
385- let ident_tuples = ( 0 ..=len)
403+ let ident_tuples = ( 0 ..input. end )
386404 . map ( |i| {
387405 let idents = input
388406 . idents
@@ -392,15 +410,11 @@ pub fn all_tuples_with_size(input: TokenStream) -> TokenStream {
392410 } )
393411 . collect :: < Vec < _ > > ( ) ;
394412 let macro_ident = & input. macro_ident ;
395- let invocations = ( input. start ..=input. end ) . map ( |i| {
396- let ident_tuples = choose_ident_tuples ( & input, & ident_tuples, i) ;
397- let attrs = if input. fake_variadic {
398- fake_variadic_attrs ( len, i)
399- } else {
400- TokenStream2 :: default ( )
401- } ;
413+ let invocations = ( input. start ..=input. end ) . map ( |n| {
414+ let ident_tuples = choose_ident_tuples ( & input, & ident_tuples, n) ;
415+ let attrs = attrs ( & input, n) ;
402416 quote ! {
403- #macro_ident!( #i , #attrs #ident_tuples) ;
417+ #macro_ident!( #n , #attrs #ident_tuples) ;
404418 }
405419 } ) ;
406420 TokenStream :: from ( quote ! {
@@ -436,30 +450,30 @@ fn parse_fake_variadic_attr(input: ParseStream) -> Result<bool> {
436450 ) )
437451}
438452
439- fn choose_ident_tuples ( input : & AllTuples , ident_tuples : & [ TokenStream2 ] , i : usize ) -> TokenStream2 {
453+ fn choose_ident_tuples ( input : & AllTuples , ident_tuples : & [ TokenStream2 ] , n : usize ) -> TokenStream2 {
440454 // `rustdoc` uses the first ident to generate nice
441455 // idents with subscript numbers e.g. (F₁, F₂, …, Fₙ).
442456 // We don't want two numbers, so we use the
443457 // original, unnumbered idents for this case.
444- if input. fake_variadic && i == 1 {
458+ if input. fake_variadic && n == 1 {
445459 let ident_tuple = to_ident_tuple ( input. idents . iter ( ) . cloned ( ) , input. idents . len ( ) ) ;
446460 quote ! { #ident_tuple }
447461 } else {
448- let ident_tuples = & ident_tuples[ ..i ] ;
462+ let ident_tuples = & ident_tuples[ ..n ] ;
449463 quote ! { #( #ident_tuples) , * }
450464 }
451465}
452466
453467fn choose_ident_tuples_enumerated (
454468 input : & AllTuples ,
455469 ident_tuples : & [ TokenStream2 ] ,
456- i : usize ,
470+ n : usize ,
457471) -> TokenStream2 {
458- if input. fake_variadic && i == 1 {
472+ if input. fake_variadic && n == 1 {
459473 let ident_tuple = to_ident_tuple_enumerated ( input. idents . iter ( ) . cloned ( ) , 0 ) ;
460474 quote ! { #ident_tuple }
461475 } else {
462- let ident_tuples = & ident_tuples[ ..i ] ;
476+ let ident_tuples = & ident_tuples[ ..n ] ;
463477 quote ! { #( #ident_tuples) , * }
464478 }
465479}
@@ -478,23 +492,33 @@ fn to_ident_tuple_enumerated(idents: impl Iterator<Item = Ident>, idx: usize) ->
478492 quote ! { ( #idx, #( #idents) , * ) }
479493}
480494
481- fn fake_variadic_attrs ( len : usize , i : usize ) -> TokenStream2 {
482- let cfg = quote ! { any( docsrs, docsrs_dep) } ;
483- match i {
495+ /// n: number of elements
496+ fn attrs ( input : & AllTuples , n : usize ) -> TokenStream2 {
497+ if !input. fake_variadic {
498+ return TokenStream2 :: default ( ) ;
499+ }
500+ match n {
484501 // An empty tuple (i.e. the unit type) is still documented separately,
485502 // so no `#[doc(hidden)]` here.
486503 0 => TokenStream2 :: default ( ) ,
487- // The `#[doc(fake_variadic)]` attr has to be on the first impl block.
488- 1 => {
489- let doc = LitStr :: new (
490- & format ! ( "This trait is implemented for tuples up to {len} items long." ) ,
491- Span2 :: call_site ( ) ,
492- ) ;
493- quote ! {
494- #[ cfg_attr( #cfg, doc( fake_variadic) ) ]
495- #[ cfg_attr( #cfg, doc = #doc) ]
504+ n => {
505+ let cfg = quote ! { any( docsrs, docsrs_dep) } ;
506+ // The `#[doc(fake_variadic)]` attr has to be on the first impl block.
507+ if n == 1 {
508+ let doc = LitStr :: new (
509+ & format ! (
510+ "This trait is implemented for tuples down to {} up to {} items long." ,
511+ input. start, input. end
512+ ) ,
513+ Span2 :: call_site ( ) ,
514+ ) ;
515+ quote ! {
516+ #[ cfg_attr( #cfg, doc( fake_variadic) ) ]
517+ #[ cfg_attr( #cfg, doc = #doc) ]
518+ }
519+ } else {
520+ quote ! { #[ cfg_attr( #cfg, doc( hidden) ) ] }
496521 }
497522 }
498- _ => quote ! { #[ cfg_attr( #cfg, doc( hidden) ) ] } ,
499523 }
500524}
0 commit comments