mirror of
https://github.com/servo/servo.git
synced 2025-07-18 21:03:45 +01:00
style: When deriving something with an output type, map preconditions as well.
Otherwise, deriving ToComputedValue and ToAnimatedValue in structs or enums with other where clauses just doesn't work. Differential Revision: https://phabricator.services.mozilla.com/D21859
This commit is contained in:
parent
35b8b95263
commit
9b24a451f6
3 changed files with 76 additions and 0 deletions
|
@ -12,6 +12,70 @@ use syn::{TypeParam, TypeParen, TypePath, TypeSlice, TypeTuple};
|
||||||
use syn::{Variant, WherePredicate};
|
use syn::{Variant, WherePredicate};
|
||||||
use synstructure::{self, BindStyle, BindingInfo, VariantAst, VariantInfo};
|
use synstructure::{self, BindStyle, BindingInfo, VariantAst, VariantInfo};
|
||||||
|
|
||||||
|
/// Given an input type which has some where clauses already, like:
|
||||||
|
///
|
||||||
|
/// struct InputType<T>
|
||||||
|
/// where
|
||||||
|
/// T: Zero,
|
||||||
|
/// {
|
||||||
|
/// ...
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Add the necessary `where` clauses so that the output type of a trait
|
||||||
|
/// fulfils them.
|
||||||
|
///
|
||||||
|
/// For example:
|
||||||
|
///
|
||||||
|
/// <T as ToComputedValue>::ComputedValue: Zero,
|
||||||
|
///
|
||||||
|
/// This needs to run before adding other bounds to the type parameters.
|
||||||
|
pub fn propagate_clauses_to_output_type(
|
||||||
|
where_clause: &mut Option<syn::WhereClause>,
|
||||||
|
generics: &syn::Generics,
|
||||||
|
trait_path: Path,
|
||||||
|
trait_output: Ident,
|
||||||
|
) {
|
||||||
|
let where_clause = match *where_clause {
|
||||||
|
Some(ref mut clause) => clause,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
let mut extra_bounds = vec![];
|
||||||
|
for pred in &where_clause.predicates {
|
||||||
|
let ty = match *pred {
|
||||||
|
syn::WherePredicate::Type(ref ty) => ty,
|
||||||
|
ref predicate => panic!("Unhanded complex where predicate: {:?}", predicate),
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = match ty.bounded_ty {
|
||||||
|
syn::Type::Path(ref p) => &p.path,
|
||||||
|
ref ty => panic!("Unhanded complex where type: {:?}", ty),
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
ty.lifetimes.is_none(),
|
||||||
|
"Unhanded complex lifetime bound: {:?}",
|
||||||
|
ty,
|
||||||
|
);
|
||||||
|
|
||||||
|
let ident = match path_to_ident(path) {
|
||||||
|
Some(i) => i,
|
||||||
|
None => panic!("Unhanded complex where type path: {:?}", path),
|
||||||
|
};
|
||||||
|
|
||||||
|
if generics.type_params().any(|param| param.ident == *ident) {
|
||||||
|
extra_bounds.push(ty.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for bound in extra_bounds {
|
||||||
|
let ty = bound.bounded_ty;
|
||||||
|
let bounds = bound.bounds;
|
||||||
|
where_clause.predicates.push(
|
||||||
|
parse_quote!(<#ty as #trait_path>::#trait_output: #bounds),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_predicate(where_clause: &mut Option<syn::WhereClause>, pred: WherePredicate) {
|
pub fn add_predicate(where_clause: &mut Option<syn::WhereClause>, pred: WherePredicate) {
|
||||||
where_clause
|
where_clause
|
||||||
.get_or_insert(parse_quote!(where))
|
.get_or_insert(parse_quote!(where))
|
||||||
|
|
|
@ -9,6 +9,12 @@ use synstructure::BindStyle;
|
||||||
|
|
||||||
pub fn derive(mut input: DeriveInput) -> TokenStream {
|
pub fn derive(mut input: DeriveInput) -> TokenStream {
|
||||||
let mut where_clause = input.generics.where_clause.take();
|
let mut where_clause = input.generics.where_clause.take();
|
||||||
|
cg::propagate_clauses_to_output_type(
|
||||||
|
&mut where_clause,
|
||||||
|
&input.generics,
|
||||||
|
parse_quote!(crate::values::animated::ToAnimatedValue),
|
||||||
|
parse_quote!(AnimatedValue),
|
||||||
|
);
|
||||||
for param in input.generics.type_params() {
|
for param in input.generics.type_params() {
|
||||||
cg::add_predicate(
|
cg::add_predicate(
|
||||||
&mut where_clause,
|
&mut where_clause,
|
||||||
|
|
|
@ -9,6 +9,12 @@ use synstructure::BindStyle;
|
||||||
|
|
||||||
pub fn derive(mut input: DeriveInput) -> TokenStream {
|
pub fn derive(mut input: DeriveInput) -> TokenStream {
|
||||||
let mut where_clause = input.generics.where_clause.take();
|
let mut where_clause = input.generics.where_clause.take();
|
||||||
|
cg::propagate_clauses_to_output_type(
|
||||||
|
&mut where_clause,
|
||||||
|
&input.generics,
|
||||||
|
parse_quote!(crate::values::computed::ToComputedValue),
|
||||||
|
parse_quote!(ComputedValue),
|
||||||
|
);
|
||||||
let (to_body, from_body) = {
|
let (to_body, from_body) = {
|
||||||
let params = input.generics.type_params().collect::<Vec<_>>();
|
let params = input.generics.type_params().collect::<Vec<_>>();
|
||||||
for param in ¶ms {
|
for param in ¶ms {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue