Skip to content

Commit 8545112

Browse files
Merge pull request #44 from kingwingfly/fix/#37
fix(#37)
2 parents 4fbea15 + 64efbd5 commit 8545112

File tree

1 file changed

+80
-56
lines changed

1 file changed

+80
-56
lines changed

src/lib.rs

Lines changed: 80 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
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

77
use proc_macro::TokenStream;
88
use 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]
165174
pub 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]
240254
pub 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]
382401
pub 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

453467
fn 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

Comments
 (0)