diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 779cfdc0b..0b4a949db 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -3464,6 +3464,11 @@ bool Converter::VisitInitListExpr(clang::InitListExpr *expr) { if (auto form = expr->getSemanticForm()) expr = form; + if (expr->isTransparent()) { + Convert(expr->getInit(0)); + return false; + } + auto qual_type = expr->getType(); if (qual_type->isScalarType()) { assert(expr->getNumInits() < 2 && "Excess elements in scalar initializer"); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index fe2909e39..99245ae7f 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1840,6 +1840,11 @@ bool ConverterRefCount::VisitInitListExpr(clang::InitListExpr *expr) { if (auto form = expr->getSemanticForm()) expr = form; + if (expr->isTransparent()) { + Convert(expr->getInit(0)); + return false; + } + auto qual_type = expr->getType(); if (qual_type->isScalarType()) { PushConversionKind push(*this, ConversionKind::Unboxed); diff --git a/tests/unit/init_list.cpp b/tests/unit/init_list.cpp index 9826ed9f0..1b761ae1b 100644 --- a/tests/unit/init_list.cpp +++ b/tests/unit/init_list.cpp @@ -1,9 +1,25 @@ #include +#include #include #include void f(std::initializer_list list) {} +struct Pair { + int a; + int b; +}; + +struct Holder { + Pair p{0, 0}; + Holder &operator=(Pair &&o) { + p = o; + return *this; + } +}; + +int sum(const Pair &p) { return p.a + p.b; } + int main() { int i1{3}; int i2{}; @@ -13,5 +29,11 @@ int main() { std::vector vec = {1, 2, 3}; f({1, 2, 3, 4}); + Pair p{1, 2}; + Holder h; + h = {std::move(p)}; + assert(h.p.a == 1 && h.p.b == 2); + assert(sum({p}) == 3); + return 0; } diff --git a/tests/unit/out/refcount/init_list.rs b/tests/unit/out/refcount/init_list.rs index 7641e4a7f..ce029c520 100644 --- a/tests/unit/out/refcount/init_list.rs +++ b/tests/unit/out/refcount/init_list.rs @@ -9,6 +9,31 @@ use std::rc::{Rc, Weak}; pub fn f_0(list: Vec) { let list: Value> = Rc::new(RefCell::new(list)); } +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, Default)] +#[byte_size(8)] +pub struct Pair { + #[offset(0)] + pub a: i32, + #[offset(4)] + pub b: i32, +} +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg)] +#[byte_size(8)] +pub struct Holder { + #[offset(0)] + #[byte_size(8)] + pub p: Pair, +} +impl Default for Holder { + fn default() -> Self { + Holder { + p: Pair { a: 0, b: 0 }, + } + } +} +pub fn sum_1(p: Ptr) -> i32 { + return ({ p.with(|__s| __s.a) } + { p.with(|__s| __s.b) }); +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -21,6 +46,20 @@ fn main_0() -> i32 { let arr: Value> = Rc::new(RefCell::new(vec![1, 2, 3])); let mut vec_: Vec = vec![1, 2, 3]; ({ f_0(vec![1, 2, 3, 4]) }); + let p: Value = Rc::new(RefCell::new(Pair { a: 1, b: 2 })); + let h: Value = Rc::new(RefCell::new(::default())); + ({ HolderImpl::operator_assign_1(&h.as_pointer(), p.as_pointer()) }); + assert!(({ (*h.borrow()).p.a } == 1) && ({ (*h.borrow()).p.b } == 2)); + assert!((({ sum_1(p.as_pointer(),) }) == 3)); return 0; } +pub trait HolderImpl { + fn operator_assign_1(&self, o: Ptr) -> Ptr; +} +impl HolderImpl for Ptr { + fn operator_assign_1(&self, o: Ptr) -> Ptr { + field!((*self), p).write({ (*o.upgrade().deref()).clone() }); + return (*self).clone(); + } +} pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/init_list.rs b/tests/unit/out/unsafe/init_list.rs index 6a316bcc8..87a6532e5 100644 --- a/tests/unit/out/unsafe/init_list.rs +++ b/tests/unit/out/unsafe/init_list.rs @@ -7,6 +7,33 @@ use std::io::{Read, Seek, Write}; use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; pub unsafe fn f_0(mut list: Vec) {} +#[repr(C)] +#[derive(Copy, Clone, VaArg, FnPtrArg, Default)] +pub struct Pair { + pub a: i32, + pub b: i32, +} +#[repr(C)] +#[derive(Copy, Clone, VaArg, FnPtrArg)] +pub struct Holder { + pub p: Pair, +} +impl Holder { + pub unsafe fn operator_assign_1(&mut self, o: *mut Pair) -> *mut Holder { + self.p = (*o); + return &mut (*(self as *mut Holder)); + } +} +impl Default for Holder { + fn default() -> Self { + Holder { + p: Pair { a: 0, b: 0 }, + } + } +} +pub unsafe fn sum_1(p: *const Pair) -> i32 { + return (((*p).a) + ((*p).b)); +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -21,6 +48,11 @@ unsafe fn main_0() -> i32 { let mut arr: Vec = vec![1, 2, 3]; let mut vec_: Vec = vec![1, 2, 3]; (unsafe { f_0(vec![1, 2, 3, 4]) }); + let mut p: Pair = Pair { a: 1, b: 2 }; + let mut h: Holder = ::default(); + (unsafe { Holder::operator_assign_1(&mut h, &mut p) }); + assert!(((h.p.a) == (1)) && ((h.p.b) == (2))); + assert!(((unsafe { sum_1(&p,) }) == (3))); return 0; } pub unsafe fn __cpp2rust_init_globals() {}