Skip to content

Commit 5ec6004

Browse files
committed
Moved generics parsing into the proc macro
1 parent d4fb763 commit 5ec6004

File tree

2 files changed

+82
-34
lines changed

2 files changed

+82
-34
lines changed

rust/kernel/init/pin_project.rs

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,19 @@ macro_rules! pin_project {
88
@args($($pinned_drop:ident)?),
99
@sig(
1010
$(#[$($struct_attr:tt)*])*
11-
$vis:vis struct $name:ident $(<$($generics:ident),*>)?
11+
$vis:vis struct $name:ident
1212
$(where $($whr:tt)*)?
1313
),
14-
@body({ $($fields:tt)* })
15-
) => {
16-
$crate::pin_project!(find_pinned_fields:
17-
@struct_attrs($(#[$($struct_attr)*])*),
18-
@vis($vis),
19-
@name($name),
20-
@impl_generics($($($generics),*)?),
21-
@ty_generics($($($generics),*)?),
22-
@where($($($whr)*)?),
23-
@fields_munch($($fields)*),
24-
@pinned(),
25-
@not_pinned(),
26-
@fields(),
27-
@accum(),
28-
@is_pinned(),
29-
@pinned_drop($($pinned_drop)?),
30-
);
31-
};
32-
(parse_input:
33-
@args($($pinned_drop:ident)?),
34-
@sig(
35-
$(#[$($struct_attr:tt)*])*
36-
$vis:vis struct $name:ident $(<$($lifetimes:lifetime,)* $($generics:ident),+>)?
37-
$(where $($whr:tt)*)?
38-
),
39-
@body({ $($fields:tt)* })
14+
@impl_generics($($impl_generics:tt)*),
15+
@ty_generics($($ty_generics:tt)*),
16+
@body({ $($fields:tt)* }),
4017
) => {
4118
$crate::pin_project!(find_pinned_fields:
4219
@struct_attrs($(#[$($struct_attr)*])*),
4320
@vis($vis),
4421
@name($name),
45-
@impl_generics($($($lifetimes,)* $($generics),+)?),
46-
@ty_generics($($($lifetimes,)* $($generics),+)?),
22+
@impl_generics($($impl_generics)*),
23+
@ty_generics($($ty_generics)*),
4724
@where($($($whr)*)?),
4825
@fields_munch($($fields)*),
4926
@pinned(),
@@ -225,7 +202,7 @@ macro_rules! pin_project {
225202
@pinned_drop($($pinned_drop:ident)?),
226203
) => {
227204
$($struct_attrs)*
228-
$vis struct $name <$($ty_generics)*>
205+
$vis struct $name <$($impl_generics)*>
229206
where $($whr)*
230207
{
231208
$($fields)*

rust/macros/pin_project.rs

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,61 @@
33
use proc_macro::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
44

55
pub(crate) fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream {
6-
let mut toks = input.into_iter().collect::<Vec<_>>();
7-
let last = toks.pop();
6+
let mut impl_generics = vec![];
7+
let mut ty_generics = vec![];
8+
let mut rest = vec![];
9+
let mut nesting = 0;
10+
let mut invalid = false;
11+
let mut toks = input.into_iter();
12+
let mut at_start = true;
13+
for tt in &mut toks {
14+
match tt.clone() {
15+
TokenTree::Punct(p) if p.as_char() == '<' => {
16+
if nesting >= 1 {
17+
impl_generics.push(tt);
18+
}
19+
nesting += 1;
20+
}
21+
TokenTree::Punct(p) if p.as_char() == '>' => {
22+
if nesting == 0 {
23+
break;
24+
} else {
25+
nesting -= 1;
26+
if nesting >= 1 {
27+
impl_generics.push(tt);
28+
}
29+
if nesting == 0 {
30+
break;
31+
}
32+
}
33+
}
34+
tt => {
35+
if nesting == 1 {
36+
match &tt {
37+
TokenTree::Ident(i) if i.to_string() == "const" => {}
38+
TokenTree::Ident(i) if at_start => {
39+
ty_generics.push(tt.clone());
40+
ty_generics.push(TokenTree::Punct(Punct::new(',', Spacing::Alone)));
41+
at_start = false;
42+
}
43+
TokenTree::Punct(p) if p.as_char() == ',' => at_start = true,
44+
TokenTree::Punct(p) if p.as_char() == '\'' && at_start => {
45+
ty_generics.push(tt.clone());
46+
ty_generics.push(TokenTree::Punct(Punct::new(',', Spacing::Alone)));
47+
}
48+
_ => {}
49+
}
50+
}
51+
if nesting >= 1 {
52+
impl_generics.push(tt);
53+
} else if nesting == 0 {
54+
rest.push(tt);
55+
}
56+
}
57+
}
58+
}
59+
rest.extend(toks);
60+
let last = rest.pop();
861
TokenStream::from_iter(vec![
962
TokenTree::Punct(Punct::new(':', Spacing::Joint)),
1063
TokenTree::Punct(Punct::new(':', Spacing::Alone)),
@@ -20,13 +73,30 @@ pub(crate) fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream
2073
TokenTree::Punct(Punct::new(':', Spacing::Alone)),
2174
TokenTree::Punct(Punct::new('@', Spacing::Alone)),
2275
TokenTree::Ident(Ident::new("args", Span::call_site())),
23-
TokenTree::Group(Group::new(Delimiter::Parenthesis, args)),
76+
TokenTree::Group(Group::new(
77+
Delimiter::Parenthesis,
78+
TokenStream::from_iter(args),
79+
)),
2480
TokenTree::Punct(Punct::new(',', Spacing::Alone)),
2581
TokenTree::Punct(Punct::new('@', Spacing::Alone)),
2682
TokenTree::Ident(Ident::new("sig", Span::call_site())),
2783
TokenTree::Group(Group::new(
2884
Delimiter::Parenthesis,
29-
TokenStream::from_iter(toks),
85+
TokenStream::from_iter(rest),
86+
)),
87+
TokenTree::Punct(Punct::new(',', Spacing::Alone)),
88+
TokenTree::Punct(Punct::new('@', Spacing::Alone)),
89+
TokenTree::Ident(Ident::new("impl_generics", Span::call_site())),
90+
TokenTree::Group(Group::new(
91+
Delimiter::Parenthesis,
92+
TokenStream::from_iter(impl_generics),
93+
)),
94+
TokenTree::Punct(Punct::new(',', Spacing::Alone)),
95+
TokenTree::Punct(Punct::new('@', Spacing::Alone)),
96+
TokenTree::Ident(Ident::new("ty_generics", Span::call_site())),
97+
TokenTree::Group(Group::new(
98+
Delimiter::Parenthesis,
99+
TokenStream::from_iter(ty_generics),
30100
)),
31101
TokenTree::Punct(Punct::new(',', Spacing::Alone)),
32102
TokenTree::Punct(Punct::new('@', Spacing::Alone)),
@@ -35,6 +105,7 @@ pub(crate) fn pin_project(args: TokenStream, input: TokenStream) -> TokenStream
35105
Delimiter::Parenthesis,
36106
TokenStream::from_iter(last),
37107
)),
108+
TokenTree::Punct(Punct::new(',', Spacing::Alone)),
38109
]),
39110
)),
40111
])

0 commit comments

Comments
 (0)