@@ -18,6 +18,8 @@ use venial::parse_declaration;
18
18
use venial:: Attribute ;
19
19
use venial:: AttributeValue ;
20
20
use venial:: Declaration ;
21
+ use venial:: GenericParam ;
22
+ use venial:: GenericParamList ;
21
23
use venial:: StructFields ;
22
24
23
25
fn stream_span ( input : impl Iterator < Item = impl Deref < Target = TokenTree > > ) -> Option < Span > {
@@ -40,15 +42,15 @@ pub(crate) fn recurse_through_definition(
40
42
mut strike_attrs : Vec < Attribute > ,
41
43
make_pub : bool ,
42
44
ret : & mut TokenStream ,
43
- ) {
45
+ ) -> Option < GenericParamList > {
44
46
let span = stream_span ( input. clone ( ) . into_iter ( ) . map ( Cow :: Owned ) ) ;
45
47
let input = move_out_inner_attrs ( input) ;
46
48
let mut parsed = match parse_declaration ( input) {
47
49
Ok ( parsed) => parsed,
48
50
Err ( e) => {
49
51
// Sadly, venial still panics on invalid syntax
50
52
report_error ( span, ret, & format ! ( "{}" , e) ) ;
51
- return ;
53
+ return None ;
52
54
}
53
55
} ;
54
56
match & mut parsed {
@@ -74,11 +76,12 @@ pub(crate) fn recurse_through_definition(
74
76
}
75
77
}
76
78
_ => {
77
- return report_error (
79
+ report_error (
78
80
span,
79
81
ret,
80
82
"Unsupported declaration (only struct and enum are allowed)" ,
81
83
) ;
84
+ return None ;
82
85
}
83
86
}
84
87
if let Declaration :: Struct ( s) = & mut parsed {
@@ -89,6 +92,7 @@ pub(crate) fn recurse_through_definition(
89
92
}
90
93
}
91
94
parsed. to_tokens ( ret) ;
95
+ parsed. generic_params ( ) . cloned ( )
92
96
}
93
97
94
98
pub ( crate ) fn make_pub_marker ( ) -> venial:: VisMarker {
@@ -292,14 +296,14 @@ fn recurse_through_type(
292
296
. iter ( )
293
297
. position ( |t| matches ! ( t, TokenTree :: Ident ( kw) if is_decl_kw( kw) ) )
294
298
. unwrap ( ) ;
295
- if let Some ( name @ TokenTree :: Ident ( _) ) = decl. get ( pos + 1 ) {
299
+ let generics = if let Some ( name @ TokenTree :: Ident ( _) ) = decl. get ( pos + 1 ) {
296
300
type_ret. push ( name. clone ( ) ) ;
297
301
recurse_through_definition (
298
302
decl. into_iter ( ) . collect ( ) ,
299
303
strike_attrs. to_vec ( ) ,
300
304
pub_hint,
301
305
ret,
302
- ) ;
306
+ )
303
307
} else {
304
308
let name = match name_hint {
305
309
Some ( name) => TokenTree :: Ident ( name. clone ( ) ) ,
@@ -315,8 +319,27 @@ fn recurse_through_type(
315
319
let tail = decl. drain ( ( pos + 1 ) ..) . collect :: < TokenStream > ( ) ;
316
320
let head = decl. into_iter ( ) . collect :: < TokenStream > ( ) ;
317
321
let newthing = quote ! { #head #name #tail} ;
318
- recurse_through_definition ( newthing, strike_attrs. to_vec ( ) , pub_hint, ret) ;
322
+ let generics =
323
+ recurse_through_definition ( newthing, strike_attrs. to_vec ( ) , pub_hint, ret) ;
324
+
319
325
type_ret. push ( name) ;
326
+ generics
327
+ } ;
328
+ if let Some ( generics) = generics {
329
+ type_ret. push ( generics. tk_l_bracket . into ( ) ) ;
330
+ let mut gp = generics. params . clone ( ) ;
331
+ gp. iter_mut ( ) . for_each ( |( gp, _) | {
332
+ * gp = GenericParam {
333
+ name : gp. name . clone ( ) ,
334
+ tk_prefix : gp
335
+ . tk_prefix
336
+ . clone ( )
337
+ . filter ( |pfx| matches ! ( pfx, TokenTree :: Punct ( _) ) ) ,
338
+ bound : None ,
339
+ }
340
+ } ) ;
341
+ type_ret. extend ( gp. into_token_stream ( ) ) ;
342
+ type_ret. push ( generics. tk_r_bracket . into ( ) ) ;
320
343
}
321
344
} else {
322
345
un_type_tree ( tok, type_ret, |g, type_ret| {
0 commit comments