@@ -62,18 +62,22 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
6262 if let Some ( t) = types. maybe_resolve_path ( & trait_path, Some ( generics) ) {
6363 let for_obj;
6464 let full_obj_path;
65+ let native_path;
6566 let mut has_inner = false ;
6667 if let syn:: Type :: Path ( ref p) = for_ty {
6768 let resolved_path = types. resolve_path ( & p. path , Some ( generics) ) ;
6869 for_obj = format ! ( "{}" , p. path. segments. last( ) . unwrap( ) . ident) ;
6970 full_obj_path = format ! ( "crate::{}" , resolved_path) ;
7071 has_inner = types. c_type_has_inner_from_path ( & resolved_path) ;
72+ let ( path, name) = full_obj_path. rsplit_once ( "::" ) . unwrap ( ) ;
73+ native_path = path. to_string ( ) + "::native" + name;
7174 } else {
7275 // We assume that anything that isn't a Path is somehow a generic that ends up in our
7376 // derived-types module.
7477 let mut for_obj_vec = Vec :: new ( ) ;
7578 types. write_c_type ( & mut for_obj_vec, for_ty, Some ( generics) , false ) ;
7679 full_obj_path = String :: from_utf8 ( for_obj_vec) . unwrap ( ) ;
80+ native_path = full_obj_path. clone ( ) ;
7781 if !full_obj_path. starts_with ( TypeResolver :: generated_container_path ( ) ) { return ; }
7882 for_obj = full_obj_path[ TypeResolver :: generated_container_path ( ) . len ( ) + 2 ..] . into ( ) ;
7983 }
@@ -98,7 +102,7 @@ fn maybe_convert_trait_impl<W: std::io::Write>(w: &mut W, trait_path: &syn::Path
98102 writeln ! ( w, "#[allow(unused)]" ) . unwrap ( ) ;
99103 writeln ! ( w, "pub(crate) extern \" C\" fn {}_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {{" , for_obj) . unwrap ( ) ;
100104 if has_inner {
101- writeln ! ( w, "\t crate::c_types::serialize_obj(unsafe {{ &*(obj as *const native {}) }})" , for_obj ) . unwrap ( ) ;
105+ writeln ! ( w, "\t crate::c_types::serialize_obj(unsafe {{ &*(obj as *const {}) }})" , native_path ) . unwrap ( ) ;
102106 } else {
103107 writeln ! ( w, "\t {}_write(unsafe {{ &*(obj as *const {}) }})" , for_obj, for_obj) . unwrap ( ) ;
104108 }
@@ -221,6 +225,11 @@ fn do_write_impl_trait<W: std::io::Write>(w: &mut W, trait_path: &str, _trait_na
221225 writeln ! ( w, "\t \t let vec = (self.write)(self.this_arg);" ) . unwrap ( ) ;
222226 writeln ! ( w, "\t \t w.write_all(vec.as_slice())" ) . unwrap ( ) ;
223227 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 ( ) ;
224233 } ,
225234 _ => panic ! ( ) ,
226235 }
@@ -446,6 +455,47 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
446455 ( $t: expr, $impl_accessor: expr, $type_resolver: expr, $generic_impls: expr) => {
447456 let mut trait_gen_types = gen_types. push_ctx( ) ;
448457 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+
449499 for item in $t. items. iter( ) {
450500 match item {
451501 syn:: TraitItem :: Method ( m) => {
@@ -534,7 +584,11 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
534584 loop {
535585 match bounds_iter. next( ) . unwrap( ) {
536586 syn:: TypeParamBound :: Trait ( tr) => {
537- 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( ) ;
538592 for bound in bounds_iter {
539593 if let syn:: TypeParamBound :: Trait ( t) = bound {
540594 // We only allow for `Sized` here.
@@ -577,10 +631,15 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
577631 writeln!( w, "impl core::cmp::Eq for {} {{}}" , trait_name) . unwrap( ) ;
578632 writeln!( w, "impl core::cmp::PartialEq for {} {{" , trait_name) . unwrap( ) ;
579633 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( ) ;
580637 } ,
581638 ( "std::hash::Hash" , _, _) |( "core::hash::Hash" , _, _) => {
582639 writeln!( w, "impl core::hash::Hash for {} {{" , trait_name) . unwrap( ) ;
583640 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( ) ;
584643 } ,
585644 ( "Send" , _, _) => { } , ( "Sync" , _, _) => { } ,
586645 ( "Clone" , _, _) => {
@@ -594,13 +653,22 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
594653 writeln!( w, "\t fn clone(&self) -> Self {{" ) . unwrap( ) ;
595654 writeln!( w, "\t \t {}_clone(self)" , trait_name) . unwrap( ) ;
596655 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( ) ;
597660 } ,
598661 ( "std::fmt::Debug" , _, _) |( "core::fmt::Debug" , _, _) => {
599662 writeln!( w, "impl core::fmt::Debug for {} {{" , trait_name) . unwrap( ) ;
600663 writeln!( w, "\t fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {{" ) . unwrap( ) ;
601664 writeln!( w, "\t \t f.write_str((self.debug_str)(self.this_arg).into_str())" ) . unwrap( ) ;
602665 writeln!( w, "\t }}" ) . unwrap( ) ;
603666 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( ) ;
604672 } ,
605673 ( s, i, generic_args) => {
606674 if let Some ( supertrait) = types. crate_types. traits. get( s) {
@@ -617,9 +685,16 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
617685 write!( w, " {}" , $s) . unwrap( ) ;
618686 maybe_write_generics( w, & $supertrait. generics, $generic_args, types, false ) ;
619687 writeln!( w, " for {} {{" , trait_name) . unwrap( ) ;
620-
621688 impl_trait_for_c!( $supertrait, format!( ".{}" , $i) , & resolver, $generic_args) ;
622689 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( ) ;
623698 }
624699 }
625700 impl_supertrait!( s, supertrait, i, generic_args) ;
@@ -646,12 +721,22 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
646721 writeln ! ( w, " for {} {{" , trait_name) . unwrap ( ) ;
647722 impl_trait_for_c ! ( t, "" , types, & syn:: PathArguments :: None ) ;
648723 writeln ! ( w, "}}\n " ) . unwrap ( ) ;
724+
725+ writeln ! ( w, "pub struct {}Ref({});" , trait_name, trait_name) . unwrap ( ) ;
726+ write ! ( w, "impl" ) . unwrap ( ) ;
727+ maybe_write_lifetime_generics ( w, & t. generics , types) ;
728+ write ! ( w, " rust{}" , t. ident) . unwrap ( ) ;
729+ maybe_write_generics ( w, & t. generics , & syn:: PathArguments :: None , types, false ) ;
730+ writeln ! ( w, " for {}Ref {{" , trait_name) . unwrap ( ) ;
731+ impl_trait_for_c ! ( t, ".0" , types, & syn:: PathArguments :: None ) ;
732+ writeln ! ( w, "}}\n " ) . unwrap ( ) ;
733+
649734 writeln ! ( w, "// We're essentially a pointer already, or at least a set of pointers, so allow us to be used" ) . unwrap ( ) ;
650735 writeln ! ( w, "// directly as a Deref trait in higher-level structs:" ) . unwrap ( ) ;
651- writeln ! ( w, "impl core::ops::Deref for {} {{\n \t type Target = Self;" , trait_name) . unwrap ( ) ;
652- writeln ! ( w, "\t fn deref(&self) -> &Self {{\n \t \t self \n \t }}\n }}" ) . unwrap ( ) ;
736+ writeln ! ( w, "impl core::ops::Deref for {} {{\n \t type Target = {}Ref;" , trait_name , trait_name) . unwrap ( ) ;
737+ writeln ! ( w, "\t fn deref(&self) -> &Self::Target {{\n \t \t unsafe {{ &*(self as *const _ as *const {}Ref) }} \n \t }}\n }}" , trait_name ) . unwrap ( ) ;
653738 writeln ! ( w, "impl core::ops::DerefMut for {} {{" , trait_name) . unwrap ( ) ;
654- writeln ! ( w, "\t fn deref_mut(&mut self) -> &mut Self {{\n \t \t self \n \t }}\n }}" ) . unwrap ( ) ;
739+ writeln ! ( w, "\t fn deref_mut(&mut self) -> &mut {}Ref {{\n \t \t unsafe {{ &mut *(self as *mut _ as *mut {}Ref) }} \n \t }}\n }}" , trait_name , trait_name ) . unwrap ( ) ;
655740 }
656741
657742 writeln ! ( w, "/// Calls the free function if one is set" ) . unwrap ( ) ;
@@ -689,15 +774,26 @@ fn writeln_opaque<W: std::io::Write>(w: &mut W, ident: &syn::Ident, struct_name:
689774 writeln ! ( w, "\t /// this to be true and invalidate the object pointed to by inner." ) . unwrap ( ) ;
690775 writeln ! ( w, "\t pub is_owned: bool," ) . unwrap ( ) ;
691776 writeln ! ( w, "}}\n " ) . unwrap ( ) ;
777+
778+ writeln ! ( w, "impl core::ops::Deref for {} {{" , struct_name) . unwrap ( ) ;
779+ writeln ! ( w, "\t type Target = native{};" , struct_name) . unwrap ( ) ;
780+ writeln ! ( w, "\t fn deref(&self) -> &Self::Target {{ unsafe {{ &*ObjOps::untweak_ptr(self.inner) }} }}" ) . unwrap ( ) ;
781+ writeln ! ( w, "}}" ) . unwrap ( ) ;
782+
783+ writeln ! ( w, "unsafe impl core::marker::Send for {} {{ }}" , struct_name) . unwrap ( ) ;
784+ writeln ! ( w, "unsafe impl core::marker::Sync for {} {{ }}" , struct_name) . unwrap ( ) ;
785+
692786 writeln ! ( w, "impl Drop for {} {{\n \t fn drop(&mut self) {{" , struct_name) . unwrap ( ) ;
693787 writeln ! ( w, "\t \t if self.is_owned && !<*mut native{}>::is_null(self.inner) {{" , ident) . unwrap ( ) ;
694788 writeln ! ( w, "\t \t \t let _ = unsafe {{ Box::from_raw(ObjOps::untweak_ptr(self.inner)) }};\n \t \t }}\n \t }}\n }}" ) . unwrap ( ) ;
789+
695790 writeln ! ( w, "/// Frees any resources used by the {}, if is_owned is set and inner is non-NULL." , struct_name) . unwrap ( ) ;
696791 writeln ! ( w, "#[no_mangle]\n pub extern \" C\" fn {}_free(this_obj: {}) {{ }}" , struct_name, struct_name) . unwrap ( ) ;
697792 writeln ! ( w, "#[allow(unused)]" ) . unwrap ( ) ;
698793 writeln ! ( w, "/// Used only if an object of this type is returned as a trait impl by a method" ) . unwrap ( ) ;
699794 writeln ! ( w, "pub(crate) extern \" C\" fn {}_free_void(this_ptr: *mut c_void) {{" , struct_name) . unwrap ( ) ;
700795 writeln ! ( w, "\t let _ = unsafe {{ Box::from_raw(this_ptr as *mut native{}) }};\n }}" , struct_name) . unwrap ( ) ;
796+
701797 writeln ! ( w, "#[allow(unused)]" ) . unwrap ( ) ;
702798 writeln ! ( w, "impl {} {{" , struct_name) . unwrap ( ) ;
703799 writeln ! ( w, "\t pub(crate) fn get_native_ref(&self) -> &'static native{} {{" , struct_name) . unwrap ( ) ;
@@ -712,6 +808,9 @@ fn writeln_opaque<W: std::io::Write>(w: &mut W, ident: &syn::Ident, struct_name:
712808 writeln ! ( w, "\t \t let ret = ObjOps::untweak_ptr(self.inner);" ) . unwrap ( ) ;
713809 writeln ! ( w, "\t \t self.inner = core::ptr::null_mut();" ) . unwrap ( ) ;
714810 writeln ! ( w, "\t \t ret" ) . unwrap ( ) ;
811+ writeln ! ( w, "\t }}" ) . unwrap ( ) ;
812+ writeln ! ( w, "\t pub(crate) fn as_ref_to(&self) -> Self {{" ) . unwrap ( ) ;
813+ writeln ! ( w, "\t \t Self {{ inner: self.inner, is_owned: false }}" ) . unwrap ( ) ;
715814 writeln ! ( w, "\t }}\n }}" ) . unwrap ( ) ;
716815
717816 write_cpp_wrapper ( cpp_headers, & format ! ( "{}" , ident) , true , None ) ;
@@ -1227,13 +1326,13 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, w_uses: &mut HashSet<String, NonRa
12271326 if let syn:: ReturnType :: Type ( _, rtype) = & $m. sig. output {
12281327 if let syn:: Type :: Reference ( r) = & * * rtype {
12291328 assert_eq!( $m. sig. inputs. len( ) , 1 ) ; // Must only take self
1230- writeln!( w, "extern \" C\" fn {}_{}_set_{}(trait_self_arg: &{}) {{" , ident, $trait. ident, $m. sig. ident, $trait . ident ) . unwrap( ) ;
1329+ writeln!( w, "extern \" C\" fn {}_{}_set_{}(trait_self_arg: &crate:: {}) {{" , ident, $trait. ident, $m. sig. ident, $trait_path ) . unwrap( ) ;
12311330 writeln!( w, "\t // This is a bit race-y in the general case, but for our specific use-cases today, we're safe" ) . unwrap( ) ;
12321331 writeln!( w, "\t // Specifically, we must ensure that the first time we're called it can never be in parallel" ) . unwrap( ) ;
12331332 write!( w, "\t if " ) . unwrap( ) ;
12341333 $types. write_empty_rust_val_check( Some ( & meth_gen_types) , w, & * r. elem, & format!( "unsafe {{ &*trait_self_arg.{}.get() }}" , $m. sig. ident) ) ;
12351334 writeln!( w, " {{" ) . unwrap( ) ;
1236- writeln!( w, "\t \t *unsafe {{ &mut *(&*(trait_self_arg as *const {})).{}.get() }} = {}_{}_{}(trait_self_arg.this_arg).into();" , $trait . ident , $m. sig. ident, ident, $trait. ident, $m. sig. ident) . unwrap( ) ;
1335+ writeln!( w, "\t \t *unsafe {{ &mut *(&*(trait_self_arg as *const crate:: {})).{}.get() }} = {}_{}_{}(trait_self_arg.this_arg).into();" , $trait_path , $m. sig. ident, ident, $trait. ident, $m. sig. ident) . unwrap( ) ;
12371336 writeln!( w, "\t }}" ) . unwrap( ) ;
12381337 writeln!( w, "}}" ) . unwrap( ) ;
12391338 }
0 commit comments