@@ -86,8 +86,8 @@ impl MacroInput {
86
86
} else {
87
87
quote ! ( )
88
88
} ;
89
- let rebrand_impl = self . expand_brand_impl ( true ) ;
90
- let erase_impl = self . expand_brand_impl ( false ) ;
89
+ let rebrand_impl = self . expand_brand_impl ( true ) ? ;
90
+ let erase_impl = self . expand_brand_impl ( false ) ? ;
91
91
Ok ( quote ! {
92
92
#trace_impl
93
93
#trace_immutable_impl
@@ -129,7 +129,7 @@ impl MacroInput {
129
129
unsafe impl #impl_generics #trait_name for #target_type #where_clause {
130
130
#needs_trace_const
131
131
#[ inline] // TODO: Should this be unconditional?
132
- fn #visit_method_name<V : GcVisitor + ?Sized >( & #mutability self , visitor: & mut V ) -> Result <( ) , V :: Err > {
132
+ fn #visit_method_name<Visitor : GcVisitor + ?Sized >( & #mutability self , visitor: & mut Visitor ) -> Result <( ) , Visitor :: Err > {
133
133
#visit_impl
134
134
}
135
135
}
@@ -151,16 +151,18 @@ impl MacroInput {
151
151
}
152
152
} )
153
153
}
154
- fn expand_brand_impl ( & self , rebrand : bool /* true => rebrand, false => erase */ ) -> Option < TokenStream > {
154
+ fn expand_brand_impl ( & self , rebrand : bool /* true => rebrand, false => erase */ ) -> Result < Option < TokenStream > , Error > {
155
155
let requirements = if rebrand { self . bounds . rebrand . clone ( ) } else { self . bounds . erase . clone ( ) } ;
156
156
if let Some ( TraitRequirements :: Never ) = requirements {
157
157
// They are requesting that we dont implement
158
- return None ;
158
+ return Ok ( None ) ;
159
159
}
160
160
let target_type = & self . target_type ;
161
161
let mut generics = self . basic_generics ( ) ;
162
162
let default_bounds: Vec < TypeParamBound > = match requirements {
163
- Some ( TraitRequirements :: Where ( _) ) => {
163
+ Some ( TraitRequirements :: Where ( ref explicit_requirements) ) => {
164
+ generics. make_where_clause ( ) . predicates
165
+ . extend ( explicit_requirements. predicates . iter ( ) . cloned ( ) ) ;
164
166
// they have explicit requirements -> no default bounds
165
167
vec ! [ ]
166
168
}
@@ -185,6 +187,8 @@ impl MacroInput {
185
187
match param {
186
188
GenericParam :: Type ( ref tp) => {
187
189
let type_name = & tp. ident ;
190
+ let mut bounds = tp. bounds . clone ( ) ;
191
+ bounds. extend ( default_bounds. iter ( ) . cloned ( ) ) ;
188
192
generics. make_where_clause ( )
189
193
. predicates . push ( WherePredicate :: Type ( PredicateType {
190
194
lifetimes : None ,
@@ -193,19 +197,19 @@ impl MacroInput {
193
197
parse_quote ! ( <#type_name as GcRebrand <' new_gc, Id >>:: Branded )
194
198
} )
195
199
} else {
196
- self . options . branded_type . clone ( ) . unwrap_or_else ( || {
200
+ self . options . erased_type . clone ( ) . unwrap_or_else ( || {
197
201
parse_quote ! ( <#type_name as GcErase <' min, Id >>:: Erased )
198
202
} )
199
203
} ,
200
204
colon_token : Default :: default ( ) ,
201
- bounds : default_bounds . iter ( ) . cloned ( ) . collect ( )
205
+ bounds : bounds . clone ( ) ,
202
206
} ) ) ;
203
207
generics. make_where_clause ( )
204
208
. predicates . push ( WherePredicate :: Type ( PredicateType {
205
209
lifetimes : None ,
206
210
bounded_ty : parse_quote ! ( #type_name) ,
207
211
colon_token : Default :: default ( ) ,
208
- bounds : default_bounds . iter ( ) . cloned ( ) . collect ( )
212
+ bounds
209
213
} ) )
210
214
}
211
215
_ => { }
@@ -231,56 +235,6 @@ impl MacroInput {
231
235
} else {
232
236
quote ! ( GcErase <' min, Id >)
233
237
} ;
234
- fn rewrite_type ( target : & Type , target_type_name : & str , rewriter : & mut dyn FnMut ( & Type ) -> Option < Type > ) -> Result < Type , Error > {
235
- if let Some ( explicitly_rewritten) = rewriter ( target) {
236
- return Ok ( explicitly_rewritten)
237
- }
238
- match target {
239
- :: syn:: Type :: Path ( :: syn:: TypePath { ref qself, ref path } ) => {
240
- let new_qself = qself. clone ( ) . map ( |mut qself| {
241
- qself. ty = Box :: new ( rewrite_type (
242
- & * qself. ty , target_type_name,
243
- & mut * rewriter
244
- ) ?) ;
245
- Ok ( qself)
246
- } ) . transpose ( ) ?;
247
- let new_path = :: syn:: Path {
248
- leading_colon : path. leading_colon ,
249
- segments : path. segments . iter ( ) . cloned ( ) . map ( |segment| {
250
- // old_segment.ident is ignored...
251
- for arg in & mut segment. arguments {
252
- match arg {
253
- :: syn:: PathArguments :: None => { } , // Nothing to do here
254
- :: syn:: PathArguments :: AngleBracketed ( ref mut generic_args) => {
255
- for arg in & mut generic_args {
256
- match arg {
257
- GenericArgument :: Lifetime ( _) | GenericArgument :: Const ( _) => { } ,
258
- GenericArgument :: Type ( ref mut generic_type) => {
259
- * generic_type = rewrite_type ( generic_type, target_type_name, & mut * rewriter) ?;
260
- }
261
- GenericArgument :: Constraint ( _) | GenericArgument :: Binding ( _) => {
262
- return Err ( Error :: new (
263
- arg. span ( ) , format ! (
264
- "Unable to handle generic arg while rewriting as a {}" ,
265
- target_type_name
266
- )
267
- ) )
268
- }
269
- }
270
- }
271
- }
272
- }
273
- }
274
- } ) . collect ( )
275
- } ;
276
- Ok ( :: syn:: Type :: Path ( :: syn:: TypePath { qself : new_qself, path : new_path } ) )
277
- }
278
- _ => return Err ( Error :: new ( target. span ( ) , format ! (
279
- "Unable to rewrite type as a `{}`: {}" ,
280
- target_type_name, target
281
- ) ) )
282
- }
283
- }
284
238
fn rewrite_brand_trait (
285
239
target : & Type , trait_name : & str , target_params : & HashSet < Ident > ,
286
240
target_trait : TokenStream , associated_type : Ident
@@ -307,17 +261,17 @@ impl MacroInput {
307
261
_ => None
308
262
} ) . collect :: < HashSet < _ > > ( ) ;
309
263
let associated_type = if rebrand {
310
- let branded = Ok ( self . options . branded_type . clone ( ) ) . transpose ( ) . unwrap_or_else ( || {
264
+ let branded = self . options . branded_type . clone ( ) . map_or_else ( || {
311
265
rewrite_brand_trait (
312
266
& self . target_type , "GcRebrand" ,
313
267
& target_params,
314
268
parse_quote ! ( GcRebrand <' new_gc, Id >) ,
315
269
parse_quote ! ( Branded )
316
270
)
317
- } ) ?;
271
+ } , Ok ) ?;
318
272
quote ! ( type Branded = #branded; )
319
273
} else {
320
- let erased = Ok ( self . options . branded_type . clone ( ) ) . transpose ( ) . unwrap_or_else ( || {
274
+ let erased = Ok ( self . options . erased_type . clone ( ) ) . transpose ( ) . unwrap_or_else ( || {
321
275
rewrite_brand_trait (
322
276
& self . target_type , "GcErase" ,
323
277
& target_params,
@@ -327,11 +281,11 @@ impl MacroInput {
327
281
} ) ?;
328
282
quote ! ( type Erased = #erased; )
329
283
} ;
330
- Some ( quote ! {
284
+ Ok ( Some ( quote ! {
331
285
unsafe impl #impl_generics #target_trait for #target_type #where_clause {
332
- const
286
+ #associated_type
333
287
}
334
- } )
288
+ } ) )
335
289
}
336
290
}
337
291
@@ -585,14 +539,7 @@ fn create_clause_with_default(
585
539
} ) )
586
540
}
587
541
}
588
- let type_idents = generic_params. iter ( )
589
- . filter_map ( |param| match param {
590
- GenericParam :: Type ( ref t) => {
591
- Some ( t. ident . clone ( ) )
592
- } ,
593
- _ => None
594
- } ) . collect :: < Vec < _ > > ( ) ;
595
- parse_quote ! ( where #( #type_idents: Trace ) , * )
542
+ where_clause
596
543
}
597
544
} )
598
545
}
@@ -739,7 +686,7 @@ impl VisitImpl {
739
686
if mutable {
740
687
quote ! ( & mut )
741
688
} else {
742
- quote ! ( )
689
+ quote ! ( & )
743
690
}
744
691
}
745
692
} ;
@@ -853,4 +800,71 @@ impl Parse for TraitRequirements {
853
800
return Err ( input. error ( "Invalid `TraitRequirement`" ) )
854
801
}
855
802
}
856
- }
803
+ }
804
+
805
+
806
+
807
+ fn rewrite_type ( target : & Type , target_type_name : & str , rewriter : & mut dyn FnMut ( & Type ) -> Option < Type > ) -> Result < Type , Error > {
808
+ if let Some ( explicitly_rewritten) = rewriter ( target) {
809
+ return Ok ( explicitly_rewritten)
810
+ }
811
+ let mut target = target. clone ( ) ;
812
+ match target {
813
+ Type :: Paren ( ref mut inner) => {
814
+ * inner. elem = rewrite_type ( & inner. elem , target_type_name, rewriter) ?
815
+ } ,
816
+ Type :: Group ( ref mut inner) => {
817
+ * inner. elem = rewrite_type ( & inner. elem , target_type_name, rewriter) ?
818
+ } ,
819
+ Type :: Reference ( ref mut target) => {
820
+ // TODO: Lifetime safety?
821
+ // Rewrite reference target
822
+ * target. elem = rewrite_type ( & target. elem , target_type_name, rewriter) ?
823
+ }
824
+ Type :: Path ( :: syn:: TypePath { ref mut qself, ref mut path } ) => {
825
+ * qself = qself. clone ( ) . map :: < Result < _ , Error > , _ > ( |mut qself| {
826
+ qself. ty = Box :: new ( rewrite_type (
827
+ & * qself. ty , target_type_name,
828
+ & mut * rewriter
829
+ ) ?) ;
830
+ Ok ( qself)
831
+ } ) . transpose ( ) ?;
832
+ path. segments = path. segments . iter ( ) . cloned ( ) . map ( |mut segment| {
833
+ // old_segment.ident is ignored...
834
+ match segment. arguments {
835
+ :: syn:: PathArguments :: None => { } , // Nothing to do here
836
+ :: syn:: PathArguments :: AngleBracketed ( ref mut generic_args) => {
837
+ for arg in & mut generic_args. args {
838
+ match arg {
839
+ GenericArgument :: Lifetime ( _) | GenericArgument :: Const ( _) => { } ,
840
+ GenericArgument :: Type ( ref mut generic_type) => {
841
+ * generic_type = rewrite_type ( generic_type, target_type_name, & mut * rewriter) ?;
842
+ }
843
+ GenericArgument :: Constraint ( _) | GenericArgument :: Binding ( _) => {
844
+ return Err ( Error :: new (
845
+ arg. span ( ) , format ! (
846
+ "Unable to handle generic arg while rewriting as a {}" ,
847
+ target_type_name
848
+ )
849
+ ) )
850
+ }
851
+ }
852
+ }
853
+ }
854
+ :: syn:: PathArguments :: Parenthesized ( ref mut paran_args) => {
855
+ return Err ( Error :: new (
856
+ paran_args. span ( ) ,
857
+ "TODO: Rewriting paranthesized (fn-style) args"
858
+ ) ) ;
859
+ }
860
+ }
861
+ Ok ( segment)
862
+ } ) . collect :: < Result < _ , Error > > ( ) ?;
863
+ }
864
+ _ => return Err ( Error :: new ( target. span ( ) , format ! (
865
+ "Unable to rewrite type as a `{}`: {}" ,
866
+ target_type_name, quote!( #target)
867
+ ) ) )
868
+ }
869
+ Ok ( target)
870
+ }
0 commit comments