@@ -225,6 +225,11 @@ fn do_write_impl_trait<W: std::io::Write>(w: &mut W, trait_path: &str, _trait_na
225
225
writeln ! ( w, "\t \t let vec = (self.write)(self.this_arg);" ) . unwrap ( ) ;
226
226
writeln ! ( w, "\t \t w.write_all(vec.as_slice())" ) . unwrap ( ) ;
227
227
writeln ! ( w, "\t }}\n }}" ) . unwrap ( ) ;
228
+ writeln ! ( w, "impl {} for {}Ref {{" , trait_path, for_obj) . unwrap ( ) ;
229
+ writeln ! ( w, "\t fn write<W: lightning::util::ser::Writer>(&self, w: &mut W) -> Result<(), crate::c_types::io::Error> {{" ) . unwrap ( ) ;
230
+ writeln ! ( w, "\t \t let vec = (self.0.write)(self.0.this_arg);" ) . unwrap ( ) ;
231
+ writeln ! ( w, "\t \t w.write_all(vec.as_slice())" ) . unwrap ( ) ;
232
+ writeln ! ( w, "\t }}\n }}" ) . unwrap ( ) ;
228
233
} ,
229
234
_ => panic ! ( ) ,
230
235
}
@@ -450,6 +455,47 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
450
455
( $t: expr, $impl_accessor: expr, $type_resolver: expr, $generic_impls: expr) => {
451
456
let mut trait_gen_types = gen_types. push_ctx( ) ;
452
457
assert!( trait_gen_types. learn_generics_with_impls( & $t. generics, $generic_impls, $type_resolver) ) ;
458
+
459
+ let mut ref_types = HashSet :: new( ) ;
460
+ for item in $t. items. iter( ) {
461
+ if let syn:: TraitItem :: Type ( ref t) = & item {
462
+ if t. default . is_some( ) || t. generics. lt_token. is_some( ) { panic!( "10" ) ; }
463
+ let mut bounds_iter = t. bounds. iter( ) ;
464
+ loop {
465
+ match bounds_iter. next( ) . unwrap( ) {
466
+ syn:: TypeParamBound :: Trait ( tr) => {
467
+ match $type_resolver. resolve_path( & tr. path, None ) . as_str( ) {
468
+ "core::ops::Deref" |"core::ops::DerefMut" |"std::ops::Deref" |"std::ops::DerefMut" => {
469
+ // Handle cases like
470
+ // trait A {
471
+ // type B;
472
+ // type C: Deref<Target = Self::B>;
473
+ // }
474
+ // by tracking if we have any B's here and making them
475
+ // the *Ref types below.
476
+ if let syn:: PathArguments :: AngleBracketed ( args) = & tr. path. segments. iter( ) . last( ) . unwrap( ) . arguments {
477
+ if let syn:: GenericArgument :: Binding ( bind) = args. args. iter( ) . last( ) . unwrap( ) {
478
+ assert_eq!( format!( "{}" , bind. ident) , "Target" ) ;
479
+ if let syn:: Type :: Path ( p) = & bind. ty {
480
+ assert!( p. qself. is_none( ) ) ;
481
+ let mut segs = p. path. segments. iter( ) ;
482
+ assert_eq!( format!( "{}" , segs. next( ) . unwrap( ) . ident) , "Self" ) ;
483
+ ref_types. insert( format!( "{}" , segs. next( ) . unwrap( ) . ident) ) ;
484
+ assert!( segs. next( ) . is_none( ) ) ;
485
+ } else { panic!( ) ; }
486
+ }
487
+ }
488
+ } ,
489
+ _ => { } ,
490
+ }
491
+ break ;
492
+ }
493
+ syn:: TypeParamBound :: Lifetime ( _) => { } ,
494
+ }
495
+ }
496
+ }
497
+ }
498
+
453
499
for item in $t. items. iter( ) {
454
500
match item {
455
501
syn:: TraitItem :: Method ( m) => {
@@ -538,7 +584,11 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
538
584
loop {
539
585
match bounds_iter. next( ) . unwrap( ) {
540
586
syn:: TypeParamBound :: Trait ( tr) => {
541
- writeln!( w, "\t type {} = crate::{};" , t. ident, $type_resolver. resolve_path( & tr. path, Some ( & gen_types) ) ) . unwrap( ) ;
587
+ write!( w, "\t type {} = crate::{}" , t. ident, $type_resolver. resolve_path( & tr. path, Some ( & gen_types) ) ) . unwrap( ) ;
588
+ if ref_types. contains( & format!( "{}" , t. ident) ) {
589
+ write!( w, "Ref" ) . unwrap( ) ;
590
+ }
591
+ writeln!( w, ";" ) . unwrap( ) ;
542
592
for bound in bounds_iter {
543
593
if let syn:: TypeParamBound :: Trait ( t) = bound {
544
594
// We only allow for `Sized` here.
@@ -581,10 +631,15 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
581
631
writeln!( w, "impl core::cmp::Eq for {} {{}}" , trait_name) . unwrap( ) ;
582
632
writeln!( w, "impl core::cmp::PartialEq for {} {{" , trait_name) . unwrap( ) ;
583
633
writeln!( w, "\t fn eq(&self, o: &Self) -> bool {{ (self.eq)(self.this_arg, o) }}\n }}" ) . unwrap( ) ;
634
+ writeln!( w, "impl core::cmp::Eq for {}Ref {{}}" , trait_name) . unwrap( ) ;
635
+ writeln!( w, "impl core::cmp::PartialEq for {}Ref {{" , trait_name) . unwrap( ) ;
636
+ writeln!( w, "\t fn eq(&self, o: &Self) -> bool {{ (self.0.eq)(self.0.this_arg, &o.0) }}\n }}" ) . unwrap( ) ;
584
637
} ,
585
638
( "std::hash::Hash" , _, _) |( "core::hash::Hash" , _, _) => {
586
639
writeln!( w, "impl core::hash::Hash for {} {{" , trait_name) . unwrap( ) ;
587
640
writeln!( w, "\t fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) {{ hasher.write_u64((self.hash)(self.this_arg)) }}\n }}" ) . unwrap( ) ;
641
+ writeln!( w, "impl core::hash::Hash for {}Ref {{" , trait_name) . unwrap( ) ;
642
+ writeln!( w, "\t fn hash<H: core::hash::Hasher>(&self, hasher: &mut H) {{ hasher.write_u64((self.0.hash)(self.0.this_arg)) }}\n }}" ) . unwrap( ) ;
588
643
} ,
589
644
( "Send" , _, _) => { } , ( "Sync" , _, _) => { } ,
590
645
( "Clone" , _, _) => {
@@ -598,13 +653,22 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
598
653
writeln!( w, "\t fn clone(&self) -> Self {{" ) . unwrap( ) ;
599
654
writeln!( w, "\t \t {}_clone(self)" , trait_name) . unwrap( ) ;
600
655
writeln!( w, "\t }}\n }}" ) . unwrap( ) ;
656
+ writeln!( w, "impl Clone for {}Ref {{" , trait_name) . unwrap( ) ;
657
+ writeln!( w, "\t fn clone(&self) -> Self {{" ) . unwrap( ) ;
658
+ writeln!( w, "\t \t Self({}_clone(&self.0))" , trait_name) . unwrap( ) ;
659
+ writeln!( w, "\t }}\n }}" ) . unwrap( ) ;
601
660
} ,
602
661
( "std::fmt::Debug" , _, _) |( "core::fmt::Debug" , _, _) => {
603
662
writeln!( w, "impl core::fmt::Debug for {} {{" , trait_name) . unwrap( ) ;
604
663
writeln!( w, "\t fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {{" ) . unwrap( ) ;
605
664
writeln!( w, "\t \t f.write_str((self.debug_str)(self.this_arg).into_str())" ) . unwrap( ) ;
606
665
writeln!( w, "\t }}" ) . unwrap( ) ;
607
666
writeln!( w, "}}" ) . unwrap( ) ;
667
+ writeln!( w, "impl core::fmt::Debug for {}Ref {{" , trait_name) . unwrap( ) ;
668
+ writeln!( w, "\t fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {{" ) . unwrap( ) ;
669
+ writeln!( w, "\t \t f.write_str((self.0.debug_str)(self.0.this_arg).into_str())" ) . unwrap( ) ;
670
+ writeln!( w, "\t }}" ) . unwrap( ) ;
671
+ writeln!( w, "}}" ) . unwrap( ) ;
608
672
} ,
609
673
( s, i, generic_args) => {
610
674
if let Some ( supertrait) = types. crate_types. traits. get( s) {
@@ -621,9 +685,16 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
621
685
write!( w, " {}" , $s) . unwrap( ) ;
622
686
maybe_write_generics( w, & $supertrait. generics, $generic_args, types, false ) ;
623
687
writeln!( w, " for {} {{" , trait_name) . unwrap( ) ;
624
-
625
688
impl_trait_for_c!( $supertrait, format!( ".{}" , $i) , & resolver, $generic_args) ;
626
689
writeln!( w, "}}" ) . unwrap( ) ;
690
+
691
+ write!( w, "impl" ) . unwrap( ) ;
692
+ maybe_write_lifetime_generics( w, & $supertrait. generics, types) ;
693
+ write!( w, " {}" , $s) . unwrap( ) ;
694
+ maybe_write_generics( w, & $supertrait. generics, $generic_args, types, false ) ;
695
+ writeln!( w, " for {}Ref {{" , trait_name) . unwrap( ) ;
696
+ impl_trait_for_c!( $supertrait, format!( ".0.{}" , $i) , & resolver, $generic_args) ;
697
+ writeln!( w, "}}" ) . unwrap( ) ;
627
698
}
628
699
}
629
700
impl_supertrait!( s, supertrait, i, generic_args) ;
@@ -651,7 +722,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
651
722
impl_trait_for_c ! ( t, "" , types, & syn:: PathArguments :: None ) ;
652
723
writeln ! ( w, "}}\n " ) . unwrap ( ) ;
653
724
654
- writeln ! ( w, "struct {}Ref({});" , trait_name, trait_name) . unwrap ( ) ;
725
+ writeln ! ( w, "pub struct {}Ref({});" , trait_name, trait_name) . unwrap ( ) ;
655
726
write ! ( w, "impl" ) . unwrap ( ) ;
656
727
maybe_write_lifetime_generics ( w, & t. generics , types) ;
657
728
write ! ( w, " rust{}" , t. ident) . unwrap ( ) ;
0 commit comments