@@ -232,12 +232,13 @@ impl NumTraits {
232
232
pub fn from_primitive ( input : TokenStream ) -> TokenStream {
233
233
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
234
234
let name = & ast. ident ;
235
+ let ( impl_, type_, where_) = split_for_impl ( & ast. generics ) ;
235
236
236
237
let import = NumTraits :: new ( & ast) ;
237
238
238
239
let impl_ = if let Some ( inner_ty) = newtype_inner ( & ast. data ) {
239
240
quote ! {
240
- impl #import:: FromPrimitive for #name {
241
+ impl #impl_ # import:: FromPrimitive for #name #type_ #where_ #inner_ty : #import :: FromPrimitive {
241
242
fn from_i64( n: i64 ) -> Option <Self > {
242
243
<#inner_ty as #import:: FromPrimitive >:: from_i64( n) . map( #name)
243
244
}
@@ -320,7 +321,7 @@ pub fn from_primitive(input: TokenStream) -> TokenStream {
320
321
} ;
321
322
322
323
quote ! {
323
- impl #import:: FromPrimitive for #name {
324
+ impl #impl_ # import:: FromPrimitive for #name #type_ #where_ {
324
325
#[ allow( trivial_numeric_casts) ]
325
326
fn from_i64( #from_i64_var: i64 ) -> Option <Self > {
326
327
#( #clauses else) * {
@@ -390,12 +391,13 @@ pub fn from_primitive(input: TokenStream) -> TokenStream {
390
391
pub fn to_primitive ( input : TokenStream ) -> TokenStream {
391
392
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
392
393
let name = & ast. ident ;
394
+ let ( impl_, type_, where_) = split_for_impl ( & ast. generics ) ;
393
395
394
396
let import = NumTraits :: new ( & ast) ;
395
397
396
398
let impl_ = if let Some ( inner_ty) = newtype_inner ( & ast. data ) {
397
399
quote ! {
398
- impl #import:: ToPrimitive for #name {
400
+ impl #impl_ # import:: ToPrimitive for #name #type_ #where_ #inner_ty : #import :: ToPrimitive {
399
401
fn to_i64( & self ) -> Option <i64 > {
400
402
<#inner_ty as #import:: ToPrimitive >:: to_i64( & self . 0 )
401
403
}
@@ -481,7 +483,7 @@ pub fn to_primitive(input: TokenStream) -> TokenStream {
481
483
} ;
482
484
483
485
quote ! {
484
- impl #import:: ToPrimitive for #name {
486
+ impl #impl_ # import:: ToPrimitive for #name #type_ #where_ {
485
487
#[ allow( trivial_numeric_casts) ]
486
488
fn to_i64( & self ) -> Option <i64 > {
487
489
#match_expr
@@ -511,33 +513,34 @@ const NEWTYPE_ONLY: &str = "This trait can only be derived for newtypes";
511
513
pub fn num_ops ( input : TokenStream ) -> TokenStream {
512
514
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
513
515
let name = & ast. ident ;
516
+ let ( impl_, type_, where_) = split_for_impl ( & ast. generics ) ;
514
517
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
515
518
let impl_ = quote ! {
516
- impl :: std:: ops:: Add for #name {
519
+ impl #impl_ :: std:: ops:: Add for #name #type_ #where_ #inner_ty : :: std :: ops :: Add < Output = #inner_ty> {
517
520
type Output = Self ;
518
521
fn add( self , other: Self ) -> Self {
519
522
#name( <#inner_ty as :: std:: ops:: Add >:: add( self . 0 , other. 0 ) )
520
523
}
521
524
}
522
- impl :: std:: ops:: Sub for #name {
525
+ impl #impl_ :: std:: ops:: Sub for #name #type_ #where_ #inner_ty : :: std :: ops :: Sub < Output = #inner_ty> {
523
526
type Output = Self ;
524
527
fn sub( self , other: Self ) -> Self {
525
528
#name( <#inner_ty as :: std:: ops:: Sub >:: sub( self . 0 , other. 0 ) )
526
529
}
527
530
}
528
- impl :: std:: ops:: Mul for #name {
531
+ impl #impl_ :: std:: ops:: Mul for #name #type_ #where_ #inner_ty : :: std :: ops :: Mul < Output = #inner_ty> {
529
532
type Output = Self ;
530
533
fn mul( self , other: Self ) -> Self {
531
534
#name( <#inner_ty as :: std:: ops:: Mul >:: mul( self . 0 , other. 0 ) )
532
535
}
533
536
}
534
- impl :: std:: ops:: Div for #name {
537
+ impl #impl_ :: std:: ops:: Div for #name #type_ #where_ #inner_ty : :: std :: ops :: Div < Output = #inner_ty> {
535
538
type Output = Self ;
536
539
fn div( self , other: Self ) -> Self {
537
540
#name( <#inner_ty as :: std:: ops:: Div >:: div( self . 0 , other. 0 ) )
538
541
}
539
542
}
540
- impl :: std:: ops:: Rem for #name {
543
+ impl #impl_ :: std:: ops:: Rem for #name #type_ #where_ #inner_ty : :: std :: ops :: Rem < Output = #inner_ty> {
541
544
type Output = Self ;
542
545
fn rem( self , other: Self ) -> Self {
543
546
#name( <#inner_ty as :: std:: ops:: Rem >:: rem( self . 0 , other. 0 ) )
@@ -555,13 +558,16 @@ pub fn num_ops(input: TokenStream) -> TokenStream {
555
558
pub fn num_cast ( input : TokenStream ) -> TokenStream {
556
559
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
557
560
let name = & ast. ident ;
561
+ let ( impl_, type_, where_) = split_for_impl ( & ast. generics ) ;
558
562
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
563
+ let fn_param = proc_macro2:: Ident :: new ( "FROM_T" , name. span ( ) ) ;
559
564
560
565
let import = NumTraits :: new ( & ast) ;
561
566
562
567
let impl_ = quote ! {
563
- impl #import:: NumCast for #name {
564
- fn from<T : #import:: ToPrimitive >( n: T ) -> Option <Self > {
568
+ impl #impl_ #import:: NumCast for #name #type_ #where_ #inner_ty: #import:: NumCast {
569
+ #[ allow( non_camel_case_types) ]
570
+ fn from<#fn_param: #import:: ToPrimitive >( n: #fn_param) -> Option <Self > {
565
571
<#inner_ty as #import:: NumCast >:: from( n) . map( #name)
566
572
}
567
573
}
@@ -577,12 +583,13 @@ pub fn num_cast(input: TokenStream) -> TokenStream {
577
583
pub fn zero ( input : TokenStream ) -> TokenStream {
578
584
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
579
585
let name = & ast. ident ;
586
+ let ( impl_, type_, where_) = split_for_impl ( & ast. generics ) ;
580
587
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
581
588
582
589
let import = NumTraits :: new ( & ast) ;
583
590
584
591
let impl_ = quote ! {
585
- impl #import:: Zero for #name {
592
+ impl #impl_ # import:: Zero for #name #type_ #where_ #inner_ty : #import :: Zero {
586
593
fn zero( ) -> Self {
587
594
#name( <#inner_ty as #import:: Zero >:: zero( ) )
588
595
}
@@ -602,12 +609,13 @@ pub fn zero(input: TokenStream) -> TokenStream {
602
609
pub fn one ( input : TokenStream ) -> TokenStream {
603
610
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
604
611
let name = & ast. ident ;
612
+ let ( impl_, type_, where_) = split_for_impl ( & ast. generics ) ;
605
613
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
606
614
607
615
let import = NumTraits :: new ( & ast) ;
608
616
609
617
let impl_ = quote ! {
610
- impl #import:: One for #name {
618
+ impl #impl_ # import:: One for #name #type_ #where_ #inner_ty : #import :: One + PartialEq {
611
619
fn one( ) -> Self {
612
620
#name( <#inner_ty as #import:: One >:: one( ) )
613
621
}
@@ -620,19 +628,31 @@ pub fn one(input: TokenStream) -> TokenStream {
620
628
import. wrap ( "One" , & name, impl_) . into ( )
621
629
}
622
630
631
+ fn split_for_impl (
632
+ generics : & syn:: Generics ,
633
+ ) -> ( syn:: ImplGenerics , syn:: TypeGenerics , impl quote:: ToTokens ) {
634
+ let ( impl_, type_, where_) = generics. split_for_impl ( ) ;
635
+ let where_ = match where_ {
636
+ Some ( where_) => quote ! { #where_, } ,
637
+ None => quote ! { where } ,
638
+ } ;
639
+ ( impl_, type_, where_)
640
+ }
641
+
623
642
/// Derives [`num_traits::Num`][num] for newtypes. The inner type must already implement `Num`.
624
643
///
625
644
/// [num]: https://docs.rs/num-traits/0.2/num_traits/trait.Num.html
626
645
#[ proc_macro_derive( Num , attributes( num_traits) ) ]
627
646
pub fn num ( input : TokenStream ) -> TokenStream {
628
647
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
629
648
let name = & ast. ident ;
649
+ let ( impl_, type_, where_) = split_for_impl ( & ast. generics ) ;
630
650
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
631
651
632
652
let import = NumTraits :: new ( & ast) ;
633
653
634
654
let impl_ = quote ! {
635
- impl #import:: Num for #name {
655
+ impl #impl_ # import:: Num for #name #type_ #where_ #inner_ty : #import :: Num {
636
656
type FromStrRadixErr = <#inner_ty as #import:: Num >:: FromStrRadixErr ;
637
657
fn from_str_radix( s: & str , radix: u32 ) -> Result <Self , Self :: FromStrRadixErr > {
638
658
<#inner_ty as #import:: Num >:: from_str_radix( s, radix) . map( #name)
@@ -651,12 +671,13 @@ pub fn num(input: TokenStream) -> TokenStream {
651
671
pub fn float ( input : TokenStream ) -> TokenStream {
652
672
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
653
673
let name = & ast. ident ;
674
+ let ( impl_, type_, where_) = split_for_impl ( & ast. generics ) ;
654
675
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
655
676
656
677
let import = NumTraits :: new ( & ast) ;
657
678
658
679
let impl_ = quote ! {
659
- impl #import:: Float for #name {
680
+ impl #impl_ # import:: Float for #name #type_ #where_ #inner_ty : #import :: Float {
660
681
fn nan( ) -> Self {
661
682
#name( <#inner_ty as #import:: Float >:: nan( ) )
662
683
}
0 commit comments