@@ -86,8 +86,8 @@ impl MacroInput {
8686 } else {
8787 quote ! ( )
8888 } ;
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 ) ? ;
9191 Ok ( quote ! {
9292 #trace_impl
9393 #trace_immutable_impl
@@ -129,7 +129,7 @@ impl MacroInput {
129129 unsafe impl #impl_generics #trait_name for #target_type #where_clause {
130130 #needs_trace_const
131131 #[ 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 > {
133133 #visit_impl
134134 }
135135 }
@@ -151,16 +151,18 @@ impl MacroInput {
151151 }
152152 } )
153153 }
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 > {
155155 let requirements = if rebrand { self . bounds . rebrand . clone ( ) } else { self . bounds . erase . clone ( ) } ;
156156 if let Some ( TraitRequirements :: Never ) = requirements {
157157 // They are requesting that we dont implement
158- return None ;
158+ return Ok ( None ) ;
159159 }
160160 let target_type = & self . target_type ;
161161 let mut generics = self . basic_generics ( ) ;
162162 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 ( ) ) ;
164166 // they have explicit requirements -> no default bounds
165167 vec ! [ ]
166168 }
@@ -185,6 +187,8 @@ impl MacroInput {
185187 match param {
186188 GenericParam :: Type ( ref tp) => {
187189 let type_name = & tp. ident ;
190+ let mut bounds = tp. bounds . clone ( ) ;
191+ bounds. extend ( default_bounds. iter ( ) . cloned ( ) ) ;
188192 generics. make_where_clause ( )
189193 . predicates . push ( WherePredicate :: Type ( PredicateType {
190194 lifetimes : None ,
@@ -193,19 +197,19 @@ impl MacroInput {
193197 parse_quote ! ( <#type_name as GcRebrand <' new_gc, Id >>:: Branded )
194198 } )
195199 } else {
196- self . options . branded_type . clone ( ) . unwrap_or_else ( || {
200+ self . options . erased_type . clone ( ) . unwrap_or_else ( || {
197201 parse_quote ! ( <#type_name as GcErase <' min, Id >>:: Erased )
198202 } )
199203 } ,
200204 colon_token : Default :: default ( ) ,
201- bounds : default_bounds . iter ( ) . cloned ( ) . collect ( )
205+ bounds : bounds . clone ( ) ,
202206 } ) ) ;
203207 generics. make_where_clause ( )
204208 . predicates . push ( WherePredicate :: Type ( PredicateType {
205209 lifetimes : None ,
206210 bounded_ty : parse_quote ! ( #type_name) ,
207211 colon_token : Default :: default ( ) ,
208- bounds : default_bounds . iter ( ) . cloned ( ) . collect ( )
212+ bounds
209213 } ) )
210214 }
211215 _ => { }
@@ -231,56 +235,6 @@ impl MacroInput {
231235 } else {
232236 quote ! ( GcErase <' min, Id >)
233237 } ;
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- }
284238 fn rewrite_brand_trait (
285239 target : & Type , trait_name : & str , target_params : & HashSet < Ident > ,
286240 target_trait : TokenStream , associated_type : Ident
@@ -307,17 +261,17 @@ impl MacroInput {
307261 _ => None
308262 } ) . collect :: < HashSet < _ > > ( ) ;
309263 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 ( || {
311265 rewrite_brand_trait (
312266 & self . target_type , "GcRebrand" ,
313267 & target_params,
314268 parse_quote ! ( GcRebrand <' new_gc, Id >) ,
315269 parse_quote ! ( Branded )
316270 )
317- } ) ?;
271+ } , Ok ) ?;
318272 quote ! ( type Branded = #branded; )
319273 } 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 ( || {
321275 rewrite_brand_trait (
322276 & self . target_type , "GcErase" ,
323277 & target_params,
@@ -327,11 +281,11 @@ impl MacroInput {
327281 } ) ?;
328282 quote ! ( type Erased = #erased; )
329283 } ;
330- Some ( quote ! {
284+ Ok ( Some ( quote ! {
331285 unsafe impl #impl_generics #target_trait for #target_type #where_clause {
332- const
286+ #associated_type
333287 }
334- } )
288+ } ) )
335289 }
336290}
337291
@@ -585,14 +539,7 @@ fn create_clause_with_default(
585539 } ) )
586540 }
587541 }
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
596543 }
597544 } )
598545}
@@ -739,7 +686,7 @@ impl VisitImpl {
739686 if mutable {
740687 quote ! ( & mut )
741688 } else {
742- quote ! ( )
689+ quote ! ( & )
743690 }
744691 }
745692 } ;
@@ -853,4 +800,71 @@ impl Parse for TraitRequirements {
853800 return Err ( input. error ( "Invalid `TraitRequirement`" ) )
854801 }
855802 }
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