Skip to content

Commit

Permalink
Update args on supertraits of supertraits when cloning trait impls
Browse files Browse the repository at this point in the history
When cloning implementations of traits from in-crate structs, we
forgot to update the arguments for supertraits of supertraits,
causing methods on that trait to be called against the previous
struct, not the cloned one.

This was ultimately identified downstream in the Java bindings,
fixes lightningdevkit/ldk-garbagecollected#138
  • Loading branch information
TheBlueMatt committed Oct 8, 2023
1 parent 10d1bac commit 2297474
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions c-bindings-gen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1254,15 +1254,25 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, w_uses: &mut HashSet<String, NonRa
writeln!(w, "extern \"C\" fn {}_{}_cloned(new_obj: &mut crate::{}) {{", trait_obj.ident, ident, full_trait_path).unwrap();
writeln!(w, "\tnew_obj.this_arg = {}_clone_void(new_obj.this_arg);", ident).unwrap();
writeln!(w, "\tnew_obj.free = Some({}_free_void);", ident).unwrap();
walk_supertraits!(trait_obj, Some(&types), (
(s, t, _) => {
if types.crate_types.traits.get(s).is_some() {
assert!(!types.is_clonable(s)); // We don't currently support cloning with a clonable supertrait
writeln!(w, "\tnew_obj.{}.this_arg = new_obj.this_arg;", t).unwrap();
writeln!(w, "\tnew_obj.{}.free = None;", t).unwrap();

fn seek_supertraits<W: std::io::Write>(w: &mut W, pfx: &str, tr: &syn::ItemTrait, types: &TypeResolver) {
walk_supertraits!(tr, Some(types), (
(s, t, _) => {
if types.crate_types.traits.get(s).is_some() {
assert!(!types.is_clonable(s)); // We don't currently support cloning with a clonable supertrait
writeln!(w, "\tnew_obj.{}{}.this_arg = new_obj.this_arg;", pfx, t).unwrap();
writeln!(w, "\tnew_obj.{}{}.free = None;", pfx, t).unwrap();
let mut module_iter = s.rsplitn(2, "::");
let _ty = module_iter.next().unwrap();
let tr = types.crate_types.traits.get(s).unwrap();
let module = module_iter.next().unwrap();
let resolver = get_module_type_resolver!(s, types.crate_types);
seek_supertraits(w, &format!("{}.", t), tr, &resolver);
}
}
}
) );
) );
}
seek_supertraits(w, "", trait_obj, types);
writeln!(w, "}}").unwrap();
}
write!(w, "\n").unwrap();
Expand Down

0 comments on commit 2297474

Please sign in to comment.