Skip to content

Commit 010d592

Browse files
committed
Respect explicit where bounds in unsafe_gc_impl!
They should suppress the generation of implicit where bounds
1 parent c368860 commit 010d592

File tree

1 file changed

+52
-30
lines changed

1 file changed

+52
-30
lines changed

libs/derive/src/macros.rs

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use std::collections::HashSet;
88

9-
use proc_macro2::{Ident, TokenStream, TokenTree};
9+
use proc_macro2::{Ident, TokenStream, TokenTree, Span};
1010
use syn::{
1111
GenericParam, WhereClause, Type, Expr, Error, Token, braced, bracketed,
1212
Generics, TypeParamBound, WherePredicate, PredicateType, parse_quote,
@@ -166,10 +166,6 @@ impl MacroInput {
166166
fn expand_brand_impl(&self, rebrand: bool /* true => rebrand, false => erase */) -> Result<Option<TokenStream>, Error> {
167167
let zerogc_crate = zerogc_crate();
168168
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-
}
173169
let target_type = &self.target_type;
174170
let mut generics = self.basic_generics();
175171
let id_type: Type = match self.options.collector_id {
@@ -179,23 +175,26 @@ impl MacroInput {
179175
parse_quote!(Id)
180176
}
181177
};
182-
let default_bounds: Vec<TypeParamBound> = match requirements {
178+
179+
let (generate_implicit, default_bounds): (bool, Vec<TypeParamBound>) = match requirements {
183180
Some(TraitRequirements::Where(ref explicit_requirements)) => {
184181
generics.make_where_clause().predicates
185182
.extend(explicit_requirements.predicates.iter().cloned());
186183
// they have explicit requirements -> no default bounds
187-
vec![]
184+
(false, vec![])
188185
}
189186
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
191191
},
192-
Some(TraitRequirements::Never) => unreachable!(),
193192
None => {
194-
if rebrand {
193+
(true, if rebrand {
195194
vec![parse_quote!(#zerogc_crate::GcRebrand<'new_gc, #id_type>)]
196195
} else {
197196
vec![parse_quote!(#zerogc_crate::GcErase<'min, #id_type>)]
198-
}
197+
})
199198
}
200199
};
201200
// generate default bounds
@@ -204,6 +203,7 @@ impl MacroInput {
204203
// no defaults to generate
205204
break
206205
}
206+
if !generate_implicit { break } // skip generating implicit bounds
207207
match param {
208208
GenericParam::Type(ref tp) => {
209209
let type_name = &tp.ident;
@@ -235,14 +235,16 @@ impl MacroInput {
235235
_ => {}
236236
}
237237
}
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+
}
246248
if rebrand {
247249
generics.params.push(parse_quote!('new_gc));
248250
} else {
@@ -510,18 +512,33 @@ pub struct CustomBounds {
510512
}
511513
impl CustomBounds {
512514
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+
}
518528
}
519529
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+
}
525542
}
526543
fn gcsafe_clause(&self, generic_params: &[GenericParam]) -> Option<WhereClause> {
527544
let zerogc_crate = zerogc_crate();
@@ -738,7 +755,12 @@ impl VisitImpl {
738755
Ok(if mutable {
739756
mutable_impl.clone()
740757
} 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+
})?
742764
})
743765
}
744766
}

0 commit comments

Comments
 (0)