@@ -27,6 +27,7 @@ struct DerivedTS {
2727 inline : TokenStream ,
2828 inline_flattened : Option < TokenStream > ,
2929 dependencies : Dependencies ,
30+ flattened_dependencies : Dependencies ,
3031 concrete : HashMap < Ident , Type > ,
3132 bound : Option < Vec < WherePredicate > > ,
3233 ts_enum : Option < Repr > ,
@@ -77,13 +78,15 @@ impl DerivedTS {
7778 } ;
7879
7980 let ident = self . ts_name . clone ( ) ;
80- let impl_start = generate_impl_block_header (
81+ let ( impl_start, bounds ) = generate_impl_block_header (
8182 & crate_rename,
8283 & rust_ty,
8384 & generics,
8485 self . bound . as_deref ( ) ,
8586 & self . dependencies ,
87+ & self . flattened_dependencies ,
8688 ) ;
89+
8790 let assoc_type = generate_assoc_type ( & rust_ty, & crate_rename, & generics, & self . concrete ) ;
8891 let name = self . generate_name_fn ( & generics) ;
8992 let is_enum = self . is_enum . clone ( ) ;
@@ -92,9 +95,20 @@ impl DerivedTS {
9295 let dependencies = & self . dependencies ;
9396 let generics_fn = self . generate_generics_fn ( & generics) ;
9497
98+ let inline_flattened = self . inline_flattened . clone ( ) . map ( |x| {
99+ quote ! {
100+ #[ automatically_derived]
101+ #impl_start #crate_rename:: Flattenable #bounds {
102+ fn inline_flattened( cfg: & #crate_rename:: Config ) -> String {
103+ #x
104+ }
105+ }
106+ }
107+ } ) ;
108+
95109 quote ! {
96110 #[ automatically_derived]
97- #impl_start {
111+ #impl_start #crate_rename :: TS #bounds {
98112 #assoc_type
99113 type OptionInnerType = Self ;
100114
@@ -119,6 +133,8 @@ impl DerivedTS {
119133 }
120134 }
121135
136+ #inline_flattened
137+
122138 #export
123139 }
124140 }
@@ -178,10 +194,12 @@ impl DerivedTS {
178194 type OptionInnerType = Self ;
179195 fn name( cfg: & #crate_rename:: Config ) -> String { stringify!( #generics) . to_owned( ) }
180196 fn inline( cfg: & #crate_rename:: Config ) -> String { panic!( "{} cannot be inlined" , #name) }
181- fn inline_flattened( cfg: & #crate_rename:: Config ) -> String { stringify!( #generics) . to_owned( ) }
182197 fn decl( cfg: & #crate_rename:: Config ) -> String { panic!( "{} cannot be declared" , #name) }
183198 fn decl_concrete( cfg: & #crate_rename:: Config ) -> String { panic!( "{} cannot be declared" , #name) }
184199 }
200+ impl #crate_rename:: Flattenable for #generics {
201+ fn inline_flattened( cfg: & #crate_rename:: Config ) -> String { stringify!( #generics) . to_owned( ) }
202+ }
185203 ) *
186204 }
187205 }
@@ -245,12 +263,6 @@ impl DerivedTS {
245263 let inline = & self . inline ;
246264 let crate_rename = & self . crate_rename ;
247265
248- let inline_flattened = self . inline_flattened . clone ( ) . unwrap_or_else ( || {
249- quote ! {
250- panic!( "{} cannot be flattened" , <Self as #crate_rename:: TS >:: name( cfg) )
251- }
252- } ) ;
253-
254266 let inline = match self . ts_enum {
255267 Some ( Repr :: Int ) => quote ! {
256268 let variants = #inline. replace( |x: char | !x. is_numeric( ) && x != ',' , "" ) ;
@@ -301,10 +313,6 @@ impl DerivedTS {
301313 fn inline( cfg: & #crate_rename:: Config ) -> String {
302314 #inline
303315 }
304-
305- fn inline_flattened( cfg: & #crate_rename:: Config ) -> String {
306- #inline_flattened
307- }
308316 }
309317 }
310318
@@ -394,7 +402,8 @@ fn generate_impl_block_header(
394402 generics : & Generics ,
395403 bounds : Option < & [ WherePredicate ] > ,
396404 dependencies : & Dependencies ,
397- ) -> TokenStream {
405+ flattened_dependencies : & Dependencies ,
406+ ) -> ( TokenStream , TokenStream ) {
398407 use GenericParam as G ;
399408
400409 let params = generics. params . iter ( ) . map ( |param| match param {
@@ -426,18 +435,23 @@ fn generate_impl_block_header(
426435 let where_bound = match bounds {
427436 Some ( bounds) => quote ! { where #( #bounds) , * } ,
428437 None => {
429- let bounds = generate_where_clause ( crate_rename, generics, dependencies) ;
438+ let bounds =
439+ generate_where_clause ( crate_rename, generics, dependencies, flattened_dependencies) ;
430440 quote ! { #bounds }
431441 }
432442 } ;
433443
434- quote ! ( impl <#( #params) , * > #crate_rename:: TS for #ty <#( #type_args) , * > #where_bound)
444+ (
445+ quote ! ( impl <#( #params) , * >) ,
446+ quote ! ( for #ty <#( #type_args) , * > #where_bound) ,
447+ )
435448}
436449
437450fn generate_where_clause (
438451 crate_rename : & Path ,
439452 generics : & Generics ,
440453 dependencies : & Dependencies ,
454+ flattened_dependencies : & Dependencies ,
441455) -> WhereClause {
442456 let used_types = {
443457 let is_type_param = |id : & Ident | generics. type_params ( ) . any ( |p| & p. ident == id) ;
@@ -449,9 +463,19 @@ fn generate_where_clause(
449463 used_types. into_iter ( )
450464 } ;
451465
466+ let flattened_used_types = {
467+ let is_type_param = |id : & Ident | generics. type_params ( ) . any ( |p| & p. ident == id) ;
468+
469+ let mut flattened_used_types = HashSet :: new ( ) ;
470+ for ty in flattened_dependencies. used_types ( ) {
471+ used_type_params ( & mut flattened_used_types, ty, is_type_param) ;
472+ }
473+ flattened_used_types. into_iter ( )
474+ } ;
475+
452476 let existing = generics. where_clause . iter ( ) . flat_map ( |w| & w. predicates ) ;
453477 parse_quote ! {
454- where #( #existing, ) * #( #used_types: #crate_rename:: TS ) , *
478+ where #( #existing, ) * #( #used_types: #crate_rename:: TS ) , * # ( , #flattened_used_types : #crate_rename :: Flattenable ) *
455479 }
456480}
457481
0 commit comments