Skip to content

Commit

Permalink
Fix handling of where clauses
Browse files Browse the repository at this point in the history
  • Loading branch information
alexanderlinne authored and althonos committed Oct 13, 2020
1 parent 5997fb5 commit ef57d14
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 4 deletions.
3 changes: 2 additions & 1 deletion src/derive/box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub fn derive(trait_: &syn::ItemTrait) -> syn::Result<syn::ItemImpl> {
// a generic type that implements the trait for which we provide the
// blanket implementation
let trait_generics = &trait_.generics;
let where_clause = &trait_.generics.where_clause;
let mut impl_generics = trait_generics.clone();
impl_generics.params.push(syn::GenericParam::Type(
parse_quote!(#generic_type: #trait_ident #trait_generics),
Expand All @@ -53,7 +54,7 @@ pub fn derive(trait_: &syn::ItemTrait) -> syn::Result<syn::ItemImpl> {
// generate the impl block
Ok(parse_quote!(
#[automatically_derived]
impl #impl_generics #trait_ident #trait_generics for Box<#generic_type> {
impl #impl_generics #trait_ident #trait_generics for Box<#generic_type> #where_clause {
#(#methods)*
}
))
Expand Down
3 changes: 2 additions & 1 deletion src/derive/mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ pub fn derive(trait_: &syn::ItemTrait) -> syn::Result<syn::ItemImpl> {
// a generic type that implements the trait for which we provide the
// blanket implementation
let trait_generics = &trait_.generics;
let where_clause = &trait_.generics.where_clause;
let mut impl_generics = trait_generics.clone();
impl_generics.params.push(syn::GenericParam::Type(
parse_quote!(#generic_type: #trait_ident #trait_generics + ?Sized),
));

Ok(parse_quote!(
#[automatically_derived]
impl #impl_generics #trait_ident #trait_generics for &mut #generic_type {
impl #impl_generics #trait_ident #trait_generics for &mut #generic_type #where_clause {
#(#methods)*
}
))
Expand Down
3 changes: 2 additions & 1 deletion src/derive/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ pub fn derive(trait_: &syn::ItemTrait) -> syn::Result<syn::ItemImpl> {
// a generic type that implements the trait for which we provide the
// blanket implementation
let trait_generics = &trait_.generics;
let where_clause = &trait_.generics.where_clause;
let mut impl_generics = trait_generics.clone();
impl_generics.params.push(syn::GenericParam::Type(
parse_quote!(#generic_type: #trait_ident #trait_generics + ?Sized),
));

Ok(parse_quote!(
#[automatically_derived]
impl #impl_generics #trait_ident #trait_generics for std::rc::Rc<#generic_type> {
impl #impl_generics #trait_ident #trait_generics for std::rc::Rc<#generic_type> #where_clause {
#(#methods)*
}
))
Expand Down
3 changes: 2 additions & 1 deletion src/derive/ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ pub fn derive(trait_: &syn::ItemTrait) -> syn::Result<syn::ItemImpl> {
// a generic type that implements the trait for which we provide the
// blanket implementation
let trait_generics = &trait_.generics;
let where_clause = &trait_.generics.where_clause;
let mut impl_generics = trait_generics.clone();
impl_generics.params.push(syn::GenericParam::Type(
parse_quote!(#generic_type: #trait_ident #trait_generics + ?Sized),
));

Ok(parse_quote!(
#[automatically_derived]
impl #impl_generics #trait_ident #trait_generics for &#generic_type {
impl #impl_generics #trait_ident #trait_generics for &#generic_type #where_clause {
#(#methods)*
}
))
Expand Down
36 changes: 36 additions & 0 deletions tests/derive_box/successes/where_clause_assoc_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
extern crate blanket;
extern crate impls;

use std::sync::atomic::AtomicU8;
use std::sync::atomic::Ordering;

use blanket::blanket;
use impls::impls;

#[blanket(derive(Box))]
pub trait Counter<T>
where
T: Clone,
{
fn increment(&self, t: T);

fn super_helpful_helper(&self, t: T)
{
self.increment(t.clone())
}
}

struct AtomicCounter {
count: AtomicU8,
}

impl Counter<u8> for AtomicCounter {
fn increment(&self, value: u8) {
self.count.fetch_add(value, Ordering::SeqCst);
}
}

fn main() {
assert!(impls!(AtomicCounter: Counter<u8>));
assert!(impls!(Box<AtomicCounter>: Counter<u8>));
}
36 changes: 36 additions & 0 deletions tests/derive_mut/successes/where_clause_assoc_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
extern crate blanket;
extern crate impls;

use std::sync::atomic::AtomicU8;
use std::sync::atomic::Ordering;

use blanket::blanket;
use impls::impls;

#[blanket(derive(Mut))]
pub trait Counter<T>
where
T: Clone,
{
fn increment(&self, t: T);

fn super_helpful_helper(&self, t: T)
{
self.increment(t.clone())
}
}

struct AtomicCounter {
count: AtomicU8,
}

impl Counter<u8> for AtomicCounter {
fn increment(&self, value: u8) {
self.count.fetch_add(value, Ordering::SeqCst);
}
}

fn main() {
assert!(impls!(AtomicCounter: Counter<u8>));
assert!(impls!(&mut AtomicCounter: Counter<u8>));
}
37 changes: 37 additions & 0 deletions tests/derive_rc/successes/where_clause_assoc_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
extern crate blanket;
extern crate impls;

use std::rc::Rc;
use std::sync::atomic::AtomicU8;
use std::sync::atomic::Ordering;

use blanket::blanket;
use impls::impls;

#[blanket(derive(Rc))]
pub trait Counter<T>
where
T: Clone,
{
fn increment(&self, t: T);

fn super_helpful_helper(&self, t: T)
{
self.increment(t.clone())
}
}

struct AtomicCounter {
count: AtomicU8,
}

impl Counter<u8> for AtomicCounter {
fn increment(&self, value: u8) {
self.count.fetch_add(value, Ordering::SeqCst);
}
}

fn main() {
assert!(impls!(AtomicCounter: Counter<u8>));
assert!(impls!(Rc<AtomicCounter>: Counter<u8>));
}
36 changes: 36 additions & 0 deletions tests/derive_ref/successes/where_clause_assoc_fn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
extern crate blanket;
extern crate impls;

use std::sync::atomic::AtomicU8;
use std::sync::atomic::Ordering;

use blanket::blanket;
use impls::impls;

#[blanket(derive(Ref))]
pub trait Counter<T>
where
T: Clone,
{
fn increment(&self, t: T);

fn super_helpful_helper(&self, t: T)
{
self.increment(t.clone())
}
}

struct AtomicCounter {
count: AtomicU8,
}

impl Counter<u8> for AtomicCounter {
fn increment(&self, value: u8) {
self.count.fetch_add(value, Ordering::SeqCst);
}
}

fn main() {
assert!(impls!(AtomicCounter: Counter<u8>));
assert!(impls!(&AtomicCounter: Counter<u8>));
}

0 comments on commit ef57d14

Please sign in to comment.