6
6
7
7
use std:: collections:: HashSet ;
8
8
9
- use proc_macro2:: { Ident , TokenStream , TokenTree } ;
9
+ use proc_macro2:: { Ident , TokenStream , TokenTree , Span } ;
10
10
use syn:: {
11
11
GenericParam , WhereClause , Type , Expr , Error , Token , braced, bracketed,
12
12
Generics , TypeParamBound , WherePredicate , PredicateType , parse_quote,
@@ -166,10 +166,6 @@ impl MacroInput {
166
166
fn expand_brand_impl ( & self , rebrand : bool /* true => rebrand, false => erase */ ) -> Result < Option < TokenStream > , Error > {
167
167
let zerogc_crate = zerogc_crate ( ) ;
168
168
let requirements = if rebrand { self . bounds . rebrand . clone ( ) } else { self . bounds . erase . clone ( ) } ;
169
- if let Some ( TraitRequirements :: Never ) = requirements {
170
- // They are requesting that we dont implement
171
- return Ok ( None ) ;
172
- }
173
169
let target_type = & self . target_type ;
174
170
let mut generics = self . basic_generics ( ) ;
175
171
let id_type: Type = match self . options . collector_id {
@@ -179,23 +175,26 @@ impl MacroInput {
179
175
parse_quote ! ( Id )
180
176
}
181
177
} ;
182
- let default_bounds: Vec < TypeParamBound > = match requirements {
178
+
179
+ let ( generate_implicit, default_bounds) : ( bool , Vec < TypeParamBound > ) = match requirements {
183
180
Some ( TraitRequirements :: Where ( ref explicit_requirements) ) => {
184
181
generics. make_where_clause ( ) . predicates
185
182
. extend ( explicit_requirements. predicates . iter ( ) . cloned ( ) ) ;
186
183
// they have explicit requirements -> no default bounds
187
- vec ! [ ]
184
+ ( false , vec ! [ ] )
188
185
}
189
186
Some ( TraitRequirements :: Always ) => {
190
- vec ! [ ] // always should implement
187
+ ( false , vec ! [ ] ) // always should implement (even without implicit bounds)
188
+ } ,
189
+ Some ( TraitRequirements :: Never ) => {
190
+ return Ok ( None ) ; // They are requesting we dont implement it at all
191
191
} ,
192
- Some ( TraitRequirements :: Never ) => unreachable ! ( ) ,
193
192
None => {
194
- if rebrand {
193
+ ( true , if rebrand {
195
194
vec ! [ parse_quote!( #zerogc_crate:: GcRebrand <' new_gc, #id_type>) ]
196
195
} else {
197
196
vec ! [ parse_quote!( #zerogc_crate:: GcErase <' min, #id_type>) ]
198
- }
197
+ } )
199
198
}
200
199
} ;
201
200
// generate default bounds
@@ -204,6 +203,7 @@ impl MacroInput {
204
203
// no defaults to generate
205
204
break
206
205
}
206
+ if !generate_implicit { break } // skip generating implicit bounds
207
207
match param {
208
208
GenericParam :: Type ( ref tp) => {
209
209
let type_name = & tp. ident ;
@@ -235,14 +235,16 @@ impl MacroInput {
235
235
_ => { }
236
236
}
237
237
}
238
- /*
239
- * If we don't have explicit specification,
240
- * extend the with the trace clauses
241
- *
242
- * TODO: Do we need to apply to the `Branded`/`Erased` types
243
- */
244
- generics. make_where_clause ( ) . predicates
245
- . extend ( self . bounds . trace_where_clause ( & self . params ) . predicates ) ;
238
+ if generate_implicit {
239
+ /*
240
+ * If we don't have explicit specification,
241
+ * extend the with the trace clauses
242
+ *
243
+ * TODO: Do we need to apply to the `Branded`/`Erased` types
244
+ */
245
+ generics. make_where_clause ( ) . predicates
246
+ . extend ( self . bounds . trace_where_clause ( & self . params ) . predicates ) ;
247
+ }
246
248
if rebrand {
247
249
generics. params . push ( parse_quote ! ( ' new_gc) ) ;
248
250
} else {
@@ -510,18 +512,33 @@ pub struct CustomBounds {
510
512
}
511
513
impl CustomBounds {
512
514
fn trace_where_clause ( & self , generic_params : & [ GenericParam ] ) -> WhereClause {
513
- let zerogc_crate = zerogc_crate ( ) ;
514
- create_clause_with_default (
515
- & self . trace , generic_params,
516
- vec ! [ parse_quote!( #zerogc_crate:: Trace ) ]
517
- ) . unwrap_or_else ( || unreachable ! ( "Trace must always be implemented" ) )
515
+ match self . trace {
516
+ Some ( TraitRequirements :: Never ) => unreachable ! ( "Trace must always be implemented" ) ,
517
+ Some ( TraitRequirements :: Always ) => empty_clause ( ) , // No requirements
518
+ Some ( TraitRequirements :: Where ( ref explicit) ) => explicit. clone ( ) ,
519
+ None => {
520
+ // generate the implicit requiremnents
521
+ let zerogc_crate = zerogc_crate ( ) ;
522
+ create_clause_with_default (
523
+ & self . trace , generic_params,
524
+ vec ! [ parse_quote!( #zerogc_crate:: Trace ) ]
525
+ ) . unwrap_or_else ( || unreachable ! ( "Trace must always be implemented" ) )
526
+ }
527
+ }
518
528
}
519
529
fn trace_immutable_clause ( & self , generic_params : & [ GenericParam ] ) -> Option < WhereClause > {
520
- let zerogc_crate = zerogc_crate ( ) ;
521
- create_clause_with_default (
522
- & self . trace_immutable , generic_params,
523
- vec ! [ parse_quote!( #zerogc_crate:: TraceImmutable ) ]
524
- )
530
+ match self . trace_immutable {
531
+ Some ( TraitRequirements :: Never ) => None , // skip this impl
532
+ Some ( TraitRequirements :: Always ) => Some ( empty_clause ( ) ) , // No requirements
533
+ Some ( TraitRequirements :: Where ( ref explicit) ) => Some ( explicit. clone ( ) ) ,
534
+ None => {
535
+ let zerogc_crate = zerogc_crate ( ) ;
536
+ create_clause_with_default (
537
+ & self . trace_immutable , generic_params,
538
+ vec ! [ parse_quote!( #zerogc_crate:: TraceImmutable ) ]
539
+ )
540
+ }
541
+ }
525
542
}
526
543
fn gcsafe_clause ( & self , generic_params : & [ GenericParam ] ) -> Option < WhereClause > {
527
544
let zerogc_crate = zerogc_crate ( ) ;
@@ -738,7 +755,12 @@ impl VisitImpl {
738
755
Ok ( if mutable {
739
756
mutable_impl. clone ( )
740
757
} else {
741
- immutable. clone ( ) . unwrap ( )
758
+ immutable. clone ( ) . ok_or_else ( || {
759
+ Error :: new (
760
+ Span :: call_site ( ) ,
761
+ "Expected a trace_immutable closure"
762
+ )
763
+ } ) ?
742
764
} )
743
765
}
744
766
}
0 commit comments