From ac09c8a721be2a646fe0ca503ab148c2bde3d862 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 29 Jun 2026 14:59:56 +0100 Subject: [PATCH 1/5] Handle array to pointer decay in union member --- cpp2rust/converter/models/converter_refcount.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 72f8f143..8339ad3c 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1499,6 +1499,7 @@ bool ConverterRefCount::VisitInitListExpr(clang::InitListExpr *expr) { } void ConverterRefCount::ConvertUnionMemberAccessor(clang::MemberExpr *expr) { + auto member = expr->getMemberDecl(); std::string str; { Buffer buf(*this); @@ -1509,15 +1510,24 @@ void ConverterRefCount::ConvertUnionMemberAccessor(clang::MemberExpr *expr) { str += "()"; if (isAddrOf()) { - StrCat(str); + if (member->getType()->isArrayType()) { + PushConversionKind push(*this, ConversionKind::Unboxed); + StrCat(std::format( + "{}.reinterpret_cast::<{}>()", str, + ToString( + member->getType()->getAsArrayTypeUnsafe()->getElementType()))); + } else { + StrCat(str); + } computed_expr_type_ = ComputedExprType::Pointer; return; } + if (isLValue()) { pending_deref_.set(str); return; } - StrCat(DerefPtrExpr(str, expr->getMemberDecl()->getType())); + StrCat(DerefPtrExpr(str, member->getType())); } bool ConverterRefCount::VisitMemberExpr(clang::MemberExpr *expr) { From 8c9aeb2a0cb58d2536028208c4c7541f89e8182e Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 29 Jun 2026 15:00:38 +0100 Subject: [PATCH 2/5] Handle Ptr to array in union accessor --- cpp2rust/converter/models/converter_refcount.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 8339ad3c..08504faf 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -503,10 +503,13 @@ void ConverterRefCount::EmitRustUnion(clang::RecordDecl *decl) { { PushBrace impl_brace(*this); for (auto *field : decl->fields()) { + PushConversionKind push(*this, ConversionKind::FullRefCount); + std::string storage_ty = ToString(field->getType()); + Unwrap(storage_ty, "Value<", ">"); StrCat(std::format( "pub fn {}(&self) -> Ptr<{}> {{ (self.__bytes.as_pointer() " "as Ptr).reinterpret_cast() }}", - GetNamedDeclAsString(field), Mapper::Map(field->getType()))); + GetNamedDeclAsString(field), storage_ty)); } } From ad2f1267a7c1c81d689175c27847ca1243572dcf Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 29 Jun 2026 15:02:11 +0100 Subject: [PATCH 3/5] Update tests --- tests/unit/union_cross_arm_cast.c | 2 +- tests/unit/union_nested.c | 2 +- tests/unit/union_pointer_pun_address.c | 2 +- tests/unit/union_struct_dual_use.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/union_cross_arm_cast.c b/tests/unit/union_cross_arm_cast.c index 598de31e..274335ac 100644 --- a/tests/unit/union_cross_arm_cast.c +++ b/tests/unit/union_cross_arm_cast.c @@ -1,4 +1,4 @@ -// no-compile: refcount +// panic: refcount #include #include #include diff --git a/tests/unit/union_nested.c b/tests/unit/union_nested.c index b056725e..ca967139 100644 --- a/tests/unit/union_nested.c +++ b/tests/unit/union_nested.c @@ -1,4 +1,4 @@ -// no-compile: refcount +// panic: refcount #include #include #include diff --git a/tests/unit/union_pointer_pun_address.c b/tests/unit/union_pointer_pun_address.c index 421bb1f0..75123e0c 100644 --- a/tests/unit/union_pointer_pun_address.c +++ b/tests/unit/union_pointer_pun_address.c @@ -1,4 +1,4 @@ -// no-compile: refcount +// panic: refcount #include struct node_a { diff --git a/tests/unit/union_struct_dual_use.c b/tests/unit/union_struct_dual_use.c index 2ddb14f4..400f5c4e 100644 --- a/tests/unit/union_struct_dual_use.c +++ b/tests/unit/union_struct_dual_use.c @@ -1,4 +1,4 @@ -// no-compile: refcount +// panic: refcount #include #include From a37075ba46cdff6af69f1e03faa36e5ac6fbbb9d Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 29 Jun 2026 15:54:12 +0100 Subject: [PATCH 4/5] Update tests --- .../unit/out/refcount/union_cross_arm_cast.rs | 176 ++++++++++++++++++ tests/unit/out/refcount/union_nested.rs | 153 +++++++++++++++ .../out/refcount/union_pointer_pun_address.rs | 76 ++++++++ .../out/refcount/union_struct_dual_use.rs | 103 ++++++++++ 4 files changed, 508 insertions(+) create mode 100644 tests/unit/out/refcount/union_cross_arm_cast.rs create mode 100644 tests/unit/out/refcount/union_nested.rs create mode 100644 tests/unit/out/refcount/union_pointer_pun_address.rs create mode 100644 tests/unit/out/refcount/union_struct_dual_use.rs diff --git a/tests/unit/out/refcount/union_cross_arm_cast.rs b/tests/unit/out/refcount/union_cross_arm_cast.rs new file mode 100644 index 00000000..378246cf --- /dev/null +++ b/tests/unit/out/refcount/union_cross_arm_cast.rs @@ -0,0 +1,176 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive()] +pub struct shape_a { + pub code: Value, + pub pad: Value>, +} +impl Default for shape_a { + fn default() -> Self { + shape_a { + code: >::default(), + pad: Rc::new(RefCell::new( + (0..14).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for shape_a { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.code.borrow()).to_bytes(&mut buf[0..2]); + (*self.pad.borrow()).to_bytes(&mut buf[2..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + code: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), + pad: Rc::new(RefCell::new(>::from_bytes(&buf[2..16]))), + } + } +} +#[derive()] +pub struct shape_b { + pub code: Value, + pub lo: Value, + pub mid: Value, + pub fill: Value>, + pub tail: Value, +} +impl Default for shape_b { + fn default() -> Self { + shape_b { + code: >::default(), + lo: >::default(), + mid: >::default(), + fill: Rc::new(RefCell::new( + (0..16).map(|_| ::default()).collect::>(), + )), + tail: >::default(), + } + } +} +impl ByteRepr for shape_b { + fn byte_size() -> usize { + 28 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.code.borrow()).to_bytes(&mut buf[0..2]); + (*self.lo.borrow()).to_bytes(&mut buf[2..4]); + (*self.mid.borrow()).to_bytes(&mut buf[4..8]); + (*self.fill.borrow()).to_bytes(&mut buf[8..24]); + (*self.tail.borrow()).to_bytes(&mut buf[24..28]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + code: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), + lo: Rc::new(RefCell::new(::from_bytes(&buf[2..4]))), + mid: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + fill: Rc::new(RefCell::new(>::from_bytes(&buf[8..24]))), + tail: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), + } + } +} +pub struct anon_0 { + __bytes: Value>, +} +impl anon_0 { + pub fn a(&self) -> Ptr { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } + pub fn b(&self) -> Ptr { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } + pub fn raw_(&self) -> Ptr> { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } +} +impl Clone for anon_0 { + fn clone(&self) -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(self.__bytes.borrow().clone())), + } + } +} +impl Default for anon_0 { + fn default() -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from([0u8; 64]))), + } + } +} +impl ByteRepr for anon_0 {} +#[derive(Default)] +pub struct Container { + pub len: Value, + pub u: Value, +} +impl ByteRepr for Container {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let c: Value = >::default(); + { + ((c.as_pointer()) as Ptr) + .to_any() + .memset((0) as u8, 68usize as usize); + ((c.as_pointer()) as Ptr).to_any().clone() + }; + (*(*(*(*c.borrow()).u.borrow()).a().upgrade().deref()) + .code + .borrow_mut()) = 10_u16; + (*(*c.borrow()).len.borrow_mut()) = (28usize as u32); + (*(*(((*(*c.borrow()).u.borrow()).a()) + .clone() + .to_any() + .cast::() + .expect("ub:wrong type")) + .upgrade() + .deref()) + .tail + .borrow_mut()) = 3735928559_u32; + assert!( + ((((*(*(*(*c.borrow()).u.borrow()).b().upgrade().deref()) + .tail + .borrow()) + == 3735928559_u32) as i32) + != 0) + ); + assert!( + (((((*(*(*(*c.borrow()).u.borrow()).b().upgrade().deref()) + .code + .borrow()) as i32) + == 10) as i32) + != 0) + ); + (*(*(*(*c.borrow()).u.borrow()).b().upgrade().deref()) + .lo + .borrow_mut()) = 8080_u16; + assert!( + ((((((((*(*c.borrow()).u.borrow()).raw_().reinterpret_cast::()) + .to_strong() + .as_pointer() as Ptr::) + .offset((2) as isize) + .read()) as i32) + == 144) as i32) + != 0) + ); + assert!( + ((((((((*(*c.borrow()).u.borrow()).raw_().reinterpret_cast::()) + .to_strong() + .as_pointer() as Ptr::) + .offset((3) as isize) + .read()) as i32) + == 31) as i32) + != 0) + ); + return 0; +} diff --git a/tests/unit/out/refcount/union_nested.rs b/tests/unit/out/refcount/union_nested.rs new file mode 100644 index 00000000..29122027 --- /dev/null +++ b/tests/unit/out/refcount/union_nested.rs @@ -0,0 +1,153 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive()] +pub struct record { + pub code: Value, + pub pad: Value>, +} +impl Default for record { + fn default() -> Self { + record { + code: >::default(), + pad: Rc::new(RefCell::new( + (0..14).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for record { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.code.borrow()).to_bytes(&mut buf[0..2]); + (*self.pad.borrow()).to_bytes(&mut buf[2..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + code: Rc::new(RefCell::new(::from_bytes(&buf[0..2]))), + pad: Rc::new(RefCell::new(>::from_bytes(&buf[2..16]))), + } + } +} +pub struct anon_0 { + __bytes: Value>, +} +impl anon_0 { + pub fn h(&self) -> Ptr { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } + pub fn raw_(&self) -> Ptr> { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } +} +impl Clone for anon_0 { + fn clone(&self) -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(self.__bytes.borrow().clone())), + } + } +} +impl Default for anon_0 { + fn default() -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from([0u8; 128]))), + } + } +} +impl ByteRepr for anon_0 {} +#[derive(Default)] +pub struct inner { + pub view: Value, +} +impl ByteRepr for inner {} +pub struct anon_1 { + __bytes: Value>, +} +impl anon_1 { + pub fn h(&self) -> Ptr { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } + pub fn nested(&self) -> Ptr { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } +} +impl Clone for anon_1 { + fn clone(&self) -> Self { + anon_1 { + __bytes: Rc::new(RefCell::new(self.__bytes.borrow().clone())), + } + } +} +impl Default for anon_1 { + fn default() -> Self { + anon_1 { + __bytes: Rc::new(RefCell::new(Box::from([0u8; 128]))), + } + } +} +impl ByteRepr for anon_1 {} +#[derive(Default)] +pub struct Outer { + pub kind: Value, + pub level: Value, + pub variant: Value, + pub len: Value, + pub body: Value, +} +impl ByteRepr for Outer {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let ex: Value = >::default(); + { + ((ex.as_pointer()) as Ptr) + .to_any() + .memset((0) as u8, 144usize as usize); + ((ex.as_pointer()) as Ptr).to_any().clone() + }; + (*(*ex.borrow()).kind.borrow_mut()) = 2; + (*(*ex.borrow()).level.borrow_mut()) = 1; + (*(*ex.borrow()).variant.borrow_mut()) = 6; + (*(*ex.borrow()).len.borrow_mut()) = (16usize as u32); + (*(*(*(*ex.borrow()).body.borrow()).h().upgrade().deref()) + .code + .borrow_mut()) = 2_u16; + (*(*(*(*ex.borrow()).body.borrow()).h().upgrade().deref()) + .pad + .borrow_mut())[(0) as usize] = (('X' as i32) as u8); + assert!( + (((((*(*(*(*ex.borrow()).body.borrow()).h().upgrade().deref()) + .code + .borrow()) as i32) + == 2) as i32) + != 0) + ); + assert!( + (((((*(*(*(*ex.borrow()).body.borrow()).h().upgrade().deref()) + .pad + .borrow())[(0) as usize] as i32) + == ('X' as i32)) as i32) + != 0) + ); + assert!( + (((((*(*(*(*(*(*ex.borrow()).body.borrow()).nested().upgrade().deref()) + .view + .borrow()) + .h() + .upgrade() + .deref()) + .code + .borrow()) as i32) + == 2) as i32) + != 0) + ); + return 0; +} diff --git a/tests/unit/out/refcount/union_pointer_pun_address.rs b/tests/unit/out/refcount/union_pointer_pun_address.rs new file mode 100644 index 00000000..a9bfd716 --- /dev/null +++ b/tests/unit/out/refcount/union_pointer_pun_address.rs @@ -0,0 +1,76 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Default)] +pub struct node_a { + pub n: Value, +} +impl ByteRepr for node_a { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.n.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + n: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive(Default)] +pub struct node_b { + pub data: Value, + pub next: Value>, +} +impl ByteRepr for node_b {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value = Rc::new(RefCell::new(node_a { + n: Rc::new(RefCell::new(123)), + })); + pub struct anon_0 { + __bytes: Value>, + } + impl anon_0 { + pub fn to_a(&self) -> Ptr> { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } + pub fn to_b(&self) -> Ptr> { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } + } + impl Clone for anon_0 { + fn clone(&self) -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(self.__bytes.borrow().clone())), + } + } + } + impl Default for anon_0 { + fn default() -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from([0u8; 8]))), + } + } + } + impl ByteRepr for anon_0 {}; + let ptr: Value = >::default(); + (*ptr.borrow_mut()).to_a().write((a.as_pointer())); + let out: Value> = Rc::new(RefCell::new(((*ptr.borrow()).to_b().read()).clone())); + assert!( + ((({ + let _lhs = (*out.borrow()).clone().to_any(); + _lhs == (a.as_pointer()).to_any() + }) as i32) + != 0) + ); + return 0; +} diff --git a/tests/unit/out/refcount/union_struct_dual_use.rs b/tests/unit/out/refcount/union_struct_dual_use.rs new file mode 100644 index 00000000..5121280e --- /dev/null +++ b/tests/unit/out/refcount/union_struct_dual_use.rs @@ -0,0 +1,103 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Default)] +pub struct Inner { + pub a: Value, + pub b: Value, +} +impl ByteRepr for Inner { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.a.borrow()).to_bytes(&mut buf[0..4]); + (*self.b.borrow()).to_bytes(&mut buf[4..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + a: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + b: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + } + } +} +pub fn sum_inner_0(i: Ptr) -> i32 { + let i: Value> = Rc::new(RefCell::new(i)); + return { + let _lhs = (*(*(*i.borrow()).upgrade().deref()).a.borrow()); + _lhs + (*(*(*i.borrow()).upgrade().deref()).b.borrow()) + }; +} +pub struct anon_1 { + __bytes: Value>, +} +impl anon_1 { + pub fn inner(&self) -> Ptr { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } + pub fn raw_(&self) -> Ptr> { + (self.__bytes.as_pointer() as Ptr).reinterpret_cast() + } +} +impl Clone for anon_1 { + fn clone(&self) -> Self { + anon_1 { + __bytes: Rc::new(RefCell::new(self.__bytes.borrow().clone())), + } + } +} +impl Default for anon_1 { + fn default() -> Self { + anon_1 { + __bytes: Rc::new(RefCell::new(Box::from([0u8; 16]))), + } + } +} +impl ByteRepr for anon_1 {} +#[derive(Default)] +pub struct Outer { + pub u: Value, +} +impl ByteRepr for Outer {} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let standalone: Value = >::default(); + (*(*standalone.borrow()).a.borrow_mut()) = 3; + (*(*standalone.borrow()).b.borrow_mut()) = 4; + assert!((((({ sum_inner_0((standalone.as_pointer()),) }) == 7) as i32) != 0)); + let outer: Value = >::default(); + { + ((outer.as_pointer()) as Ptr) + .to_any() + .memset((0) as u8, 16usize as usize); + ((outer.as_pointer()) as Ptr).to_any().clone() + }; + (*(*(*(*outer.borrow()).u.borrow()).inner().upgrade().deref()) + .a + .borrow_mut()) = 3; + (*(*(*(*outer.borrow()).u.borrow()).inner().upgrade().deref()) + .b + .borrow_mut()) = 4; + assert!( + (((({ sum_inner_0(((*(*outer.borrow()).u.borrow()).inner()).clone(),) }) == 7) as i32) + != 0) + ); + assert!( + (((((((*(*outer.borrow()).u.borrow()).raw_().read())[(0) as usize] as u8) as i32) == 3) + as i32) + != 0) + ); + assert!( + (((((((*(*outer.borrow()).u.borrow()).raw_().read())[(4) as usize] as u8) as i32) == 4) + as i32) + != 0) + ); + return 0; +} From 515386e5c0bc2c9f4e1b6c803ddcad557372222f Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 29 Jun 2026 22:41:42 +0100 Subject: [PATCH 5/5] Update tests --- .../unit/out/refcount/union_cross_arm_cast.rs | 30 ++++++++- tests/unit/out/refcount/union_nested.rs | 64 +++++++++++++++++-- .../out/refcount/union_pointer_pun_address.rs | 14 +++- .../out/refcount/union_struct_dual_use.rs | 28 +++++++- 4 files changed, 127 insertions(+), 9 deletions(-) diff --git a/tests/unit/out/refcount/union_cross_arm_cast.rs b/tests/unit/out/refcount/union_cross_arm_cast.rs index 378246cf..0cbc548c 100644 --- a/tests/unit/out/refcount/union_cross_arm_cast.rs +++ b/tests/unit/out/refcount/union_cross_arm_cast.rs @@ -106,13 +106,39 @@ impl Default for anon_0 { } } } -impl ByteRepr for anon_0 {} +impl ByteRepr for anon_0 { + fn byte_size() -> usize { + 64 + } + fn to_bytes(&self, buf: &mut [u8]) { + buf.copy_from_slice(&self.__bytes.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from(buf))), + } + } +} #[derive(Default)] pub struct Container { pub len: Value, pub u: Value, } -impl ByteRepr for Container {} +impl ByteRepr for Container { + fn byte_size() -> usize { + 68 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.len.borrow()).to_bytes(&mut buf[0..4]); + (*self.u.borrow()).to_bytes(&mut buf[4..68]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + len: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + u: Rc::new(RefCell::new(::from_bytes(&buf[4..68]))), + } + } +} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/union_nested.rs b/tests/unit/out/refcount/union_nested.rs index 29122027..d1810f2a 100644 --- a/tests/unit/out/refcount/union_nested.rs +++ b/tests/unit/out/refcount/union_nested.rs @@ -61,12 +61,36 @@ impl Default for anon_0 { } } } -impl ByteRepr for anon_0 {} +impl ByteRepr for anon_0 { + fn byte_size() -> usize { + 128 + } + fn to_bytes(&self, buf: &mut [u8]) { + buf.copy_from_slice(&self.__bytes.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from(buf))), + } + } +} #[derive(Default)] pub struct inner { pub view: Value, } -impl ByteRepr for inner {} +impl ByteRepr for inner { + fn byte_size() -> usize { + 128 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.view.borrow()).to_bytes(&mut buf[0..128]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + view: Rc::new(RefCell::new(::from_bytes(&buf[0..128]))), + } + } +} pub struct anon_1 { __bytes: Value>, } @@ -92,7 +116,19 @@ impl Default for anon_1 { } } } -impl ByteRepr for anon_1 {} +impl ByteRepr for anon_1 { + fn byte_size() -> usize { + 128 + } + fn to_bytes(&self, buf: &mut [u8]) { + buf.copy_from_slice(&self.__bytes.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + anon_1 { + __bytes: Rc::new(RefCell::new(Box::from(buf))), + } + } +} #[derive(Default)] pub struct Outer { pub kind: Value, @@ -101,7 +137,27 @@ pub struct Outer { pub len: Value, pub body: Value, } -impl ByteRepr for Outer {} +impl ByteRepr for Outer { + fn byte_size() -> usize { + 144 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.kind.borrow()).to_bytes(&mut buf[0..4]); + (*self.level.borrow()).to_bytes(&mut buf[4..8]); + (*self.variant.borrow()).to_bytes(&mut buf[8..12]); + (*self.len.borrow()).to_bytes(&mut buf[12..16]); + (*self.body.borrow()).to_bytes(&mut buf[16..144]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + kind: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + level: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + variant: Rc::new(RefCell::new(::from_bytes(&buf[8..12]))), + len: Rc::new(RefCell::new(::from_bytes(&buf[12..16]))), + body: Rc::new(RefCell::new(::from_bytes(&buf[16..144]))), + } + } +} pub fn main() { std::process::exit(main_0()); } diff --git a/tests/unit/out/refcount/union_pointer_pun_address.rs b/tests/unit/out/refcount/union_pointer_pun_address.rs index a9bfd716..d0c51711 100644 --- a/tests/unit/out/refcount/union_pointer_pun_address.rs +++ b/tests/unit/out/refcount/union_pointer_pun_address.rs @@ -61,7 +61,19 @@ fn main_0() -> i32 { } } } - impl ByteRepr for anon_0 {}; + impl ByteRepr for anon_0 { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + buf.copy_from_slice(&self.__bytes.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + anon_0 { + __bytes: Rc::new(RefCell::new(Box::from(buf))), + } + } + }; let ptr: Value = >::default(); (*ptr.borrow_mut()).to_a().write((a.as_pointer())); let out: Value> = Rc::new(RefCell::new(((*ptr.borrow()).to_b().read()).clone())); diff --git a/tests/unit/out/refcount/union_struct_dual_use.rs b/tests/unit/out/refcount/union_struct_dual_use.rs index 5121280e..98225b6d 100644 --- a/tests/unit/out/refcount/union_struct_dual_use.rs +++ b/tests/unit/out/refcount/union_struct_dual_use.rs @@ -58,12 +58,36 @@ impl Default for anon_1 { } } } -impl ByteRepr for anon_1 {} +impl ByteRepr for anon_1 { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + buf.copy_from_slice(&self.__bytes.borrow()); + } + fn from_bytes(buf: &[u8]) -> Self { + anon_1 { + __bytes: Rc::new(RefCell::new(Box::from(buf))), + } + } +} #[derive(Default)] pub struct Outer { pub u: Value, } -impl ByteRepr for Outer {} +impl ByteRepr for Outer { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.u.borrow()).to_bytes(&mut buf[0..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + u: Rc::new(RefCell::new(::from_bytes(&buf[0..16]))), + } + } +} pub fn main() { std::process::exit(main_0()); }