@@ -165,10 +165,16 @@ fn newtype_inner(data: &syn::Data) -> Option<syn::Type> {
165
165
pub fn from_primitive ( input : TokenStream ) -> TokenStream {
166
166
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
167
167
let name = & ast. ident ;
168
+ let ( impl_, type_, where_) = & ast. generics . split_for_impl ( ) ;
168
169
169
170
let impl_ = if let Some ( inner_ty) = newtype_inner ( & ast. data ) {
171
+ let bound = quote ! { #inner_ty: _num_traits:: FromPrimitive } ;
172
+ let where_ = match where_ {
173
+ Some ( where_) => quote ! { #where_, #bound } ,
174
+ None => quote ! { where #bound } ,
175
+ } ;
170
176
quote ! {
171
- impl _num_traits:: FromPrimitive for #name {
177
+ impl #impl_ _num_traits:: FromPrimitive for #name #type_ #where_ {
172
178
fn from_i64( n: i64 ) -> Option <Self > {
173
179
<#inner_ty as _num_traits:: FromPrimitive >:: from_i64( n) . map( #name)
174
180
}
@@ -251,7 +257,7 @@ pub fn from_primitive(input: TokenStream) -> TokenStream {
251
257
} ;
252
258
253
259
quote ! {
254
- impl _num_traits:: FromPrimitive for #name {
260
+ impl #impl_ _num_traits:: FromPrimitive for #name #type_ #where_ {
255
261
#[ allow( trivial_numeric_casts) ]
256
262
fn from_i64( #from_i64_var: i64 ) -> Option <Self > {
257
263
#( #clauses else) * {
@@ -321,10 +327,16 @@ pub fn from_primitive(input: TokenStream) -> TokenStream {
321
327
pub fn to_primitive ( input : TokenStream ) -> TokenStream {
322
328
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
323
329
let name = & ast. ident ;
330
+ let ( impl_, type_, where_) = & ast. generics . split_for_impl ( ) ;
324
331
325
332
let impl_ = if let Some ( inner_ty) = newtype_inner ( & ast. data ) {
333
+ let bound = quote ! { #inner_ty: _num_traits:: ToPrimitive } ;
334
+ let where_ = match where_ {
335
+ Some ( where_) => quote ! { #where_, #bound } ,
336
+ None => quote ! { where #bound } ,
337
+ } ;
326
338
quote ! {
327
- impl _num_traits:: ToPrimitive for #name {
339
+ impl #impl_ _num_traits:: ToPrimitive for #name #type_ #where_ {
328
340
fn to_i64( & self ) -> Option <i64 > {
329
341
<#inner_ty as _num_traits:: ToPrimitive >:: to_i64( & self . 0 )
330
342
}
@@ -410,7 +422,7 @@ pub fn to_primitive(input: TokenStream) -> TokenStream {
410
422
} ;
411
423
412
424
quote ! {
413
- impl _num_traits:: ToPrimitive for #name {
425
+ impl #impl_ _num_traits:: ToPrimitive for #name #type_ #where_ {
414
426
#[ allow( trivial_numeric_casts) ]
415
427
fn to_i64( & self ) -> Option <i64 > {
416
428
#match_expr
@@ -440,36 +452,41 @@ const NEWTYPE_ONLY: &str = "This trait can only be derived for newtypes";
440
452
pub fn num_ops ( input : TokenStream ) -> TokenStream {
441
453
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
442
454
let name = & ast. ident ;
455
+ let ( impl_, type_, where_) = & ast. generics . split_for_impl ( ) ;
443
456
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
457
+ let where_ = match where_ {
458
+ Some ( where_) => quote ! { #where_, } ,
459
+ None => quote ! { where } ,
460
+ } ;
444
461
dummy_const_trick (
445
462
"NumOps" ,
446
463
& name,
447
464
quote ! {
448
- impl :: std:: ops:: Add for #name {
465
+ impl #impl_ :: std:: ops:: Add for #name #type_ #where_ #inner_ty : :: std :: ops :: Add < Output = #inner_ty> {
449
466
type Output = Self ;
450
467
fn add( self , other: Self ) -> Self {
451
468
#name( <#inner_ty as :: std:: ops:: Add >:: add( self . 0 , other. 0 ) )
452
469
}
453
470
}
454
- impl :: std:: ops:: Sub for #name {
471
+ impl #impl_ :: std:: ops:: Sub for #name #type_ #where_ #inner_ty : :: std :: ops :: Sub < Output = #inner_ty> {
455
472
type Output = Self ;
456
473
fn sub( self , other: Self ) -> Self {
457
474
#name( <#inner_ty as :: std:: ops:: Sub >:: sub( self . 0 , other. 0 ) )
458
475
}
459
476
}
460
- impl :: std:: ops:: Mul for #name {
477
+ impl #impl_ :: std:: ops:: Mul for #name #type_ #where_ #inner_ty : :: std :: ops :: Mul < Output = #inner_ty> {
461
478
type Output = Self ;
462
479
fn mul( self , other: Self ) -> Self {
463
480
#name( <#inner_ty as :: std:: ops:: Mul >:: mul( self . 0 , other. 0 ) )
464
481
}
465
482
}
466
- impl :: std:: ops:: Div for #name {
483
+ impl #impl_ :: std:: ops:: Div for #name #type_ #where_ #inner_ty : :: std :: ops :: Div < Output = #inner_ty> {
467
484
type Output = Self ;
468
485
fn div( self , other: Self ) -> Self {
469
486
#name( <#inner_ty as :: std:: ops:: Div >:: div( self . 0 , other. 0 ) )
470
487
}
471
488
}
472
- impl :: std:: ops:: Rem for #name {
489
+ impl #impl_ :: std:: ops:: Rem for #name #type_ #where_ #inner_ty : :: std :: ops :: Rem < Output = #inner_ty> {
473
490
type Output = Self ;
474
491
fn rem( self , other: Self ) -> Self {
475
492
#name( <#inner_ty as :: std:: ops:: Rem >:: rem( self . 0 , other. 0 ) )
@@ -488,13 +505,20 @@ pub fn num_ops(input: TokenStream) -> TokenStream {
488
505
pub fn num_cast ( input : TokenStream ) -> TokenStream {
489
506
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
490
507
let name = & ast. ident ;
508
+ let ( impl_, type_, where_) = & ast. generics . split_for_impl ( ) ;
491
509
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
510
+ let where_ = match where_ {
511
+ Some ( where_) => quote ! { #where_, } ,
512
+ None => quote ! { where } ,
513
+ } ;
514
+ let fn_param = proc_macro2:: Ident :: new ( "FROM_T" , name. span ( ) ) ;
492
515
dummy_const_trick (
493
516
"NumCast" ,
494
517
& name,
495
518
quote ! {
496
- impl _num_traits:: NumCast for #name {
497
- fn from<T : _num_traits:: ToPrimitive >( n: T ) -> Option <Self > {
519
+ impl #impl_ _num_traits:: NumCast for #name #type_ #where_ #inner_ty: _num_traits:: NumCast {
520
+ #[ allow( non_camel_case_types) ]
521
+ fn from<#fn_param: _num_traits:: ToPrimitive >( n: #fn_param) -> Option <Self > {
498
522
<#inner_ty as _num_traits:: NumCast >:: from( n) . map( #name)
499
523
}
500
524
}
@@ -510,12 +534,17 @@ pub fn num_cast(input: TokenStream) -> TokenStream {
510
534
pub fn zero ( input : TokenStream ) -> TokenStream {
511
535
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
512
536
let name = & ast. ident ;
537
+ let ( impl_, type_, where_) = & ast. generics . split_for_impl ( ) ;
513
538
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
539
+ let where_ = match where_ {
540
+ Some ( where_) => quote ! { #where_, } ,
541
+ None => quote ! { where } ,
542
+ } ;
514
543
dummy_const_trick (
515
544
"Zero" ,
516
545
& name,
517
546
quote ! {
518
- impl _num_traits:: Zero for #name {
547
+ impl #impl_ _num_traits:: Zero for #name #type_ #where_ #inner_ty : _num_traits :: Zero {
519
548
fn zero( ) -> Self {
520
549
#name( <#inner_ty as _num_traits:: Zero >:: zero( ) )
521
550
}
@@ -535,12 +564,17 @@ pub fn zero(input: TokenStream) -> TokenStream {
535
564
pub fn one ( input : TokenStream ) -> TokenStream {
536
565
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
537
566
let name = & ast. ident ;
567
+ let ( impl_, type_, where_) = & ast. generics . split_for_impl ( ) ;
538
568
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
569
+ let where_ = match where_ {
570
+ Some ( where_) => quote ! { #where_, } ,
571
+ None => quote ! { where } ,
572
+ } ;
539
573
dummy_const_trick (
540
574
"One" ,
541
575
& name,
542
576
quote ! {
543
- impl _num_traits:: One for #name {
577
+ impl #impl_ _num_traits:: One for #name #type_ #where_ #inner_ty : _num_traits :: One + PartialEq {
544
578
fn one( ) -> Self {
545
579
#name( <#inner_ty as _num_traits:: One >:: one( ) )
546
580
}
@@ -560,12 +594,17 @@ pub fn one(input: TokenStream) -> TokenStream {
560
594
pub fn num ( input : TokenStream ) -> TokenStream {
561
595
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
562
596
let name = & ast. ident ;
597
+ let ( impl_, type_, where_) = & ast. generics . split_for_impl ( ) ;
563
598
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
599
+ let where_ = match where_ {
600
+ Some ( where_) => quote ! { #where_, } ,
601
+ None => quote ! { where } ,
602
+ } ;
564
603
dummy_const_trick (
565
604
"Num" ,
566
605
& name,
567
606
quote ! {
568
- impl _num_traits:: Num for #name {
607
+ impl #impl_ _num_traits:: Num for #name #type_ #where_ #inner_ty : _num_traits :: Num {
569
608
type FromStrRadixErr = <#inner_ty as _num_traits:: Num >:: FromStrRadixErr ;
570
609
fn from_str_radix( s: & str , radix: u32 ) -> Result <Self , Self :: FromStrRadixErr > {
571
610
<#inner_ty as _num_traits:: Num >:: from_str_radix( s, radix) . map( #name)
@@ -584,12 +623,17 @@ pub fn num(input: TokenStream) -> TokenStream {
584
623
pub fn float ( input : TokenStream ) -> TokenStream {
585
624
let ast: syn:: DeriveInput = syn:: parse ( input) . unwrap ( ) ;
586
625
let name = & ast. ident ;
626
+ let ( impl_, type_, where_) = & ast. generics . split_for_impl ( ) ;
587
627
let inner_ty = newtype_inner ( & ast. data ) . expect ( NEWTYPE_ONLY ) ;
628
+ let where_ = match where_ {
629
+ Some ( where_) => quote ! { #where_, } ,
630
+ None => quote ! { where } ,
631
+ } ;
588
632
dummy_const_trick (
589
633
"Float" ,
590
634
& name,
591
635
quote ! {
592
- impl _num_traits:: Float for #name {
636
+ impl #impl_ _num_traits:: Float for #name #type_ #where_ #inner_ty : _num_traits :: Float {
593
637
fn nan( ) -> Self {
594
638
#name( <#inner_ty as _num_traits:: Float >:: nan( ) )
595
639
}
0 commit comments