From 8fbc44fceb52db9292754f9f237bda0d190f0e18 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 09:24:28 +0100 Subject: [PATCH 01/11] Add move rules for array, map, unique_ptr and vector --- rules/array/src.cpp | 10 ++++++++++ rules/array/tgt_refcount.rs | 4 ++++ rules/array/tgt_unsafe.rs | 8 ++++++++ rules/map/src.cpp | 9 +++++++++ rules/map/tgt_refcount.rs | 12 ++++++++++++ rules/map/tgt_unsafe.rs | 8 ++++++++ rules/unique_ptr/src.cpp | 19 +++++++++++++++++++ rules/unique_ptr/tgt_refcount.rs | 16 ++++++++++++++++ rules/unique_ptr/tgt_unsafe.rs | 16 ++++++++++++++++ rules/vector/src.cpp | 9 +++++++++ rules/vector/tgt_unsafe.rs | 8 ++++++++ 11 files changed, 119 insertions(+) diff --git a/rules/array/src.cpp b/rules/array/src.cpp index 7c2cdcd24..4429fe38e 100644 --- a/rules/array/src.cpp +++ b/rules/array/src.cpp @@ -19,3 +19,13 @@ std::size_t f2(const std::array &o) { template T1 *f3(std::array &o) { return o.data(); } + +template +std::array f4(std::array &&o) { + return std::array(std::move(o)); +} + +template +std::array &f5(std::array &dst, std::array &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/array/tgt_refcount.rs b/rules/array/tgt_refcount.rs index 6f0ea5e1d..e558b8eeb 100644 --- a/rules/array/tgt_refcount.rs +++ b/rules/array/tgt_refcount.rs @@ -12,3 +12,7 @@ fn f1(a0: Ptr) -> Ptr { fn f3(a0: Ptr) -> Ptr { a0 } + +fn f5(a0: Ptr>, a1: &mut Vec) { + a0.write(std::mem::take(&mut *a1)) +} diff --git a/rules/array/tgt_unsafe.rs b/rules/array/tgt_unsafe.rs index 072b80828..dd98ee0fc 100644 --- a/rules/array/tgt_unsafe.rs +++ b/rules/array/tgt_unsafe.rs @@ -18,3 +18,11 @@ unsafe fn f2(a0: Vec) -> usize { unsafe fn f3(a0: &mut Vec) -> *mut T1 { a0.as_mut_ptr() } + +unsafe fn f4(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} + +unsafe fn f5(a0: &mut Vec, a1: &mut Vec) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/rules/map/src.cpp b/rules/map/src.cpp index 2ab0aa1ab..f1479d0e9 100644 --- a/rules/map/src.cpp +++ b/rules/map/src.cpp @@ -117,3 +117,12 @@ template T2 &f23(typename std::map::iterator it) { return it->second; } + +template std::map f24(std::map &&o) { + return std::map(std::move(o)); +} + +template +std::map &f25(std::map &dst, std::map &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/map/tgt_refcount.rs b/rules/map/tgt_refcount.rs index 8c5144ab4..457c23b73 100644 --- a/rules/map/tgt_refcount.rs +++ b/rules/map/tgt_refcount.rs @@ -139,3 +139,15 @@ fn f22(a0: RefcountMapIter) -> V fn f23(a0: RefcountMapIter) -> Value { a0.second() } + +fn f24(a0: Ptr>>) -> BTreeMap> { + a0.with_mut(|__v: &mut BTreeMap>| std::mem::take(__v)) +} + +fn f25( + a0: Ptr>>, + a1: Ptr>>, +) { + let __src = a1.with_mut(|__v: &mut BTreeMap>| std::mem::take(__v)); + a0.write(__src) +} diff --git a/rules/map/tgt_unsafe.rs b/rules/map/tgt_unsafe.rs index 14cd1b515..8024cad2b 100644 --- a/rules/map/tgt_unsafe.rs +++ b/rules/map/tgt_unsafe.rs @@ -102,3 +102,11 @@ unsafe fn f22(a0: UnsafeMapIterator) -> *const T1 { unsafe fn f23(a0: UnsafeMapIterator) -> *mut T2 { a0.second() } + +unsafe fn f24(a0: &mut BTreeMap>) -> BTreeMap> { + std::mem::take(&mut *a0) +} + +unsafe fn f25(a0: &mut BTreeMap>, a1: &mut BTreeMap>) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/rules/unique_ptr/src.cpp b/rules/unique_ptr/src.cpp index acc6b05ae..8d7790f42 100644 --- a/rules/unique_ptr/src.cpp +++ b/rules/unique_ptr/src.cpp @@ -55,3 +55,22 @@ template std::unique_ptr f10() { template std::unique_ptr f11() { return std::unique_ptr(); } + +template std::unique_ptr f12(std::unique_ptr &&o) { + return std::unique_ptr(std::move(o)); +} + +template std::unique_ptr f13(std::unique_ptr &&o) { + return std::unique_ptr(std::move(o)); +} + +template +std::unique_ptr &f14(std::unique_ptr &dst, std::unique_ptr &&src) { + return dst.operator=(std::move(src)); +} + +template +std::unique_ptr &f15(std::unique_ptr &dst, + std::unique_ptr &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/unique_ptr/tgt_refcount.rs b/rules/unique_ptr/tgt_refcount.rs index f0062cefe..b48f9bdcc 100644 --- a/rules/unique_ptr/tgt_refcount.rs +++ b/rules/unique_ptr/tgt_refcount.rs @@ -59,3 +59,19 @@ fn f10() -> Option> { fn f11() -> Option>> { None } + +fn f12(a0: &mut Option>) -> Option> { + a0.take() +} + +fn f13(a0: &mut Option>>) -> Option>> { + a0.take() +} + +fn f14(a0: Ptr>>, a1: &mut Option>) { + a0.write(a1.take()) +} + +fn f15(a0: Ptr>>>, a1: &mut Option>>) { + a0.write(a1.take()) +} diff --git a/rules/unique_ptr/tgt_unsafe.rs b/rules/unique_ptr/tgt_unsafe.rs index ca144a867..8db2a3c1b 100644 --- a/rules/unique_ptr/tgt_unsafe.rs +++ b/rules/unique_ptr/tgt_unsafe.rs @@ -53,3 +53,19 @@ unsafe fn f10() -> Option> { unsafe fn f11() -> Option> { None } + +unsafe fn f12(a0: &mut Option>) -> Option> { + a0.take() +} + +unsafe fn f13(a0: &mut Option>) -> Option> { + a0.take() +} + +unsafe fn f14(a0: &mut Option>, a1: &mut Option>) { + *a0 = a1.take() +} + +unsafe fn f15(a0: &mut Option>, a1: &mut Option>) { + *a0 = a1.take() +} diff --git a/rules/vector/src.cpp b/rules/vector/src.cpp index 2abb52cd8..39b424fd9 100644 --- a/rules/vector/src.cpp +++ b/rules/vector/src.cpp @@ -527,3 +527,12 @@ template > void f106(std::vector &o) { return o.shrink_to_fit(); } + +template std::vector f107(std::vector &&o) { + return std::vector(std::move(o)); +} + +template > +std::vector f108(std::vector &&o) { + return std::vector(std::move(o)); +} diff --git a/rules/vector/tgt_unsafe.rs b/rules/vector/tgt_unsafe.rs index 37866d27e..22abe970b 100644 --- a/rules/vector/tgt_unsafe.rs +++ b/rules/vector/tgt_unsafe.rs @@ -473,3 +473,11 @@ unsafe fn f105(a0: &mut Vec, a1: Vec) { unsafe fn f106(a0: &mut Vec) { a0.shrink_to_fit() } + +unsafe fn f107(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} + +unsafe fn f108(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} From 34a5373bd91c8ea771bc4913423e3ea91bd13101 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 09:33:00 +0100 Subject: [PATCH 02/11] Make std::move transparent in the converter --- cpp2rust/converter/converter.cpp | 7 +------ .../converter/models/converter_refcount.cpp | 12 +++++------ tests/unit/out/refcount/07_unique.rs | 5 ++--- tests/unit/out/refcount/11_move.rs | 3 +-- tests/unit/out/refcount/alloc_array.rs | 3 +-- tests/unit/out/refcount/matmul.rs | 20 +++++++++++++------ tests/unit/out/refcount/references2.rs | 3 +-- tests/unit/out/refcount/unique_ptr.rs | 9 +++++---- .../out/refcount/unique_ptr_const_deref.rs | 3 ++- tests/unit/out/refcount/unique_ptr_small.rs | 3 +-- tests/unit/out/unsafe/07_unique.rs | 6 +++--- tests/unit/out/unsafe/fft.rs | 4 ++-- tests/unit/out/unsafe/huffman.rs | 6 +++--- tests/unit/out/unsafe/matmul.rs | 7 ++++--- .../unit/out/unsafe/unique_ptr_const_deref.rs | 2 +- 15 files changed, 46 insertions(+), 47 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 96f446426..aae2337f7 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1765,12 +1765,7 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) { } if (expr->isCallToStdMove()) { - if (IsUniquePtr(expr->getArg(0)->getType())) { - StrCat(std::format("{}.take()", ConvertLValue(expr->getArg(0)))); - computed_expr_type_ = ComputedExprType::FreshValue; - return false; - } - StrCat(std::format("{}", ToString(expr->getArg(0)))); + Convert(expr->getArg(0)); return false; } diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 19cd1d50b..4c10e3750 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1151,15 +1151,9 @@ bool ConverterRefCount::VisitStringLiteral(clang::StringLiteral *expr) { bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { auto *sub_expr = expr->getSubExpr(); - // return unique_ptr (implicit xvalue cast) if (expr->isXValue() && sub_expr->isLValue()) { Convert(sub_expr); - if (IsUniquePtr(sub_expr->getType())) { - StrCat(".take()"); - computed_expr_type_ = ComputedExprType::FreshValue; - } else { - computed_expr_type_ = ComputedExprType::Value; - } + computed_expr_type_ = ComputedExprType::Value; return false; } @@ -2578,6 +2572,10 @@ std::string ConverterRefCount::ConvertMappedMethodCall( auto arg_idx = receiver_ph->n; auto *arg = BuildUnifiedArgs(expr, args, num_args)[arg_idx]; + if (auto *call = clang::dyn_cast(arg->IgnoreCasts()); + call && call->isCallToStdMove()) { + arg = call->getArg(0); + } if (!arg->getType()->isPointerType() && !IsReferenceType(arg)) { return Converter::ConvertMappedMethodCall(expr, mc, args, num_args, ctx); diff --git a/tests/unit/out/refcount/07_unique.rs b/tests/unit/out/refcount/07_unique.rs index 53efeb5a6..9fab5506e 100644 --- a/tests/unit/out/refcount/07_unique.rs +++ b/tests/unit/out/refcount/07_unique.rs @@ -21,9 +21,8 @@ fn main_0() -> i32 { (*f_ptr1.borrow()).write(10); let f_ptr2: Value> = Rc::new(RefCell::new(((*f.borrow()).as_pointer()))); (*f_ptr2.borrow()).write(11); - (*f.borrow_mut()) = Some(Rc::new(RefCell::new(9))); - let __rhs = ({ fn_0((*f.borrow_mut()).take()) }); - (*f.borrow_mut()) = __rhs; + (f.as_pointer() as Ptr>>).write(Some(Rc::new(RefCell::new(9))).take()); + (f.as_pointer() as Ptr>>).write(({ fn_0((*f.borrow_mut()).take()) }).take()); assert!(((*(*f.borrow()).as_ref().unwrap().borrow()) == 10)); return 0; } diff --git a/tests/unit/out/refcount/11_move.rs b/tests/unit/out/refcount/11_move.rs index c428fa124..3cd5d9fbf 100644 --- a/tests/unit/out/refcount/11_move.rs +++ b/tests/unit/out/refcount/11_move.rs @@ -8,8 +8,7 @@ use std::os::fd::AsFd; use std::rc::{Rc, Weak}; pub fn change_0(n: Ptr>>) { let m: Value>> = Rc::new(RefCell::new(Some(Rc::new(RefCell::new(20))))); - let __rhs = (*m.borrow_mut()).take(); - n.write(__rhs); + ((n).clone() as Ptr>>).write((*m.borrow_mut()).take()); assert!(((*m.borrow()).as_pointer()).is_null()); } pub fn main() { diff --git a/tests/unit/out/refcount/alloc_array.rs b/tests/unit/out/refcount/alloc_array.rs index 7c56dabbc..6fbf5bf04 100644 --- a/tests/unit/out/refcount/alloc_array.rs +++ b/tests/unit/out/refcount/alloc_array.rs @@ -20,8 +20,7 @@ pub fn All_0(arr: Ptr>>>, N: i32, element: i32) { (*element.borrow()); (*i.borrow_mut()).prefix_inc(); } - let __rhs = (*all.borrow_mut()).take(); - arr.write(__rhs); + ((arr).clone() as Ptr>>>).write((*all.borrow_mut()).take()); } pub fn Consume_1(arr: Option>>, N: i32) -> i32 { let arr: Value>>> = Rc::new(RefCell::new(arr)); diff --git a/tests/unit/out/refcount/matmul.rs b/tests/unit/out/refcount/matmul.rs index ccbd29d99..0d7d95502 100644 --- a/tests/unit/out/refcount/matmul.rs +++ b/tests/unit/out/refcount/matmul.rs @@ -18,12 +18,20 @@ pub fn matalloc_0(n: i32, p: i32, e: i32) -> Option = Rc::new(RefCell::new(0)); 'loop_: while ((*i.borrow()) < (*n.borrow())) { - (*m.borrow()).as_ref().unwrap().borrow_mut()[((*i.borrow()) as usize) as usize] = - Some(Rc::new(RefCell::new( - (0..((*p.borrow()) as usize)) - .map(|_| ::default()) - .collect::>(), - ))); + (((*m.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*i.borrow()) as usize))) + .clone() as Ptr>>>) + .write( + Some(Rc::new(RefCell::new( + (0..((*p.borrow()) as usize)) + .map(|_| ::default()) + .collect::>(), + ))) + .take(), + ); let j: Value = Rc::new(RefCell::new(0)); 'loop_: while ((*j.borrow()) < (*p.borrow())) { (*m.borrow()).as_ref().unwrap().borrow()[((*i.borrow()) as usize) as usize] diff --git a/tests/unit/out/refcount/references2.rs b/tests/unit/out/refcount/references2.rs index 1db9fd605..d7b1e5272 100644 --- a/tests/unit/out/refcount/references2.rs +++ b/tests/unit/out/refcount/references2.rs @@ -8,8 +8,7 @@ use std::os::fd::AsFd; use std::rc::{Rc, Weak}; pub fn change_0(p: Ptr>>) { let q: Value>> = Rc::new(RefCell::new(Some(Rc::new(RefCell::new(7))))); - let __rhs = (*q.borrow_mut()).take(); - p.write(__rhs); + ((p).clone() as Ptr>>).write((*q.borrow_mut()).take()); } pub fn main() { std::process::exit(main_0()); diff --git a/tests/unit/out/refcount/unique_ptr.rs b/tests/unit/out/refcount/unique_ptr.rs index 9c94c790c..057d2497d 100644 --- a/tests/unit/out/refcount/unique_ptr.rs +++ b/tests/unit/out/refcount/unique_ptr.rs @@ -57,12 +57,13 @@ pub fn DoStuffWithSafePointer_0(safe_ptr: Ptr>>) { let x1: Value>> = Rc::new(RefCell::new(Some(Rc::new(RefCell::new(0))))); let x2: Value>> = Rc::new(RefCell::new(Some(Rc::new(RefCell::new(0))))); (*(*x2.borrow_mut()).as_ref().unwrap().borrow_mut()) = 1; - (*x1.borrow_mut()) = (*x2.borrow_mut()).take(); + (x1.as_pointer() as Ptr>>).write((*x2.borrow_mut()).take()); let raw_ptr1: Value> = Rc::new(RefCell::new(((*x1.borrow()).as_pointer()))); (*raw_ptr1.borrow()).with_mut(|__v| __v.prefix_inc()); - (*(*(*safe_ptr.upgrade().deref()).as_ref().unwrap().borrow()) + ((*(*safe_ptr.upgrade().deref()).as_ref().unwrap().borrow()) .ptr - .borrow_mut()) = (*x1.borrow_mut()).take(); + .as_pointer() as Ptr>>) + .write((*x1.borrow_mut()).take()); ({ SafePointerImpl::inc(&((*safe_ptr.upgrade().deref()).as_pointer())) }); ({ SafePointerImpl::inc(&((*safe_ptr.upgrade().deref()).as_pointer())) }); let x3: Value>> = Rc::new(RefCell::new(Some(Rc::new(RefCell::new(10))))); @@ -70,7 +71,7 @@ pub fn DoStuffWithSafePointer_0(safe_ptr: Ptr>>) { let __rhs = ((*(*x3.borrow()).as_ref().unwrap().borrow()) + (*(*x4.borrow()).as_ref().unwrap().borrow())); (*(*x3.borrow_mut()).as_ref().unwrap().borrow_mut()) = __rhs; - (*x4.borrow_mut()) = (*x3.borrow_mut()).take(); + (x4.as_pointer() as Ptr>>).write((*x3.borrow_mut()).take()); let raw_ptr2: Value> = Rc::new(RefCell::new(((*x4.borrow()).as_pointer()))); { let _ptr = (*raw_ptr2.borrow()).clone(); diff --git a/tests/unit/out/refcount/unique_ptr_const_deref.rs b/tests/unit/out/refcount/unique_ptr_const_deref.rs index c50dfc99a..299f6780d 100644 --- a/tests/unit/out/refcount/unique_ptr_const_deref.rs +++ b/tests/unit/out/refcount/unique_ptr_const_deref.rs @@ -43,7 +43,8 @@ pub fn main() { } fn main_0() -> i32 { let h: Value = Rc::new(RefCell::new(::default())); - (*(*h.borrow()).val.borrow_mut()) = Some(Rc::new(RefCell::new(10))); + ((*h.borrow()).val.as_pointer() as Ptr>>) + .write(Some(Rc::new(RefCell::new(10))).take()); ({ write_val_1((h.as_pointer()), 42) }); assert!((({ read_val_0((h.as_pointer()),) }) == 42)); return 0; diff --git a/tests/unit/out/refcount/unique_ptr_small.rs b/tests/unit/out/refcount/unique_ptr_small.rs index 859e06eab..d22c425cc 100644 --- a/tests/unit/out/refcount/unique_ptr_small.rs +++ b/tests/unit/out/refcount/unique_ptr_small.rs @@ -8,8 +8,7 @@ use std::os::fd::AsFd; use std::rc::{Rc, Weak}; pub fn change_0(n: Ptr>>) { let m: Value>> = Rc::new(RefCell::new(Some(Rc::new(RefCell::new(20))))); - let __rhs = (*m.borrow_mut()).take(); - n.write(__rhs); + ((n).clone() as Ptr>>).write((*m.borrow_mut()).take()); } pub fn main() { std::process::exit(main_0()); diff --git a/tests/unit/out/unsafe/07_unique.rs b/tests/unit/out/unsafe/07_unique.rs index ff03cae4e..1cfbca6cb 100644 --- a/tests/unit/out/unsafe/07_unique.rs +++ b/tests/unit/out/unsafe/07_unique.rs @@ -8,7 +8,7 @@ use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; use std::rc::Rc; pub unsafe fn fn_0(mut u: Option>) -> Option> { (*u.as_deref_mut().unwrap()) = 10; - return u; + return u.take(); } pub fn main() { unsafe { @@ -24,8 +24,8 @@ unsafe fn main_0() -> i32 { (*f_ptr1) = 10; let mut f_ptr2: *mut i32 = (&mut (*f.as_deref_mut().unwrap()) as *mut i32); (*f_ptr2) = 11; - f = Some(Box::new(9)); - f = (unsafe { fn_0(f.take()) }); + f = Some(Box::new(9)).take(); + f = (unsafe { fn_0(f.take()) }).take(); assert!(((*f.as_deref_mut().unwrap()) == (10))); return 0; } diff --git a/tests/unit/out/unsafe/fft.rs b/tests/unit/out/unsafe/fft.rs index 1a19476db..19ed836f2 100644 --- a/tests/unit/out/unsafe/fft.rs +++ b/tests/unit/out/unsafe/fft.rs @@ -44,7 +44,7 @@ pub unsafe fn fft_3(a: *mut Option>, mut N: i32) -> Option> = Some( (0..(N as usize)) @@ -120,7 +120,7 @@ pub unsafe fn fft_3(a: *mut Option>, mut N: i32) -> Option Option> { .collect::>(), ), })); - return minHeap; + return minHeap.take(); } pub unsafe fn Huffman_2( data: *mut Option>, @@ -176,7 +176,7 @@ pub unsafe fn Huffman_2( (*top).right = right; (unsafe { MinHeap::Insert(&mut (*minHeap.as_deref_mut().unwrap()), top) }); } - return minHeap; + return minHeap.take(); } pub unsafe fn CollectCode_3( arr: *mut Option>, @@ -269,7 +269,7 @@ pub unsafe fn HuffmanCodes_5( &mut next as *mut i32, ) }); - return out; + return out.take(); } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/matmul.rs b/tests/unit/out/unsafe/matmul.rs index b40871b87..f9ae8d015 100644 --- a/tests/unit/out/unsafe/matmul.rs +++ b/tests/unit/out/unsafe/matmul.rs @@ -18,7 +18,8 @@ pub unsafe fn matalloc_0(mut n: i32, mut p: i32, mut e: i32) -> Option::default()) .collect::>(), - ); + ) + .take(); let mut j: i32 = 0; 'loop_: while ((j) < (p)) { m.as_mut().unwrap()[(i as usize)].as_mut().unwrap()[(j as usize)] = e; @@ -26,7 +27,7 @@ pub unsafe fn matalloc_0(mut n: i32, mut p: i32, mut e: i32) -> Option>]>>, @@ -53,7 +54,7 @@ pub unsafe fn matmul_1( } i.prefix_inc(); } - return m3; + return m3.take(); } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/unique_ptr_const_deref.rs b/tests/unit/out/unsafe/unique_ptr_const_deref.rs index d8bfaca4c..2de998939 100644 --- a/tests/unit/out/unsafe/unique_ptr_const_deref.rs +++ b/tests/unit/out/unsafe/unique_ptr_const_deref.rs @@ -28,7 +28,7 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut h: Holder = ::default(); - h.val = Some(Box::new(10)); + h.val = Some(Box::new(10)).take(); (unsafe { write_val_1((&mut h as *mut Holder).cast_const(), 42) }); assert!(((unsafe { read_val_0((&mut h as *mut Holder).cast_const(),) }) == (42))); return 0; From e2c3173c8a1d1f8ca5b5648d9f4eec9177fd220c Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 09:58:57 +0100 Subject: [PATCH 03/11] Translate and use user defined move constructor --- cpp2rust/converter/converter.cpp | 110 ++-- cpp2rust/converter/converter.h | 3 + cpp2rust/converter/converter_lib.cpp | 78 ++- cpp2rust/converter/converter_lib.h | 7 +- .../converter/models/converter_refcount.cpp | 31 +- cpp2rust/converter/plugins/emplace_back.cpp | 62 +- .../defaulted_move_cross_tu/CMakeLists.txt | 3 + .../multi-file/defaulted_move_cross_tu/a.cpp | 12 + .../multi-file/defaulted_move_cross_tu/b.cpp | 14 + .../out/refcount/defaulted_move_cross_tu.rs | 105 ++++ .../out/unsafe/defaulted_move_cross_tu.rs | 68 +++ tests/multi-file/defaulted_move_cross_tu/s.h | 17 + tests/unit/copy_move_defaulted.cpp | 23 +- tests/unit/copy_move_deleted.cpp | 1 - .../unit/out/refcount/copy_move_defaulted.rs | 577 ++++++++++++++++++ tests/unit/out/refcount/copy_move_deleted.rs | 212 +++++++ tests/unit/out/refcount/empty_main.rs | 4 +- tests/unit/out/refcount/huffman.rs | 17 + .../out/refcount/operator_arithmetic_free.rs | 6 +- .../refcount/operator_arithmetic_member.rs | 10 +- .../refcount/operator_comparison_defaulted.rs | 100 +-- tests/unit/out/refcount/push_emplace_back.rs | 45 +- tests/unit/out/refcount/unique_ptr.rs | 11 + tests/unit/out/refcount/unique_ptr_nested.rs | 11 + .../out/refcount/vector_with_allocator.rs | 10 +- tests/unit/out/unsafe/copy_ctor.rs | 2 +- tests/unit/out/unsafe/copy_move_defaulted.rs | 302 +++++++++ tests/unit/out/unsafe/copy_move_deleted.rs | 128 ++++ tests/unit/out/unsafe/empty_main.rs | 2 +- tests/unit/out/unsafe/huffman.rs | 20 +- tests/unit/out/unsafe/move_assign.rs | 28 +- tests/unit/out/unsafe/move_ctor.rs | 17 +- tests/unit/out/unsafe/move_this.rs | 6 +- .../out/unsafe/operator_arithmetic_free.rs | 4 +- .../out/unsafe/operator_arithmetic_member.rs | 4 +- .../unsafe/operator_comparison_defaulted.rs | 70 +-- tests/unit/out/unsafe/push_emplace_back.rs | 14 +- tests/unit/out/unsafe/rule_of_five.rs | 8 +- tests/unit/out/unsafe/rule_of_three.rs | 4 +- tests/unit/out/unsafe/rvalue_ref_general.rs | 2 +- tests/unit/out/unsafe/rvalue_struct.rs | 2 +- tests/unit/out/unsafe/unique_ptr.rs | 6 + tests/unit/out/unsafe/unique_ptr_nested.rs | 8 + .../unit/out/unsafe/vector_with_allocator.rs | 4 +- 44 files changed, 1917 insertions(+), 251 deletions(-) create mode 100644 tests/multi-file/defaulted_move_cross_tu/CMakeLists.txt create mode 100644 tests/multi-file/defaulted_move_cross_tu/a.cpp create mode 100644 tests/multi-file/defaulted_move_cross_tu/b.cpp create mode 100644 tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs create mode 100644 tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs create mode 100644 tests/multi-file/defaulted_move_cross_tu/s.h create mode 100644 tests/unit/out/refcount/copy_move_defaulted.rs create mode 100644 tests/unit/out/refcount/copy_move_deleted.rs create mode 100644 tests/unit/out/unsafe/copy_move_defaulted.rs create mode 100644 tests/unit/out/unsafe/copy_move_deleted.rs diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index aae2337f7..84e8d9ff7 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -253,6 +253,9 @@ Converter::ConvertRValue(clang::Expr *expr, std::string Converter::ConvertFreshRValue( clang::Expr *expr, std::optional implicit_convert_to) { auto str = ConvertRValue(expr, implicit_convert_to); + if (expr->isGLValue()) { + SetValueFreshness(expr->getType()); + } if (!isFresh() && !expr->getType()->isVoidType() && !expr->getType()->isPointerType()) { SetFresh(); @@ -948,8 +951,9 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) { } if (!record_decls_.MarkDefined(GetRecordName(decl))) { - // Other translation units may instantiate members this one did not. - if (clang::isa(decl)) { + // Other translation units may instantiate or synthesize members this + // one did not. + if (!decl->isAbstract()) { ConvertLateInstantiatedMethods(decl); } return false; @@ -960,25 +964,7 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) { return false; } - sema_->ForceDeclarationOfImplicitMembers(decl); - for (auto ctor : decl->ctors()) { - if (ctor->isCopyConstructor() && ctor->isImplicit() && - !ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted()) { - sema_->DefineImplicitCopyConstructor(decl->getLocation(), ctor); - } - } - for (auto *method : decl->methods()) { - if (IsComparisonOperator(method) && method->isDefaulted() && - !method->doesThisDeclarationHaveABody()) { -#if CLANG_VERSION_MAJOR >= 24 - auto kind = method->getDefaultedComparisonKind(); -#else - auto kind = sema_->getDefaultedComparisonKind(method); -#endif - sema_->DefineDefaultedComparison(decl->getLocation(), method, kind); - } - } - + DefineImplicitMembers(decl); EmitRustStructOrUnion(decl); } else if (decl->isUnion()) { if (!record_decls_.MarkDefined(GetRecordName(decl))) { @@ -993,6 +979,27 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) { return false; } +void Converter::DefineImplicitMembers(clang::CXXRecordDecl *decl) { + sema_->ForceDeclarationOfImplicitMembers(decl); + for (auto ctor : decl->ctors()) { + if (ctor->isCopyConstructor() && ctor->isImplicit() && + !ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted()) { + sema_->DefineImplicitCopyConstructor(decl->getLocation(), ctor); + } + } + for (auto *method : decl->methods()) { + if (IsComparisonOperator(method) && method->isDefaulted() && + !method->doesThisDeclarationHaveABody()) { +#if CLANG_VERSION_MAJOR >= 24 + auto kind = method->getDefaultedComparisonKind(); +#else + auto kind = sema_->getDefaultedComparisonKind(method); +#endif + sema_->DefineDefaultedComparison(decl->getLocation(), method, kind); + } + } +} + bool Converter::VisitCXXMethodDecl(clang::CXXMethodDecl *decl) { decl->dump(log()); if (!ShouldConvertMethod(decl)) { @@ -1080,7 +1087,8 @@ std::string Converter::GetCtorName(clang::CXXConstructorDecl *decl) { } bool Converter::VisitCXXConstructorDecl(clang::CXXConstructorDecl *decl) { - if (decl->isOutOfLine() || decl->isImplicit()) { + if (decl->isOutOfLine() || + (decl->isImplicit() && !IsUserDefinedMoveConstructorOrAssignment(decl))) { return false; } PushCurrFunction push_fn(*this, decl); @@ -1718,18 +1726,54 @@ void Converter::ConvertVAArgCall(clang::CallExpr *expr) { } } +bool Converter::ConvertMemberAssignmentCall(clang::CallExpr *expr) { + auto *member_call = clang::dyn_cast(expr); + if (!member_call) { + return false; + } + auto *callee = member_call->getMethodDecl(); + if (!callee || (!callee->isCopyAssignmentOperator() && + !callee->isMoveAssignmentOperator())) { + return false; + } + auto *object = member_call->getImplicitObjectArgument(); + if (clang::isa(object->IgnoreParenImpCasts())) { + return true; + } + if (IsUserDefinedDecl(callee->getParent()) || + Mapper::Contains(member_call->getCallee())) { + return false; + } + ConvertAssignment(object, member_call->getArg(0), "="); + return true; +} + bool Converter::VisitCallExpr(clang::CallExpr *expr) { if (IsBuiltinVaStart(expr) || IsBuiltinVaEnd(expr) || IsBuiltinVaCopy(expr)) { ConvertVAArgCall(expr); return false; } + if (IsMemberMemcpy(expr)) { + ConvertAssignment( + clang::cast(expr->getArg(0)->IgnoreImpCasts()) + ->getSubExpr(), + clang::cast(expr->getArg(1)->IgnoreImpCasts()) + ->getSubExpr(), + "="); + return false; + } + // p->~T() on a scalar is a no-op if (clang::isa( expr->getCallee()->IgnoreParenImpCasts())) { return false; } + if (ConvertMemberAssignmentCall(expr)) { + return false; + } + if (auto plugin_str = TryPluginConvert(expr)) { StrCat(*plugin_str); return false; @@ -2662,6 +2706,9 @@ void Converter::ConvertGenericBinaryOperator(clang::BinaryOperator *expr) { bool Converter::IsReferenceType(const clang::Expr *expr) const { const auto *e = expr->IgnoreCasts(); if (const auto *call = clang::dyn_cast(e)) { + if (call->isCallToStdMove()) { + return IsReferenceType(call->getArg(0)); + } return !clang::isa(call) && GetReturnTypeOfFunction(call)->isReferenceType(); } @@ -3411,21 +3458,12 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { } auto *ctor = expr->getConstructor(); - // Default move is translated using a bitwise .clone() implementation. - // Bitwise clone is only satisfied by default copy constructor. If the copy - // constructor is user defined, then default move calls copy constructor, - // which is wrong. - if (IsDefaultedMoveConstructor(ctor) && - !HasDefaultedCopyConstructor(ctor->getParent())) { - llvm::report_fatal_error("defaulted move constructor without a fieldwise " - "copy constructor is not supported"); - } - if (IsPassThroughConstructor(ctor)) { // Take suppress before recursing into the child. bool suppress = PushSuppressIteratorClone::take(*this); Convert(expr->getArg(0)); - if ((ctor->isCopyConstructor() || IsDefaultedMoveConstructor(ctor)) && + if ((ctor->isCopyConstructor() || + (ctor->isMoveConstructor() && IsUserDefinedDecl(ctor->getParent()))) && !suppress && !TypeIsCopyable(expr->getType())) { StrCat(".clone()"); } @@ -3438,7 +3476,7 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { return false; } - assert(ctor->isUserProvided()); + assert(ctor->isUserProvided() || IsUserDefinedMoveConstructor(ctor)); if (expr->getType()->isArrayType()) { ConvertArrayCXXConstructExpr(expr); } else { @@ -3843,6 +3881,10 @@ std::string Converter::ConvertVarDefaultInit(clang::QualType qual_type) { std::string Converter::GetOverloadedFunctionName(const clang::FunctionDecl *decl) { auto name = GetFunctionBaseName(decl); + if (auto *ctor = clang::dyn_cast(decl); + ctor && !ctor->getParent()->getIdentifier()) { + name = GetRecordName(ctor->getParent()); + } if (decl->getNumParams() != 0U) { name += '_'; diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index a5117fc7b..54a453d14 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -331,6 +331,9 @@ class Converter : public clang::RecursiveASTVisitor { virtual void ConvertVariadicArg(clang::Expr *arg); + void DefineImplicitMembers(clang::CXXRecordDecl *decl); + + bool ConvertMemberAssignmentCall(clang::CallExpr *expr); virtual bool VisitCallExpr(clang::CallExpr *expr); virtual bool VisitIntegerLiteral(clang::IntegerLiteral *expr); diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index a7c6500c3..91c0ab8b3 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -286,9 +286,40 @@ bool IsUserDefinedCopyConstructor(const clang::CXXConstructorDecl *ctor) { IsUserDefinedDecl(ctor); } +static bool HasUserProvidedCopyMember(const clang::CXXRecordDecl *decl) { + return std::any_of(decl->method_begin(), decl->method_end(), [](auto *m) { + auto *ctor = clang::dyn_cast(m); + return m->isUserProvided() && + (ctor ? ctor->isCopyConstructor() : m->isCopyAssignmentOperator()); + }); +} + +static bool IsTranslatedMoveMember(const clang::CXXMethodDecl *method) { + if (method->isDeleted() || !IsUserDefinedDecl(method->getParent())) { + return false; + } + if (method->isUserProvided()) { + return true; + } + return method->isDefaulted() && method->hasBody() && + (!method->isTrivial() || + HasUserProvidedCopyMember(method->getParent())); +} + bool IsUserDefinedMoveConstructor(const clang::CXXConstructorDecl *ctor) { - return ctor->isMoveConstructor() && ctor->isUserProvided() && - IsUserDefinedDecl(ctor); + return ctor->isMoveConstructor() && IsTranslatedMoveMember(ctor); +} + +bool IsUserDefinedMoveAssignment(const clang::CXXMethodDecl *method) { + return method->isMoveAssignmentOperator() && IsTranslatedMoveMember(method); +} + +bool IsUserDefinedMoveConstructorOrAssignment( + const clang::CXXMethodDecl *method) { + if (auto *ctor = clang::dyn_cast(method)) { + return IsUserDefinedMoveConstructor(ctor); + } + return IsUserDefinedMoveAssignment(method); } bool IsUserDefinedCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor) { @@ -296,11 +327,6 @@ bool IsUserDefinedCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor) { IsUserDefinedMoveConstructor(ctor); } -bool IsDefaultedMoveConstructor(const clang::CXXConstructorDecl *ctor) { - return ctor->isMoveConstructor() && !ctor->isUserProvided() && - IsUserDefinedDecl(ctor->getParent()); -} - clang::CXXConstructorDecl * GetUserDefinedCopyConstructor(const clang::RecordDecl *decl) { auto *cxx = clang::dyn_cast(decl); @@ -328,6 +354,25 @@ bool HasDefaultedCopyConstructor(const clang::RecordDecl *decl) { return !cxx->defaultedCopyConstructorIsDeleted(); } +bool IsMemberMemcpy(const clang::CallExpr *expr) { + const auto *fn = expr->getDirectCallee(); + if (!fn || fn->getBuiltinID() != clang::Builtin::BI__builtin_memcpy) { + return false; + } + auto member = [](const clang::Expr *arg) -> const clang::MemberExpr * { + const auto *unary = + clang::dyn_cast(arg->IgnoreImpCasts()); + if (!unary || unary->getOpcode() != clang::UO_AddrOf) { + return nullptr; + } + return clang::dyn_cast( + unary->getSubExpr()->IgnoreImpCasts()); + }; + const auto *dst = member(expr->getArg(0)); + const auto *src = member(expr->getArg(1)); + return dst && src && dst->getType() == src->getType(); +} + bool HasCallableCopyConstructor(const clang::RecordDecl *decl) { auto *cxx = clang::dyn_cast(decl); if (!cxx) { @@ -375,7 +420,8 @@ bool IsConvertibleCXXMethodDecl(const clang::CXXMethodDecl *decl) { if (llvm::isa(decl)) { return GetUserDefinedDestructor(decl->getParent()) != nullptr; } - return !decl->isImplicit() || IsComparisonOperator(decl); + return !decl->isImplicit() || IsComparisonOperator(decl) || + IsUserDefinedMoveConstructorOrAssignment(decl); } bool IsConvertibleFunctionDecl(const clang::FunctionDecl *decl) { @@ -652,12 +698,10 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) { llvm::dyn_cast(pdecl->getDeclContext()); const auto *ctor = llvm::dyn_cast_or_null(fn); if (pdecl->isExplicitObjectParameter() || - (ctor && ctor->isCopyOrMoveConstructor())) { + (ctor && ctor->isCopyConstructor())) { name = "self"; - } else if (fn && fn->isDefaulted() && IsComparisonOperator(fn)) { - name = std::format("_arg{}", pdecl->getFunctionScopeIndex()); } else { - name = "_"; + name = std::format("_a{}", pdecl->getFunctionScopeIndex()); } } else if (auto *pdecl = llvm::dyn_cast(decl)) { // Expanded parameter packs share one name across the expansion @@ -816,6 +860,10 @@ bool IsUserOperatorCall(const clang::CXXOperatorCallExpr *expr) { method && method->isDefaulted() && IsComparisonOperator(method)) { return IsUserDefinedDecl(method->getParent()); } + if (const auto *method = clang::dyn_cast(callee); + method && IsUserDefinedMoveConstructorOrAssignment(method)) { + return true; + } if (!callee->isUserProvided() || !IsUserDefinedDecl(callee)) { return false; } @@ -906,6 +954,9 @@ bool IsEmittableMethod(clang::CXXMethodDecl *method) { if (IsComparisonOperator(method)) { return method->hasBody(); } + if (IsUserDefinedMoveConstructorOrAssignment(method)) { + return method->hasBody(); + } // Compiler-generated members are covered by derived traits if (method->isImplicit()) { return false; @@ -923,6 +974,9 @@ bool IsMethodOnPtr(const clang::CXXMethodDecl *method) { clang::isa(method)) { return false; } + if (IsUserDefinedMoveConstructorOrAssignment(method)) { + return method->hasBody(); + } if (method->isImplicit() && !IsComparisonOperator(method)) { return false; } diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index df20998c6..d6f05a2a8 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -74,7 +74,12 @@ bool IsUserDefinedMoveConstructor(const clang::CXXConstructorDecl *ctor); bool IsUserDefinedCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor); -bool IsDefaultedMoveConstructor(const clang::CXXConstructorDecl *ctor); +bool IsUserDefinedMoveAssignment(const clang::CXXMethodDecl *method); + +bool IsMemberMemcpy(const clang::CallExpr *expr); + +bool IsUserDefinedMoveConstructorOrAssignment( + const clang::CXXMethodDecl *method); clang::CXXConstructorDecl * GetUserDefinedCopyConstructor(const clang::RecordDecl *decl); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 4c10e3750..dbc423431 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1053,6 +1053,16 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) { return false; } + if (IsMemberMemcpy(expr)) { + ConvertAssignment( + clang::cast(expr->getArg(0)->IgnoreImpCasts()) + ->getSubExpr(), + clang::cast(expr->getArg(1)->IgnoreImpCasts()) + ->getSubExpr(), + "="); + return false; + } + // p->~T() on a scalar is a no-op if (clang::isa( expr->getCallee()->IgnoreParenImpCasts())) { @@ -1063,6 +1073,10 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) { return Converter::VisitCallExpr(expr); } + if (ConvertMemberAssignmentCall(expr)) { + return false; + } + if (auto *opcall = clang::dyn_cast(expr); opcall && !IsUserOperatorCall(opcall) && !Mapper::Contains(expr->getCallee())) { @@ -1892,15 +1906,6 @@ bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { return false; } - // Default move is translated using a bitwise .clone() implementation. - // Bitwise clone is only satisfied by default copy constructor. If the copy - // constructor is user defined, then default move calls copy constructor, - // which is wrong. - if (IsDefaultedMoveConstructor(ctor) && - !HasDefaultedCopyConstructor(ctor->getParent())) { - llvm::report_fatal_error("defaulted move constructor without a fieldwise " - "copy constructor is not supported"); - } if (ctor->isCopyOrMoveConstructor() && !IsUserDefinedCopyOrMoveConstructor(ctor)) { StrCat(PushSuppressIteratorClone::take(*this) @@ -1916,7 +1921,7 @@ bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { return false; } - assert(ctor->isUserProvided()); + assert(ctor->isUserProvided() || IsUserDefinedMoveConstructor(ctor)); if (expr->getType()->isArrayType()) { ConvertArrayCXXConstructExpr(expr); } else { @@ -2667,7 +2672,11 @@ void ConverterRefCount::SetUFCSReceiver(clang::Expr *base, bool is_arrow, } return; } - if (!base->isLValue() && base->getType()->isRecordType() && + auto *moved = clang::dyn_cast(base->IgnoreParenImpCasts()); + bool is_moved_object = + moved && moved->isCallToStdMove() && moved->getArg(0)->isGLValue(); + if (!base->isLValue() && !is_moved_object && + base->getType()->isRecordType() && !IsReferenceType(base->IgnoreImplicit())) { PushConversionKind push(*this, ConversionKind::FullRefCount); ufcs_receiver_ = diff --git a/cpp2rust/converter/plugins/emplace_back.cpp b/cpp2rust/converter/plugins/emplace_back.cpp index c7e6e1e8c..de2cde3dd 100644 --- a/cpp2rust/converter/plugins/emplace_back.cpp +++ b/cpp2rust/converter/plugins/emplace_back.cpp @@ -155,41 +155,45 @@ bool Converter::emplace_back_plugin_convert(clang::CallExpr *call) { auto [elem_ty, ctor] = analyzeEmplaceCall(member_call, GetSema()); assert(!elem_ty.isNull() && "Could not analyze emplace_back type"); - emplace_back_emit_push_open(member_call); - - if (ctor) { - auto is_argument_moved = false; - if (call->getNumArgs() > 0) { - if (auto arg_call = clang::dyn_cast(call->getArg(0))) { - is_argument_moved = arg_call->isCallToStdMove(); + std::string arg; + { + Buffer buf(*this); + if (ctor) { + auto *construct = buildConstructExpr(member_call, GetSema()); + auto is_argument_moved = + construct && construct->getConstructor()->isMoveConstructor() && + !IsUserDefinedMoveConstructor(construct->getConstructor()); + + if (is_argument_moved) { + StrCat("std::mem::take(&mut"); + } + emplace_back_plugin_construct_arg(elem_ty, construct); + if (is_argument_moved) { + StrCat(')'); + } + } else if (elem_ty.isPODType(ctx_)) { + if (call->getNumArgs() == 0) { + StrCat(GetDefaultAsString(elem_ty)); + } else { + assert(call->getNumArgs() == 1 && + "multiple arguments passed for building POD type"); + Convert(call->getArg(0)); + StrCat("as"); + StrCat(GetUnsafeTypeAsString(elem_ty)); } - } - - if (is_argument_moved) { - StrCat("std::mem::take(&mut"); - } - emplace_back_plugin_construct_arg( - elem_ty, buildConstructExpr(member_call, GetSema())); - if (is_argument_moved) { - StrCat(')'); - } - } else if (elem_ty.isPODType(ctx_)) { - if (call->getNumArgs() == 0) { - StrCat(GetDefaultAsString(elem_ty)); } else { - assert(call->getNumArgs() == 1 && - "multiple arguments passed for building POD type"); - Convert(call->getArg(0)); - StrCat("as"); - StrCat(GetUnsafeTypeAsString(elem_ty)); + call->dump(); + assert(0 && "no ctor and no pod type"); + return false; } - } else { - call->dump(); - assert(0 && "no ctor and no pod type"); - return false; + arg = std::move(buf).str(); } + StrCat("{ let __arg = ", arg, ";"); + emplace_back_emit_push_open(member_call); + StrCat("__arg"); emplace_back_emit_push_close(member_call); + StrCat('}'); return true; } diff --git a/tests/multi-file/defaulted_move_cross_tu/CMakeLists.txt b/tests/multi-file/defaulted_move_cross_tu/CMakeLists.txt new file mode 100644 index 000000000..504c2af0e --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16) +project(defaulted_move_cross_tu LANGUAGES CXX) +add_executable(app a.cpp b.cpp) diff --git a/tests/multi-file/defaulted_move_cross_tu/a.cpp b/tests/multi-file/defaulted_move_cross_tu/a.cpp new file mode 100644 index 000000000..3ef5d1a8f --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/a.cpp @@ -0,0 +1,12 @@ +#include + +#include "s.h" + +int sum(const S &s) { return static_cast(s.v.size()) + s.n[0] + s.n[1]; } + +int main() { + S s(2); + assert(sum(s) == 7); + assert(shuffle(3) == 10); + return 0; +} diff --git a/tests/multi-file/defaulted_move_cross_tu/b.cpp b/tests/multi-file/defaulted_move_cross_tu/b.cpp new file mode 100644 index 000000000..193cd0f0a --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/b.cpp @@ -0,0 +1,14 @@ +#include +#include + +#include "s.h" + +int shuffle(int x) { + S a(x); + S b(std::move(a)); + assert(a.v.empty()); + S c(1); + c = std::move(b); + assert(b.v.empty()); + return sum(c); +} diff --git a/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs b/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs new file mode 100644 index 000000000..577d60b4d --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs @@ -0,0 +1,105 @@ +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 S { + pub v: Value>, + pub n: Value>, +} +impl S { + pub fn S(x: i32) -> Self { + let x: Value = Rc::new(RefCell::new(x)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(vec![ + (*x.borrow()); + ((*x.borrow()) as usize) as usize + ])), + n: Rc::new(RefCell::new(Box::new([(*x.borrow()), ((*x.borrow()) + 1)]))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for S { + fn default() -> Self { + S { + v: Rc::new(RefCell::new(Default::default())), + n: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for S { + fn byte_size() -> usize { + 32 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..24]); + (*self.n.borrow()).to_bytes(&mut buf[24..32]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + n: Rc::new(RefCell::new(>::from_bytes(&buf[24..32]))), + } + } +} +pub fn sum_0(s: Ptr) -> i32 { + return { + let _lhs = { + let _lhs = ((*(*s.upgrade().deref()).v.borrow()).len() as i32); + _lhs + (*(*s.upgrade().deref()).n.borrow())[(0) as usize] + }; + _lhs + (*(*s.upgrade().deref()).n.borrow())[(1) as usize] + }; +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let s: Value = Rc::new(RefCell::new(S::S({ 2 }))); + assert!((({ sum_0(s.as_pointer(),) }) == 7)); + assert!((({ shuffle_1(3,) }) == 10)); + return 0; +} +impl S { + pub fn S_pmutS(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(std::mem::take( + &mut (*(*_a0.upgrade().deref()).v.borrow_mut()), + ))), + n: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).n.borrow()).clone())), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +pub fn shuffle_1(x: i32) -> i32 { + let x: Value = Rc::new(RefCell::new(x)); + let a: Value = Rc::new(RefCell::new(S::S({ (*x.borrow()) }))); + let b: Value = Rc::new(RefCell::new(S::S_pmutS({ a.as_pointer() }))); + assert!((*(*a.borrow()).v.borrow()).is_empty()); + let c: Value = Rc::new(RefCell::new(S::S({ 1 }))); + ({ SImpl::operator_assign_pmutS(&c.as_pointer(), b.as_pointer()) }); + assert!((*(*b.borrow()).v.borrow()).is_empty()); + return ({ sum_0(c.as_pointer()) }); +} +pub trait SImpl { + fn operator_assign_pmutS(&self, _a0: Ptr) -> Ptr; +} +impl SImpl for Ptr { + fn operator_assign_pmutS(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).v.as_pointer() as Ptr>).write(std::mem::take( + &mut (*(*_a0.upgrade().deref()).v.borrow_mut()), + )); + let __rhs = (*(*_a0.upgrade().deref()).n.borrow()).clone(); + (*(*(*self).upgrade().deref()).n.borrow_mut()) = __rhs; + return (*self).clone(); + } +} diff --git a/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs b/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs new file mode 100644 index 000000000..1db3eff4e --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs @@ -0,0 +1,68 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive()] +pub struct S { + pub v: Vec, + pub n: [i32; 2], +} +impl S { + pub unsafe fn S(mut x: i32) -> Self { + let mut this = Self { + v: vec![x; (x as usize) as usize], + n: [x, ((x) + (1))], + }; + this + } +} +impl Default for S { + fn default() -> Self { + S { + v: Default::default(), + n: [0_i32; 2], + } + } +} +pub unsafe fn sum_0(s: *const S) -> i32 { + return ((((*s).v.len() as i32) + ((*s).n[(0) as usize])) + ((*s).n[(1) as usize])); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut s: S = S::S({ 2 }); + assert!(((unsafe { sum_0(&s as *const S,) }) == (7))); + assert!(((unsafe { shuffle_1(3,) }) == (10))); + return 0; +} +impl S { + pub unsafe fn S_pmutS(_a0: *mut S) -> Self { + let mut this = Self { + v: std::mem::take(&mut (*_a0).v), + n: (*_a0).n, + }; + this + } + pub unsafe fn operator_assign_pmutS(&mut self, _a0: *mut S) -> *mut S { + self.v = std::mem::take(&mut (*_a0).v); + self.n = ((*_a0).n).clone(); + return &mut (*(self as *mut S)) as *mut S; + } +} +pub unsafe fn shuffle_1(mut x: i32) -> i32 { + let mut a: S = S::S({ x }); + let mut b: S = S::S_pmutS({ &mut a as *mut S }); + assert!(a.v.is_empty()); + let mut c: S = S::S({ 1 }); + (unsafe { S::operator_assign_pmutS(&mut c, &mut b as *mut S) }); + assert!(b.v.is_empty()); + return (unsafe { sum_0(&c as *const S) }); +} diff --git a/tests/multi-file/defaulted_move_cross_tu/s.h b/tests/multi-file/defaulted_move_cross_tu/s.h new file mode 100644 index 000000000..99c1e4170 --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/s.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +struct S { + std::vector v; + int n[2]; + + S(int x) : v(x, x), n{x, x + 1} {} + S(const S &) = delete; + S(S &&) = default; + S &operator=(const S &) = delete; + S &operator=(S &&) = default; +}; + +int sum(const S &s); +int shuffle(int x); diff --git a/tests/unit/copy_move_defaulted.cpp b/tests/unit/copy_move_defaulted.cpp index 8452357c3..f95e9a269 100644 --- a/tests/unit/copy_move_defaulted.cpp +++ b/tests/unit/copy_move_defaulted.cpp @@ -1,4 +1,3 @@ -// translation-fail #include #include #include @@ -50,6 +49,17 @@ struct UserCopyDefaultMove { UserCopyDefaultMove &operator=(UserCopyDefaultMove &&) = default; }; +struct Buffer { + std::vector data; + int n; + int arr[2]; + Buffer(int n) : data(n, n), n(n), arr{n, n + 1} {} + Buffer(const Buffer &) = delete; + Buffer(Buffer &&) = default; + Buffer &operator=(const Buffer &) = delete; + Buffer &operator=(Buffer &&) = default; +}; + static bool same(const Explicit &a, const Explicit &b) { return a.v == b.v && a.inner.x == b.inner.x && a.arr[0] == b.arr[0] && a.arr[1] == b.arr[1]; @@ -101,5 +111,16 @@ int main() { u3 = u2; u4 = std::move(u2); assert(u3.v == 108 && u4.v == 8); + + Buffer p(3); + Buffer q = std::move(p); + assert(q.n == 3 && q.data.size() == 3 && q.data[2] == 3 && p.data.empty()); + Buffer r(1); + r = std::move(q); + assert(r.n == 3 && r.data.size() == 3 && r.arr[1] == 4 && q.data.empty()); + std::vector bufs; + bufs.push_back(std::move(r)); + bufs.emplace_back(std::move(bufs[0])); + assert(bufs[1].n == 3 && bufs[1].data.size() == 3 && bufs[0].data.empty()); return 0; } diff --git a/tests/unit/copy_move_deleted.cpp b/tests/unit/copy_move_deleted.cpp index c635eb03e..4f7eabed1 100644 --- a/tests/unit/copy_move_deleted.cpp +++ b/tests/unit/copy_move_deleted.cpp @@ -1,4 +1,3 @@ -// translation-fail #include #include diff --git a/tests/unit/out/refcount/copy_move_defaulted.rs b/tests/unit/out/refcount/copy_move_defaulted.rs new file mode 100644 index 000000000..e451fd040 --- /dev/null +++ b/tests/unit/out/refcount/copy_move_defaulted.rs @@ -0,0 +1,577 @@ +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 x: Value, +} +impl Clone for Inner { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + x: Rc::new(RefCell::new((*self.x.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for Inner { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.x.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + x: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive()] +pub struct Explicit { + pub v: Value, + pub inner: Value, + pub arr: Value>, +} +impl Explicit { + pub fn Explicit(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*v.borrow()))), + inner: Rc::new(RefCell::new(Inner { + x: Rc::new(RefCell::new(((*v.borrow()) * 10))), + })), + arr: Rc::new(RefCell::new(Box::new([(*v.borrow()), ((*v.borrow()) + 1)]))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Clone for Explicit { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*self.v.borrow()))), + inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())), + arr: Rc::new(RefCell::new((*self.arr.borrow()).clone())), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Explicit { + fn default() -> Self { + Explicit { + v: >::default(), + inner: >::default(), + arr: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for Explicit { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + (*self.inner.borrow()).to_bytes(&mut buf[4..8]); + (*self.arr.borrow()).to_bytes(&mut buf[8..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + inner: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + arr: Rc::new(RefCell::new(>::from_bytes(&buf[8..16]))), + } + } +} +#[derive()] +pub struct Implicit { + pub v: Value, + pub inner: Value, + pub arr: Value>, +} +impl Clone for Implicit { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*self.v.borrow()))), + inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())), + arr: Rc::new(RefCell::new((*self.arr.borrow()).clone())), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Implicit { + fn default() -> Self { + Implicit { + v: >::default(), + inner: >::default(), + arr: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for Implicit { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + (*self.inner.borrow()).to_bytes(&mut buf[4..8]); + (*self.arr.borrow()).to_bytes(&mut buf[8..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + inner: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + arr: Rc::new(RefCell::new(>::from_bytes(&buf[8..16]))), + } + } +} +#[derive(Default)] +pub struct DefaultCopyUserMove { + pub v: Value, +} +impl DefaultCopyUserMove { + pub fn DefaultCopyUserMove(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn DefaultCopyUserMove_pmutDefaultCopyUserMove(o: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*o.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Clone for DefaultCopyUserMove { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*self.v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for DefaultCopyUserMove { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive(Default)] +pub struct UserCopyDefaultMove { + pub v: Value, +} +impl UserCopyDefaultMove { + pub fn UserCopyDefaultMove(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn UserCopyDefaultMove_pconstUserCopyDefaultMove(o: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(((*(*o.upgrade().deref()).v.borrow()) + 100))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn UserCopyDefaultMove_pmutUserCopyDefaultMove(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Clone for UserCopyDefaultMove { + fn clone(&self) -> Self { + let __src: Value = + Rc::new(RefCell::new(UserCopyDefaultMove { v: self.v.clone() })); + UserCopyDefaultMove::UserCopyDefaultMove_pconstUserCopyDefaultMove(__src.as_pointer()) + } +} +impl ByteRepr for UserCopyDefaultMove { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive()] +pub struct Buffer { + pub data: Value>, + pub n: Value, + pub arr: Value>, +} +impl Buffer { + pub fn Buffer(n: i32) -> Self { + let n: Value = Rc::new(RefCell::new(n)); + let __this: Value = Rc::new(RefCell::new(Self { + data: Rc::new(RefCell::new(vec![ + (*n.borrow()); + ((*n.borrow()) as usize) as usize + ])), + n: Rc::new(RefCell::new((*n.borrow()))), + arr: Rc::new(RefCell::new(Box::new([(*n.borrow()), ((*n.borrow()) + 1)]))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn Buffer_pmutBuffer(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + data: Rc::new(RefCell::new(std::mem::take( + &mut (*(*_a0.upgrade().deref()).data.borrow_mut()), + ))), + n: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).n.borrow()))), + arr: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).arr.borrow()).clone(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Buffer { + fn default() -> Self { + Buffer { + data: Rc::new(RefCell::new(Default::default())), + n: >::default(), + arr: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for Buffer { + fn byte_size() -> usize { + 40 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.data.borrow()).to_bytes(&mut buf[0..24]); + (*self.n.borrow()).to_bytes(&mut buf[24..28]); + (*self.arr.borrow()).to_bytes(&mut buf[28..36]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + data: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + n: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), + arr: Rc::new(RefCell::new(>::from_bytes(&buf[28..36]))), + } + } +} +pub fn same_0(a: Ptr, b: Ptr) -> bool { + return ((({ + let _lhs = (*(*a.upgrade().deref()).v.borrow()); + _lhs == (*(*b.upgrade().deref()).v.borrow()) + }) && ({ + let _lhs = (*(*(*a.upgrade().deref()).inner.borrow()).x.borrow()); + _lhs == (*(*(*b.upgrade().deref()).inner.borrow()).x.borrow()) + })) && ({ + let _lhs = (*(*a.upgrade().deref()).arr.borrow())[(0) as usize]; + _lhs == (*(*b.upgrade().deref()).arr.borrow())[(0) as usize] + })) && ({ + let _lhs = (*(*a.upgrade().deref()).arr.borrow())[(1) as usize]; + _lhs == (*(*b.upgrade().deref()).arr.borrow())[(1) as usize] + }); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value = Rc::new(RefCell::new(Explicit::Explicit({ 1 }))); + let _dtor_a = ScopedDestructor::new(&a, |__p| __p.destructor()); + let b: Value = Rc::new(RefCell::new((*a.borrow()).clone())); + let _dtor_b = ScopedDestructor::new(&b, |__p| __p.destructor()); + let c: Value = Rc::new(RefCell::new((*a.borrow()).clone())); + let _dtor_c = ScopedDestructor::new(&c, |__p| __p.destructor()); + let d: Value = Rc::new(RefCell::new((*a.borrow()).clone())); + let _dtor_d = ScopedDestructor::new(&d, |__p| __p.destructor()); + assert!( + (({ same_0(b.as_pointer(), a.as_pointer(),) }) + && ({ same_0(c.as_pointer(), a.as_pointer(),) })) + && ({ same_0(d.as_pointer(), a.as_pointer(),) }) + ); + let e: Value = Rc::new(RefCell::new(Explicit::Explicit({ 2 }))); + let _dtor_e = ScopedDestructor::new(&e, |__p| __p.destructor()); + let f: Value = Rc::new(RefCell::new(Explicit::Explicit({ 3 }))); + let _dtor_f = ScopedDestructor::new(&f, |__p| __p.destructor()); + (*e.borrow_mut()) = (*b.borrow()).clone(); + (*f.borrow_mut()) = (*c.borrow()).clone(); + assert!( + ({ same_0(e.as_pointer(), b.as_pointer(),) }) + && ({ same_0(f.as_pointer(), c.as_pointer(),) }) + ); + let g: Value = Rc::new(RefCell::new(Explicit::Explicit({ 4 }))); + let _dtor_g = ScopedDestructor::new(&g, |__p| __p.destructor()); + (*g.borrow_mut()) = { + (*e.borrow_mut()) = (*f.borrow()).clone(); + (*e.borrow()).clone() + }; + assert!( + ({ same_0(g.as_pointer(), f.as_pointer(),) }) + && ({ same_0(e.as_pointer(), f.as_pointer(),) }) + ); + let i: Value = Rc::new(RefCell::new(Implicit { + v: Rc::new(RefCell::new(5)), + inner: Rc::new(RefCell::new(Inner { + x: Rc::new(RefCell::new(50)), + })), + arr: Rc::new(RefCell::new(Box::new([5, 6]))), + })); + let j: Value = Rc::new(RefCell::new((*i.borrow()).clone())); + let k: Value = Rc::new(RefCell::new((*i.borrow()).clone())); + assert!( + (((*(*j.borrow()).v.borrow()) == 5) + && ((*(*(*j.borrow()).inner.borrow()).x.borrow()) == 50)) + && ((*(*j.borrow()).arr.borrow())[(1) as usize] == 6) + ); + assert!(((*(*i.borrow()).v.borrow()) == 5) && ((*(*k.borrow()).v.borrow()) == 5)); + let l: Value = Rc::new(RefCell::new(Implicit { + v: Rc::new(RefCell::new(0)), + inner: Rc::new(RefCell::new(Inner { + x: Rc::new(RefCell::new(0)), + })), + arr: Rc::new(RefCell::new(Box::new([0, 0]))), + })); + (*l.borrow_mut()) = (*j.borrow()).clone(); + assert!( + (((*(*l.borrow()).v.borrow()) == 5) + && ((*(*(*l.borrow()).inner.borrow()).x.borrow()) == 50)) + && ((*(*l.borrow()).arr.borrow())[(0) as usize] == 5) + ); + let vec_: Value> = Rc::new(RefCell::new(Vec::new())); + { + let a0_clone = (*b.borrow()).clone(); + (*vec_.borrow_mut()).push(a0_clone) + }; + (*vec_.borrow_mut()).push(Explicit::Explicit({ 9 })); + assert!( + ((*(*(vec_.as_pointer() as Ptr) + .offset(0_usize) + .upgrade() + .deref()) + .v + .borrow()) + == 1) + && ((*(*(vec_.as_pointer() as Ptr) + .offset(1_usize) + .upgrade() + .deref()) + .v + .borrow()) + == 9) + ); + let m: Value = + Rc::new(RefCell::new(DefaultCopyUserMove::DefaultCopyUserMove({ + 7 + }))); + let m1: Value = Rc::new(RefCell::new((*m.borrow()).clone())); + let m2: Value = Rc::new(RefCell::new( + DefaultCopyUserMove::DefaultCopyUserMove_pmutDefaultCopyUserMove({ m.as_pointer() }), + )); + assert!( + (((*(*m1.borrow()).v.borrow()) == 7) && ((*(*m2.borrow()).v.borrow()) == 7)) + && ((*(*m.borrow()).v.borrow()) == 0) + ); + let m3: Value = + Rc::new(RefCell::new(DefaultCopyUserMove::DefaultCopyUserMove({ + 1 + }))); + let m4: Value = + Rc::new(RefCell::new(DefaultCopyUserMove::DefaultCopyUserMove({ + 1 + }))); + (*m3.borrow_mut()) = (*m1.borrow()).clone(); + ({ + DefaultCopyUserMoveImpl::operator_assign_pmutDefaultCopyUserMove( + &m4.as_pointer(), + m1.as_pointer(), + ) + }); + assert!( + (((*(*m3.borrow()).v.borrow()) == 7) && ((*(*m4.borrow()).v.borrow()) == 7)) + && ((*(*m1.borrow()).v.borrow()) == 0) + ); + let u: Value = + Rc::new(RefCell::new(UserCopyDefaultMove::UserCopyDefaultMove({ + 8 + }))); + let u1: Value = Rc::new(RefCell::new( + UserCopyDefaultMove::UserCopyDefaultMove_pconstUserCopyDefaultMove({ u.as_pointer() }), + )); + let u2: Value = Rc::new(RefCell::new( + UserCopyDefaultMove::UserCopyDefaultMove_pmutUserCopyDefaultMove({ u.as_pointer() }), + )); + assert!( + (((*(*u1.borrow()).v.borrow()) == 108) && ((*(*u2.borrow()).v.borrow()) == 8)) + && ((*(*u.borrow()).v.borrow()) == 8) + ); + let u3: Value = + Rc::new(RefCell::new(UserCopyDefaultMove::UserCopyDefaultMove({ + 1 + }))); + let u4: Value = + Rc::new(RefCell::new(UserCopyDefaultMove::UserCopyDefaultMove({ + 1 + }))); + ({ + UserCopyDefaultMoveImpl::operator_assign_pconstUserCopyDefaultMove( + &u3.as_pointer(), + u2.as_pointer(), + ) + }); + ({ + UserCopyDefaultMoveImpl::operator_assign_pmutUserCopyDefaultMove( + &u4.as_pointer(), + u2.as_pointer(), + ) + }); + assert!(((*(*u3.borrow()).v.borrow()) == 108) && ((*(*u4.borrow()).v.borrow()) == 8)); + let p: Value = Rc::new(RefCell::new(Buffer::Buffer({ 3 }))); + let q: Value = Rc::new(RefCell::new(Buffer::Buffer_pmutBuffer({ p.as_pointer() }))); + assert!( + ((((*(*q.borrow()).n.borrow()) == 3) && ((*(*q.borrow()).data.borrow()).len() == 3_usize)) + && ((((*q.borrow()).data.as_pointer() as Ptr) + .offset(2_usize) + .read()) + == 3)) + && ((*(*p.borrow()).data.borrow()).is_empty()) + ); + let r: Value = Rc::new(RefCell::new(Buffer::Buffer({ 1 }))); + ({ BufferImpl::operator_assign_pmutBuffer(&r.as_pointer(), q.as_pointer()) }); + assert!( + ((((*(*r.borrow()).n.borrow()) == 3) && ((*(*r.borrow()).data.borrow()).len() == 3_usize)) + && ((*(*r.borrow()).arr.borrow())[(1) as usize] == 4)) + && ((*(*q.borrow()).data.borrow()).is_empty()) + ); + let bufs: Value> = Rc::new(RefCell::new(Vec::new())); + (*bufs.borrow_mut()).push(std::mem::take(&mut (*r.borrow_mut()))); + { + let __arg = + Buffer::Buffer_pmutBuffer({ (bufs.as_pointer() as Ptr).offset(0_usize) }); + bufs.as_pointer() + .with_mut(|__v: &mut Vec| __v.push(__arg)) + }; + assert!( + (((*(*(bufs.as_pointer() as Ptr) + .offset(1_usize) + .upgrade() + .deref()) + .n + .borrow()) + == 3) + && ((*(*(bufs.as_pointer() as Ptr) + .offset(1_usize) + .upgrade() + .deref()) + .data + .borrow()) + .len() + == 3_usize)) + && ((*(*(bufs.as_pointer() as Ptr) + .offset(0_usize) + .upgrade() + .deref()) + .data + .borrow()) + .is_empty()) + ); + return 0; +} +pub trait BufferImpl { + fn operator_assign_pmutBuffer(&self, _a0: Ptr) -> Ptr; +} +impl BufferImpl for Ptr { + fn operator_assign_pmutBuffer(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).data.as_pointer() as Ptr>).write(std::mem::take( + &mut (*(*_a0.upgrade().deref()).data.borrow_mut()), + )); + let __rhs = (*(*_a0.upgrade().deref()).n.borrow()); + (*(*(*self).upgrade().deref()).n.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).arr.borrow()).clone(); + (*(*(*self).upgrade().deref()).arr.borrow_mut()) = __rhs; + return (*self).clone(); + } +} +pub trait DefaultCopyUserMoveImpl { + fn operator_assign_pmutDefaultCopyUserMove( + &self, + o: Ptr, + ) -> Ptr; +} +impl DefaultCopyUserMoveImpl for Ptr { + fn operator_assign_pmutDefaultCopyUserMove( + &self, + o: Ptr, + ) -> Ptr { + let __rhs = (*(*o.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + return (*self).clone(); + } +} +pub trait ExplicitImpl { + fn destructor(&self); +} +impl ExplicitImpl for Ptr { + fn destructor(&self) {} +} +pub trait UserCopyDefaultMoveImpl { + fn operator_assign_pconstUserCopyDefaultMove( + &self, + o: Ptr, + ) -> Ptr; + fn operator_assign_pmutUserCopyDefaultMove( + &self, + _a0: Ptr, + ) -> Ptr; +} +impl UserCopyDefaultMoveImpl for Ptr { + fn operator_assign_pconstUserCopyDefaultMove( + &self, + o: Ptr, + ) -> Ptr { + let __rhs = ((*(*o.upgrade().deref()).v.borrow()) + 100); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + return (*self).clone(); + } + fn operator_assign_pmutUserCopyDefaultMove( + &self, + _a0: Ptr, + ) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/copy_move_deleted.rs b/tests/unit/out/refcount/copy_move_deleted.rs new file mode 100644 index 000000000..2c2b46a02 --- /dev/null +++ b/tests/unit/out/refcount/copy_move_deleted.rs @@ -0,0 +1,212 @@ +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 NoCopy { + pub v: Value, +} +impl NoCopy { + pub fn NoCopy(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn NoCopy_pmutNoCopy(o: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*o.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for NoCopy { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive()] +pub struct PrivateCopy { + pub v: Value, +} +impl PrivateCopy { + pub fn PrivateCopy() -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(0)), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn PrivateCopy_pmutPrivateCopy(o: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*o.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for PrivateCopy { + fn default() -> Self { + { PrivateCopy::PrivateCopy() } + } +} +impl ByteRepr for PrivateCopy { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive()] +pub struct Immovable { + pub v: Value, +} +impl Immovable { + pub fn Immovable() -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(0)), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Immovable { + fn default() -> Self { + { Immovable::Immovable() } + } +} +impl ByteRepr for Immovable { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive(Default)] +pub struct Container { + pub inner: Value, + pub tag: Value, +} +impl Container { + pub fn Container_pmutContainer(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + inner: Rc::new(RefCell::new(NoCopy::NoCopy_pmutNoCopy({ + (*_a0.upgrade().deref()).inner.as_pointer() + }))), + tag: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).tag.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for Container { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.inner.borrow()).to_bytes(&mut buf[0..4]); + (*self.tag.borrow()).to_bytes(&mut buf[4..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + inner: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + tag: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + } + } +} +pub fn bump_0(p: Ptr) { + let p: Value> = Rc::new(RefCell::new(p)); + (*(*(*p.borrow()).upgrade().deref()).v.borrow_mut()).postfix_inc(); +} +pub fn bump_ref_1(r: Ptr) { + (*(*r.upgrade().deref()).v.borrow_mut()).postfix_inc(); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value = Rc::new(RefCell::new(NoCopy::NoCopy({ 1 }))); + let b: Value = Rc::new(RefCell::new(NoCopy::NoCopy_pmutNoCopy({ a.as_pointer() }))); + assert!(((*(*b.borrow()).v.borrow()) == 1) && ((*(*a.borrow()).v.borrow()) == 0)); + ({ NoCopyImpl::operator_assign_pmutNoCopy(&a.as_pointer(), b.as_pointer()) }); + assert!(((*(*a.borrow()).v.borrow()) == 1) && ((*(*b.borrow()).v.borrow()) == 0)); + ({ bump_0((a.as_pointer())) }); + assert!(((*(*a.borrow()).v.borrow()) == 2)); + let p: Value = Rc::new(RefCell::new(PrivateCopy::PrivateCopy())); + (*(*p.borrow()).v.borrow_mut()) = 3; + let q: Value = Rc::new(RefCell::new(PrivateCopy::PrivateCopy_pmutPrivateCopy({ + p.as_pointer() + }))); + assert!(((*(*q.borrow()).v.borrow()) == 3) && ((*(*p.borrow()).v.borrow()) == 0)); + ({ PrivateCopyImpl::operator_assign_pmutPrivateCopy(&p.as_pointer(), q.as_pointer()) }); + assert!(((*(*p.borrow()).v.borrow()) == 3) && ((*(*q.borrow()).v.borrow()) == 0)); + let im: Value = Rc::new(RefCell::new(Immovable::Immovable())); + (*(*im.borrow()).v.borrow_mut()) = 4; + ({ bump_ref_1(im.as_pointer()) }); + let pim: Value> = Rc::new(RefCell::new((im.as_pointer()))); + assert!(((*(*(*pim.borrow()).upgrade().deref()).v.borrow()) == 5)); + let c: Value = Rc::new(RefCell::new(Container { + inner: Rc::new(RefCell::new(NoCopy::NoCopy({ 6 }))), + tag: Rc::new(RefCell::new(7)), + })); + let d: Value = Rc::new(RefCell::new(Container::Container_pmutContainer({ + c.as_pointer() + }))); + assert!( + (((*(*(*d.borrow()).inner.borrow()).v.borrow()) == 6) + && ((*(*d.borrow()).tag.borrow()) == 7)) + && ((*(*(*c.borrow()).inner.borrow()).v.borrow()) == 0) + ); + return 0; +} +pub trait NoCopyImpl { + fn operator_assign_pmutNoCopy(&self, o: Ptr) -> Ptr; +} +impl NoCopyImpl for Ptr { + fn operator_assign_pmutNoCopy(&self, o: Ptr) -> Ptr { + let __rhs = (*(*o.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + return (*self).clone(); + } +} +pub trait PrivateCopyImpl { + fn operator_assign_pmutPrivateCopy(&self, o: Ptr) -> Ptr; +} +impl PrivateCopyImpl for Ptr { + fn operator_assign_pmutPrivateCopy(&self, o: Ptr) -> Ptr { + let __rhs = (*(*o.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/empty_main.rs b/tests/unit/out/refcount/empty_main.rs index 4e280a57e..be7ceea31 100644 --- a/tests/unit/out/refcount/empty_main.rs +++ b/tests/unit/out/refcount/empty_main.rs @@ -22,6 +22,8 @@ pub fn main() { (*argv.borrow_mut()).push(Ptr::null()); ::std::process::exit(main_0(::std::env::args().len() as i32, argv.as_pointer())); } -fn main_0(_: i32, _: Ptr>) -> i32 { +fn main_0(_a0: i32, _a1: Ptr>) -> i32 { + let _a0: Value = Rc::new(RefCell::new(_a0)); + let _a1: Value>> = Rc::new(RefCell::new(_a1)); return 0; } diff --git a/tests/unit/out/refcount/huffman.rs b/tests/unit/out/refcount/huffman.rs index 0b622cb5f..9b46de39d 100644 --- a/tests/unit/out/refcount/huffman.rs +++ b/tests/unit/out/refcount/huffman.rs @@ -82,6 +82,23 @@ pub struct MinHeap { pub next: Value, pub alloc: Value>>>, } +impl MinHeap { + pub fn MinHeap_pmutMinHeap(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + size: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).size.borrow()))), + capacity: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).capacity.borrow()))), + arr: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).arr.borrow_mut()).take(), + )), + next: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).next.borrow()))), + alloc: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).alloc.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for MinHeap { fn byte_size() -> usize { 32 diff --git a/tests/unit/out/refcount/operator_arithmetic_free.rs b/tests/unit/out/refcount/operator_arithmetic_free.rs index 4ed526dab..ebbf39a7a 100644 --- a/tests/unit/out/refcount/operator_arithmetic_free.rs +++ b/tests/unit/out/refcount/operator_arithmetic_free.rs @@ -86,7 +86,8 @@ pub fn operator_inc_7(a: Ptr) -> Ptr { (*(*a.upgrade().deref()).v.borrow_mut()).prefix_inc(); return (a).clone(); } -pub fn operator_post_inc_8(a: Ptr, _: i32) -> S { +pub fn operator_post_inc_8(a: Ptr, _a1: i32) -> S { + let _a1: Value = Rc::new(RefCell::new(_a1)); let old: Value = Rc::new(RefCell::new((*a.upgrade().deref()).clone())); (*(*a.upgrade().deref()).v.borrow_mut()).prefix_inc(); return (*old.borrow()).clone(); @@ -95,7 +96,8 @@ pub fn operator_dec_9(a: Ptr) -> Ptr { (*(*a.upgrade().deref()).v.borrow_mut()).prefix_dec(); return (a).clone(); } -pub fn operator_post_dec_10(a: Ptr, _: i32) -> S { +pub fn operator_post_dec_10(a: Ptr, _a1: i32) -> S { + let _a1: Value = Rc::new(RefCell::new(_a1)); let old: Value = Rc::new(RefCell::new((*a.upgrade().deref()).clone())); (*(*a.upgrade().deref()).v.borrow_mut()).prefix_dec(); return (*old.borrow()).clone(); diff --git a/tests/unit/out/refcount/operator_arithmetic_member.rs b/tests/unit/out/refcount/operator_arithmetic_member.rs index 5dcf3ff74..b1065522d 100644 --- a/tests/unit/out/refcount/operator_arithmetic_member.rs +++ b/tests/unit/out/refcount/operator_arithmetic_member.rs @@ -123,9 +123,9 @@ pub trait SImpl { fn operator_pos_const(&self) -> S; fn operator_neg_const(&self) -> S; fn operator_inc(&self) -> Ptr; - fn operator_post_inc_i32(&self, _: i32) -> S; + fn operator_post_inc_i32(&self, _a0: i32) -> S; fn operator_dec(&self) -> Ptr; - fn operator_post_dec_i32(&self, _: i32) -> S; + fn operator_post_dec_i32(&self, _a0: i32) -> S; } impl SImpl for Ptr { fn operator_add_pconstS_const(&self, o: Ptr) -> S { @@ -182,7 +182,8 @@ impl SImpl for Ptr { (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_inc(); return (*self).clone(); } - fn operator_post_inc_i32(&self, _: i32) -> S { + fn operator_post_inc_i32(&self, _a0: i32) -> S { + let _a0: Value = Rc::new(RefCell::new(_a0)); let old: Value = Rc::new(RefCell::new((*(*self).upgrade().deref()).clone())); (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_inc(); return (*old.borrow()).clone(); @@ -191,7 +192,8 @@ impl SImpl for Ptr { (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_dec(); return (*self).clone(); } - fn operator_post_dec_i32(&self, _: i32) -> S { + fn operator_post_dec_i32(&self, _a0: i32) -> S { + let _a0: Value = Rc::new(RefCell::new(_a0)); let old: Value = Rc::new(RefCell::new((*(*self).upgrade().deref()).clone())); (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_dec(); return (*old.borrow()).clone(); diff --git a/tests/unit/out/refcount/operator_comparison_defaulted.rs b/tests/unit/out/refcount/operator_comparison_defaulted.rs index 696557263..8d8c3fa81 100644 --- a/tests/unit/out/refcount/operator_comparison_defaulted.rs +++ b/tests/unit/out/refcount/operator_comparison_defaulted.rs @@ -527,21 +527,21 @@ fn main_0() -> i32 { return 0; } pub trait BothImpl { - fn operator_eq(&self, _arg0: Ptr) -> bool; - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; + fn operator_eq(&self, _a0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; } impl BothImpl for Ptr { - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return { let _lhs = (*(*(*self).upgrade().deref()).a.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).a.borrow()) + _lhs == (*(*_a0.upgrade().deref()).a.borrow()) }; } - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).a.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).a.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).a.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -551,15 +551,15 @@ impl BothImpl for Ptr { } } pub trait CmpImpl { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; - fn operator_eq(&self, _arg0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; + fn operator_eq(&self, _a0: Ptr) -> bool; } impl CmpImpl for Ptr { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).a.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).a.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).a.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -568,7 +568,7 @@ impl CmpImpl for Ptr { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).b.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).b.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).b.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -576,40 +576,40 @@ impl CmpImpl for Ptr { } return std::cmp::Ordering::Equal; } - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return ({ let _lhs = (*(*(*self).upgrade().deref()).a.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).a.borrow()) + _lhs == (*(*_a0.upgrade().deref()).a.borrow()) }) && ({ let _lhs = (*(*(*self).upgrade().deref()).b.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).b.borrow()) + _lhs == (*(*_a0.upgrade().deref()).b.borrow()) }); } } pub trait EqImpl { - fn operator_eq(&self, _arg0: Ptr) -> bool; + fn operator_eq(&self, _a0: Ptr) -> bool; } impl EqImpl for Ptr { - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return ({ let _lhs = (*(*(*self).upgrade().deref()).a.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).a.borrow()) + _lhs == (*(*_a0.upgrade().deref()).a.borrow()) }) && ({ let _lhs = (*(*(*self).upgrade().deref()).b.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).b.borrow()) + _lhs == (*(*_a0.upgrade().deref()).b.borrow()) }); } } pub trait InnerImpl { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; - fn operator_eq(&self, _arg0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; + fn operator_eq(&self, _a0: Ptr) -> bool; } impl InnerImpl for Ptr { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).x.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).x.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).x.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -617,22 +617,22 @@ impl InnerImpl for Ptr { } return std::cmp::Ordering::Equal; } - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return { let _lhs = (*(*(*self).upgrade().deref()).x.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).x.borrow()) + _lhs == (*(*_a0.upgrade().deref()).x.borrow()) }; } } pub trait OrdOnlyImpl { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; } impl OrdOnlyImpl for Ptr { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).a.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).a.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).a.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -642,15 +642,15 @@ impl OrdOnlyImpl for Ptr { } } pub trait OuterImpl { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; - fn operator_eq(&self, _arg0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; + fn operator_eq(&self, _a0: Ptr) -> bool; } impl OuterImpl for Ptr { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( ({ - let _arg0: Ptr = (*_arg0.upgrade().deref()).i.as_pointer(); + let _arg0: Ptr = (*_a0.upgrade().deref()).i.as_pointer(); InnerImpl::operator_cmp(&(*(*self).upgrade().deref()).i.as_pointer(), _arg0) }), )); @@ -661,7 +661,7 @@ impl OuterImpl for Ptr { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).y.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).y.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).y.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -669,41 +669,41 @@ impl OuterImpl for Ptr { } return std::cmp::Ordering::Equal; } - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return ({ - let _arg0: Ptr = (*_arg0.upgrade().deref()).i.as_pointer(); + let _arg0: Ptr = (*_a0.upgrade().deref()).i.as_pointer(); InnerImpl::operator_eq(&(*(*self).upgrade().deref()).i.as_pointer(), _arg0) }) && ({ let _lhs = (*(*(*self).upgrade().deref()).y.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).y.borrow()) + _lhs == (*(*_a0.upgrade().deref()).y.borrow()) }); } } pub trait SecondaryImpl { - fn operator_eq(&self, _arg0: Ptr) -> bool; - fn operator_ne(&self, _arg0: Ptr) -> bool; - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; - fn operator_lt(&self, _arg0: Ptr) -> bool; - fn operator_ge(&self, _arg0: Ptr) -> bool; + fn operator_eq(&self, _a0: Ptr) -> bool; + fn operator_ne(&self, _a0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; + fn operator_lt(&self, _a0: Ptr) -> bool; + fn operator_ge(&self, _a0: Ptr) -> bool; } impl SecondaryImpl for Ptr { - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return { let _lhs = (*(*(*self).upgrade().deref()).a.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).a.borrow()) + _lhs == (*(*_a0.upgrade().deref()).a.borrow()) }; } - fn operator_ne(&self, _arg0: Ptr) -> bool { + fn operator_ne(&self, _a0: Ptr) -> bool { return !({ - let _arg0: Ptr = (_arg0).clone(); + let _arg0: Ptr = (_a0).clone(); SecondaryImpl::operator_eq(&(*self), _arg0) }); } - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).a.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).a.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).a.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -711,15 +711,15 @@ impl SecondaryImpl for Ptr { } return std::cmp::Ordering::Equal; } - fn operator_lt(&self, _arg0: Ptr) -> bool { + fn operator_lt(&self, _a0: Ptr) -> bool { return ({ - let _arg0: Ptr = (_arg0).clone(); + let _arg0: Ptr = (_a0).clone(); SecondaryImpl::operator_cmp(&(*self), _arg0) }) == std::cmp::Ordering::Less; } - fn operator_ge(&self, _arg0: Ptr) -> bool { + fn operator_ge(&self, _a0: Ptr) -> bool { return ({ - let _arg0: Ptr = (_arg0).clone(); + let _arg0: Ptr = (_a0).clone(); SecondaryImpl::operator_cmp(&(*self), _arg0) }) != std::cmp::Ordering::Less; } diff --git a/tests/unit/out/refcount/push_emplace_back.rs b/tests/unit/out/refcount/push_emplace_back.rs index e547adace..581d32446 100644 --- a/tests/unit/out/refcount/push_emplace_back.rs +++ b/tests/unit/out/refcount/push_emplace_back.rs @@ -161,31 +161,32 @@ pub fn emplace_local_from_field_4(jpg: Ptr, cond: bool) { } else { (*dest.borrow_mut()) = ((*(*jpg.borrow()).upgrade().deref()).app_data.as_pointer()); } - (*dest.borrow()) - .to_strong() - .as_pointer() - .with_mut(|__v: &mut Vec>>| { - __v.push(Rc::new(RefCell::new({ - let __count = (head.as_pointer() as Ptr) - .offset((3) as isize) - .get_offset() - - (head.as_pointer() as Ptr).get_offset(); - PtrValueIter::new(&(head.as_pointer() as Ptr), __count) - .map(|item| u8::try_from(item).ok().unwrap()) - .collect::>() - }))) - }); + { + let __arg = Rc::new(RefCell::new({ + let __count = (head.as_pointer() as Ptr) + .offset((3) as isize) + .get_offset() + - (head.as_pointer() as Ptr).get_offset(); + PtrValueIter::new(&(head.as_pointer() as Ptr), __count) + .map(|item| u8::try_from(item).ok().unwrap()) + .collect::>() + })); + (*dest.borrow()) + .to_strong() + .as_pointer() + .with_mut(|__v: &mut Vec>>| __v.push(__arg)) + }; } pub fn nested_emplace_move_5(bw: Ptr) { let bw: Value> = Rc::new(RefCell::new(bw)); - (*(*(*bw.borrow()).upgrade().deref()).output.borrow()) - .to_strong() - .as_pointer() - .with_mut(|__v: &mut Vec| { - __v.push(std::mem::take( - &mut (*(*(*bw.borrow()).upgrade().deref()).chunk.borrow()).clone(), - )) - }); + { + let __arg = + std::mem::take(&mut (*(*(*bw.borrow()).upgrade().deref()).chunk.borrow()).clone()); + (*(*(*bw.borrow()).upgrade().deref()).output.borrow()) + .to_strong() + .as_pointer() + .with_mut(|__v: &mut Vec| __v.push(__arg)) + }; } pub fn self_ref_push_6(comps: Ptr>) { let comps: Value>> = Rc::new(RefCell::new(comps)); diff --git a/tests/unit/out/refcount/unique_ptr.rs b/tests/unit/out/refcount/unique_ptr.rs index 057d2497d..91ab24ae6 100644 --- a/tests/unit/out/refcount/unique_ptr.rs +++ b/tests/unit/out/refcount/unique_ptr.rs @@ -10,6 +10,17 @@ use std::rc::{Rc, Weak}; pub struct SafePointer { pub ptr: Value>>, } +impl SafePointer { + pub fn SafePointer_pmutSafePointer(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + ptr: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).ptr.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for SafePointer { fn byte_size() -> usize { 8 diff --git a/tests/unit/out/refcount/unique_ptr_nested.rs b/tests/unit/out/refcount/unique_ptr_nested.rs index 7f5be219b..31a78b45a 100644 --- a/tests/unit/out/refcount/unique_ptr_nested.rs +++ b/tests/unit/out/refcount/unique_ptr_nested.rs @@ -40,6 +40,17 @@ impl ByteRepr for Inner { pub struct Outer { pub inner: Value>>, } +impl Outer { + pub fn Outer_pmutOuter(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + inner: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).inner.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for Outer { fn byte_size() -> usize { 8 diff --git a/tests/unit/out/refcount/vector_with_allocator.rs b/tests/unit/out/refcount/vector_with_allocator.rs index 4246ce5ea..288910bdf 100644 --- a/tests/unit/out/refcount/vector_with_allocator.rs +++ b/tests/unit/out/refcount/vector_with_allocator.rs @@ -341,7 +341,7 @@ fn main_0() -> i32 { } pub trait TestAllocator_double_Impl { fn allocate(&self, n: usize) -> Ptr; - fn deallocate(&self, p: Ptr, _: usize); + fn deallocate(&self, p: Ptr, _a1: usize); } impl TestAllocator_double_Impl for Ptr { fn allocate(&self, n: usize) -> Ptr { @@ -352,14 +352,15 @@ impl TestAllocator_double_Impl for Ptr { .collect::>(), ); } - fn deallocate(&self, p: Ptr, _: usize) { + fn deallocate(&self, p: Ptr, _a1: usize) { let p: Value> = Rc::new(RefCell::new(p)); + let _a1: Value = Rc::new(RefCell::new(_a1)); (*p.borrow()).delete_array(); } } pub trait TestAllocator_int_Impl { fn allocate(&self, n: usize) -> Ptr; - fn deallocate(&self, p: Ptr, _: usize); + fn deallocate(&self, p: Ptr, _a1: usize); } impl TestAllocator_int_Impl for Ptr { fn allocate(&self, n: usize) -> Ptr { @@ -370,8 +371,9 @@ impl TestAllocator_int_Impl for Ptr { .collect::>(), ); } - fn deallocate(&self, p: Ptr, _: usize) { + fn deallocate(&self, p: Ptr, _a1: usize) { let p: Value> = Rc::new(RefCell::new(p)); + let _a1: Value = Rc::new(RefCell::new(_a1)); (*p.borrow()).delete_array(); } } diff --git a/tests/unit/out/unsafe/copy_ctor.rs b/tests/unit/out/unsafe/copy_ctor.rs index 5bbe7906c..8df79bb6c 100644 --- a/tests/unit/out/unsafe/copy_ctor.rs +++ b/tests/unit/out/unsafe/copy_ctor.rs @@ -80,7 +80,7 @@ pub unsafe fn by_value_1(mut c: Counted) -> i32 { } pub unsafe fn make_2(mut v: i32) -> Counted { let mut c: Counted = Counted::Counted({ v }); - return Counted::Counted_pconstCounted({ &mut c }); + return Counted::Counted_pconstCounted({ &c as *const Counted }); } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/copy_move_defaulted.rs b/tests/unit/out/unsafe/copy_move_defaulted.rs new file mode 100644 index 000000000..0d38c53d8 --- /dev/null +++ b/tests/unit/out/unsafe/copy_move_defaulted.rs @@ -0,0 +1,302 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Inner { + pub x: i32, +} +#[repr(C)] +#[derive(Clone)] +pub struct Explicit { + pub v: i32, + pub inner: Inner, + pub arr: [i32; 2], +} +impl Explicit { + pub unsafe fn Explicit(mut v: i32) -> Self { + let mut this = Self { + v: v, + inner: Inner { x: ((v) * (10)) }, + arr: [v, ((v) + (1))], + }; + this + } + pub unsafe fn destructor(&mut self) {} +} +impl Default for Explicit { + fn default() -> Self { + Explicit { + v: 0_i32, + inner: ::default(), + arr: [0_i32; 2], + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Implicit { + pub v: i32, + pub inner: Inner, + pub arr: [i32; 2], +} +impl Default for Implicit { + fn default() -> Self { + Implicit { + v: 0_i32, + inner: ::default(), + arr: [0_i32; 2], + } + } +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct DefaultCopyUserMove { + pub v: i32, +} +impl DefaultCopyUserMove { + pub unsafe fn DefaultCopyUserMove(mut v: i32) -> Self { + let mut this = Self { v: v }; + this + } + pub unsafe fn DefaultCopyUserMove_pmutDefaultCopyUserMove(o: *mut DefaultCopyUserMove) -> Self { + let mut this = Self { v: (*o).v }; + (*o).v = 0; + this + } + pub unsafe fn operator_assign_pmutDefaultCopyUserMove( + &mut self, + o: *mut DefaultCopyUserMove, + ) -> *mut DefaultCopyUserMove { + self.v = (*o).v; + (*o).v = 0; + return &mut (*(self as *mut DefaultCopyUserMove)) as *mut DefaultCopyUserMove; + } +} +#[repr(C)] +#[derive(Default)] +pub struct UserCopyDefaultMove { + pub v: i32, +} +impl UserCopyDefaultMove { + pub unsafe fn UserCopyDefaultMove(mut v: i32) -> Self { + let mut this = Self { v: v }; + this + } + pub unsafe fn UserCopyDefaultMove_pconstUserCopyDefaultMove( + o: *const UserCopyDefaultMove, + ) -> Self { + let mut this = Self { + v: (((*o).v) + (100)), + }; + this + } + pub unsafe fn UserCopyDefaultMove_pmutUserCopyDefaultMove( + _a0: *mut UserCopyDefaultMove, + ) -> Self { + let mut this = Self { v: (*_a0).v }; + this + } + pub unsafe fn operator_assign_pconstUserCopyDefaultMove( + &mut self, + o: *const UserCopyDefaultMove, + ) -> *mut UserCopyDefaultMove { + self.v = (((*o).v) + (100)); + return &mut (*(self as *mut UserCopyDefaultMove)) as *mut UserCopyDefaultMove; + } + pub unsafe fn operator_assign_pmutUserCopyDefaultMove( + &mut self, + _a0: *mut UserCopyDefaultMove, + ) -> *mut UserCopyDefaultMove { + self.v = (*_a0).v; + return &mut (*(self as *mut UserCopyDefaultMove)) as *mut UserCopyDefaultMove; + } +} +impl Clone for UserCopyDefaultMove { + fn clone(&self) -> Self { + unsafe { + UserCopyDefaultMove::UserCopyDefaultMove_pconstUserCopyDefaultMove( + self as *const UserCopyDefaultMove, + ) + } + } +} +#[repr(C)] +#[derive()] +pub struct Buffer { + pub data: Vec, + pub n: i32, + pub arr: [i32; 2], +} +impl Buffer { + pub unsafe fn Buffer(mut n: i32) -> Self { + let mut this = Self { + data: vec![n; (n as usize) as usize], + n: n, + arr: [n, ((n) + (1))], + }; + this + } + pub unsafe fn Buffer_pmutBuffer(_a0: *mut Buffer) -> Self { + let mut this = Self { + data: std::mem::take(&mut (*_a0).data), + n: (*_a0).n, + arr: (*_a0).arr, + }; + this + } + pub unsafe fn operator_assign_pmutBuffer(&mut self, _a0: *mut Buffer) -> *mut Buffer { + self.data = std::mem::take(&mut (*_a0).data); + self.n = (*_a0).n; + self.arr = ((*_a0).arr).clone(); + return &mut (*(self as *mut Buffer)) as *mut Buffer; + } +} +impl Default for Buffer { + fn default() -> Self { + Buffer { + data: Default::default(), + n: 0_i32, + arr: [0_i32; 2], + } + } +} +pub unsafe fn same_0(a: *const Explicit, b: *const Explicit) -> bool { + return (((((*a).v) == ((*b).v)) && (((*a).inner.x) == ((*b).inner.x))) + && (((*a).arr[(0) as usize]) == ((*b).arr[(0) as usize]))) + && (((*a).arr[(1) as usize]) == ((*b).arr[(1) as usize])); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: Explicit = Explicit::Explicit({ 1 }); + let _dtor_a = ScopedDestructorUnsafe::new(&raw mut a, Explicit::destructor); + let mut b: Explicit = a.clone(); + let _dtor_b = ScopedDestructorUnsafe::new(&raw mut b, Explicit::destructor); + let mut c: Explicit = a.clone(); + let _dtor_c = ScopedDestructorUnsafe::new(&raw mut c, Explicit::destructor); + let mut d: Explicit = a.clone(); + let _dtor_d = ScopedDestructorUnsafe::new(&raw mut d, Explicit::destructor); + assert!( + ((unsafe { same_0(&b as *const Explicit, &a as *const Explicit,) }) + && (unsafe { same_0(&c as *const Explicit, &a as *const Explicit,) })) + && (unsafe { same_0(&d as *const Explicit, &a as *const Explicit,) }) + ); + let mut e: Explicit = Explicit::Explicit({ 2 }); + let _dtor_e = ScopedDestructorUnsafe::new(&raw mut e, Explicit::destructor); + let mut f: Explicit = Explicit::Explicit({ 3 }); + let _dtor_f = ScopedDestructorUnsafe::new(&raw mut f, Explicit::destructor); + e = (b).clone(); + f = (c).clone(); + assert!( + (unsafe { same_0(&e as *const Explicit, &b as *const Explicit,) }) + && (unsafe { same_0(&f as *const Explicit, &c as *const Explicit,) }) + ); + let mut g: Explicit = Explicit::Explicit({ 4 }); + let _dtor_g = ScopedDestructorUnsafe::new(&raw mut g, Explicit::destructor); + g = ({ + e = (f).clone(); + (e).clone() + }) + .clone(); + assert!( + (unsafe { same_0(&g as *const Explicit, &f as *const Explicit,) }) + && (unsafe { same_0(&e as *const Explicit, &f as *const Explicit,) }) + ); + let mut i: Implicit = Implicit { + v: 5, + inner: Inner { x: 50 }, + arr: [5, 6], + }; + let mut j: Implicit = i; + let mut k: Implicit = i; + assert!((((j.v) == (5)) && ((j.inner.x) == (50))) && ((j.arr[(1) as usize]) == (6))); + assert!(((i.v) == (5)) && ((k.v) == (5))); + let mut l: Implicit = Implicit { + v: 0, + inner: Inner { x: 0 }, + arr: [0, 0], + }; + l = j; + assert!((((l.v) == (5)) && ((l.inner.x) == (50))) && ((l.arr[(0) as usize]) == (5))); + let mut vec_: Vec = Vec::new(); + { + let a0_clone = b.clone(); + vec_.push(a0_clone) + }; + vec_.push(Explicit::Explicit({ 9 })); + assert!(((vec_[(0_usize)].v) == (1)) && ((vec_[(1_usize)].v) == (9))); + let mut m: DefaultCopyUserMove = DefaultCopyUserMove::DefaultCopyUserMove({ 7 }); + let mut m1: DefaultCopyUserMove = m; + let mut m2: DefaultCopyUserMove = + DefaultCopyUserMove::DefaultCopyUserMove_pmutDefaultCopyUserMove({ + &mut m as *mut DefaultCopyUserMove + }); + assert!((((m1.v) == (7)) && ((m2.v) == (7))) && ((m.v) == (0))); + let mut m3: DefaultCopyUserMove = DefaultCopyUserMove::DefaultCopyUserMove({ 1 }); + let mut m4: DefaultCopyUserMove = DefaultCopyUserMove::DefaultCopyUserMove({ 1 }); + m3 = m1; + (unsafe { + DefaultCopyUserMove::operator_assign_pmutDefaultCopyUserMove( + &mut m4, + &mut m1 as *mut DefaultCopyUserMove, + ) + }); + assert!((((m3.v) == (7)) && ((m4.v) == (7))) && ((m1.v) == (0))); + let mut u: UserCopyDefaultMove = UserCopyDefaultMove::UserCopyDefaultMove({ 8 }); + let mut u1: UserCopyDefaultMove = + UserCopyDefaultMove::UserCopyDefaultMove_pconstUserCopyDefaultMove({ + &u as *const UserCopyDefaultMove + }); + let mut u2: UserCopyDefaultMove = + UserCopyDefaultMove::UserCopyDefaultMove_pmutUserCopyDefaultMove({ + &mut u as *mut UserCopyDefaultMove + }); + assert!((((u1.v) == (108)) && ((u2.v) == (8))) && ((u.v) == (8))); + let mut u3: UserCopyDefaultMove = UserCopyDefaultMove::UserCopyDefaultMove({ 1 }); + let mut u4: UserCopyDefaultMove = UserCopyDefaultMove::UserCopyDefaultMove({ 1 }); + (unsafe { + UserCopyDefaultMove::operator_assign_pconstUserCopyDefaultMove( + &mut u3, + &u2 as *const UserCopyDefaultMove, + ) + }); + (unsafe { + UserCopyDefaultMove::operator_assign_pmutUserCopyDefaultMove( + &mut u4, + &mut u2 as *mut UserCopyDefaultMove, + ) + }); + assert!(((u3.v) == (108)) && ((u4.v) == (8))); + let mut p: Buffer = Buffer::Buffer({ 3 }); + let mut q: Buffer = Buffer::Buffer_pmutBuffer({ &mut p as *mut Buffer }); + assert!( + ((((q.n) == (3)) && ((q.data.len()) == (3_usize))) && ((q.data[(2_usize)]) == (3))) + && (p.data.is_empty()) + ); + let mut r: Buffer = Buffer::Buffer({ 1 }); + (unsafe { Buffer::operator_assign_pmutBuffer(&mut r, &mut q as *mut Buffer) }); + assert!( + ((((r.n) == (3)) && ((r.data.len()) == (3_usize))) && ((r.arr[(1) as usize]) == (4))) + && (q.data.is_empty()) + ); + let mut bufs: Vec = Vec::new(); + bufs.push(std::mem::take(&mut r)); + { + let __arg = Buffer::Buffer_pmutBuffer({ &mut bufs[(0_usize)] as *mut Buffer }); + bufs.push(__arg) + }; + assert!( + (((bufs[(1_usize)].n) == (3)) && ((bufs[(1_usize)].data.len()) == (3_usize))) + && (bufs[(0_usize)].data.is_empty()) + ); + return 0; +} diff --git a/tests/unit/out/unsafe/copy_move_deleted.rs b/tests/unit/out/unsafe/copy_move_deleted.rs new file mode 100644 index 000000000..59aeede69 --- /dev/null +++ b/tests/unit/out/unsafe/copy_move_deleted.rs @@ -0,0 +1,128 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive(Default)] +pub struct NoCopy { + pub v: i32, +} +impl NoCopy { + pub unsafe fn NoCopy(mut v: i32) -> Self { + let mut this = Self { v: v }; + this + } + pub unsafe fn NoCopy_pmutNoCopy(o: *mut NoCopy) -> Self { + let mut this = Self { v: (*o).v }; + (*o).v = 0; + this + } + pub unsafe fn operator_assign_pmutNoCopy(&mut self, o: *mut NoCopy) -> *mut NoCopy { + self.v = (*o).v; + (*o).v = 0; + return &mut (*(self as *mut NoCopy)) as *mut NoCopy; + } +} +#[repr(C)] +#[derive()] +pub struct PrivateCopy { + pub v: i32, +} +impl PrivateCopy { + pub unsafe fn PrivateCopy() -> Self { + let mut this = Self { v: 0 }; + this + } + pub unsafe fn PrivateCopy_pmutPrivateCopy(o: *mut PrivateCopy) -> Self { + let mut this = Self { v: (*o).v }; + (*o).v = 0; + this + } + pub unsafe fn operator_assign_pmutPrivateCopy( + &mut self, + o: *mut PrivateCopy, + ) -> *mut PrivateCopy { + self.v = (*o).v; + (*o).v = 0; + return &mut (*(self as *mut PrivateCopy)) as *mut PrivateCopy; + } +} +impl Default for PrivateCopy { + fn default() -> Self { + unsafe { PrivateCopy::PrivateCopy() } + } +} +#[repr(C)] +#[derive()] +pub struct Immovable { + pub v: i32, +} +impl Immovable { + pub unsafe fn Immovable() -> Self { + let mut this = Self { v: 0 }; + this + } +} +impl Default for Immovable { + fn default() -> Self { + unsafe { Immovable::Immovable() } + } +} +#[repr(C)] +#[derive(Default)] +pub struct Container { + pub inner: NoCopy, + pub tag: i32, +} +impl Container { + pub unsafe fn Container_pmutContainer(_a0: *mut Container) -> Self { + let mut this = Self { + inner: NoCopy::NoCopy_pmutNoCopy({ &mut (*_a0).inner as *mut NoCopy }), + tag: (*_a0).tag, + }; + this + } +} +pub unsafe fn bump_0(mut p: *mut NoCopy) { + (*p).v.postfix_inc(); +} +pub unsafe fn bump_ref_1(r: *mut Immovable) { + (*r).v.postfix_inc(); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: NoCopy = NoCopy::NoCopy({ 1 }); + let mut b: NoCopy = NoCopy::NoCopy_pmutNoCopy({ &mut a as *mut NoCopy }); + assert!(((b.v) == (1)) && ((a.v) == (0))); + (unsafe { NoCopy::operator_assign_pmutNoCopy(&mut a, &mut b as *mut NoCopy) }); + assert!(((a.v) == (1)) && ((b.v) == (0))); + (unsafe { bump_0((&mut a as *mut NoCopy)) }); + assert!(((a.v) == (2))); + let mut p: PrivateCopy = PrivateCopy::PrivateCopy(); + p.v = 3; + let mut q: PrivateCopy = + PrivateCopy::PrivateCopy_pmutPrivateCopy({ &mut p as *mut PrivateCopy }); + assert!(((q.v) == (3)) && ((p.v) == (0))); + (unsafe { PrivateCopy::operator_assign_pmutPrivateCopy(&mut p, &mut q as *mut PrivateCopy) }); + assert!(((p.v) == (3)) && ((q.v) == (0))); + let mut im: Immovable = Immovable::Immovable(); + im.v = 4; + (unsafe { bump_ref_1(&mut im as *mut Immovable) }); + let mut pim: *mut Immovable = (&mut im as *mut Immovable); + assert!((((*pim).v) == (5))); + let mut c: Container = Container { + inner: NoCopy::NoCopy({ 6 }), + tag: 7, + }; + let mut d: Container = Container::Container_pmutContainer({ &mut c as *mut Container }); + assert!((((d.inner.v) == (6)) && ((d.tag) == (7))) && ((c.inner.v) == (0))); + return 0; +} diff --git a/tests/unit/out/unsafe/empty_main.rs b/tests/unit/out/unsafe/empty_main.rs index c92775cf8..08a4a0a4b 100644 --- a/tests/unit/out/unsafe/empty_main.rs +++ b/tests/unit/out/unsafe/empty_main.rs @@ -19,6 +19,6 @@ pub fn main() { argv.push(::std::ptr::null_mut()); unsafe { ::std::process::exit(main_0((argv.len() - 1) as i32, argv.as_mut_ptr()) as i32) } } -unsafe fn main_0(_: i32, _: *mut *mut libc::c_char) -> i32 { +unsafe fn main_0(mut _a0: i32, mut _a1: *mut *mut libc::c_char) -> i32 { return 0; } diff --git a/tests/unit/out/unsafe/huffman.rs b/tests/unit/out/unsafe/huffman.rs index ea15aba8e..a34c73a7f 100644 --- a/tests/unit/out/unsafe/huffman.rs +++ b/tests/unit/out/unsafe/huffman.rs @@ -26,20 +26,18 @@ pub unsafe fn Swap_0(a: *mut MinHeapNode, b: *mut MinHeapNode) { left: (*a).left, right: (*a).right, }; - (*a) = (MinHeapNode { + (*a) = MinHeapNode { data: (*b).data, freq: (*b).freq, left: (*b).left, right: (*b).right, - }) - .clone(); - (*b) = (MinHeapNode { + }; + (*b) = MinHeapNode { data: t.data, freq: t.freq, left: t.left, right: t.right, - }) - .clone(); + }; } #[repr(C)] #[derive(Default)] @@ -129,6 +127,16 @@ impl MinHeap { i.prefix_dec(); } } + pub unsafe fn MinHeap_pmutMinHeap(_a0: *mut MinHeap) -> Self { + let mut this = Self { + size: (*_a0).size, + capacity: (*_a0).capacity, + arr: (*_a0).arr.take(), + next: (*_a0).next, + alloc: (*_a0).alloc.take(), + }; + this + } } pub unsafe fn AllocMinHeap_1(mut capacity: i32) -> Option> { let mut minHeap: Option> = Some(Box::new(MinHeap { diff --git a/tests/unit/out/unsafe/move_assign.rs b/tests/unit/out/unsafe/move_assign.rs index 81caf1145..37ac2d03d 100644 --- a/tests/unit/out/unsafe/move_assign.rs +++ b/tests/unit/out/unsafe/move_assign.rs @@ -62,7 +62,7 @@ impl Default for ConstMoveAssign { } pub unsafe fn make_0(mut v: i32) -> MoveOnly { let mut m: MoveOnly = MoveOnly::MoveOnly({ v }); - return MoveOnly::MoveOnly_pmutMoveOnly({ &mut m }); + return MoveOnly::MoveOnly_pmutMoveOnly({ &mut m as *mut MoveOnly }); } pub fn main() { unsafe { @@ -73,7 +73,7 @@ unsafe fn main_0() -> i32 { let mut a: MoveOnly = MoveOnly::MoveOnly({ 1 }); let mut b: MoveOnly = MoveOnly::MoveOnly({ 2 }); let mut c: MoveOnly = MoveOnly::MoveOnly({ 3 }); - (unsafe { MoveOnly::operator_assign_pmutMoveOnly(&mut a, &mut b) }); + (unsafe { MoveOnly::operator_assign_pmutMoveOnly(&mut a, &mut b as *mut MoveOnly) }); assert!(((a.v) == (2))); assert!(((b.v) == (0))); (unsafe { @@ -83,7 +83,9 @@ unsafe fn main_0() -> i32 { (unsafe { MoveOnly::operator_assign_pmutMoveOnly( &mut c, - (unsafe { MoveOnly::operator_assign_pmutMoveOnly(&mut a, &mut b) }), + &mut (*(unsafe { + MoveOnly::operator_assign_pmutMoveOnly(&mut a, &mut b as *mut MoveOnly) + })) as *mut MoveOnly, ) }); assert!((((b.v) == (0)) && ((a.v) == (0))) && ((c.v) == (3))); @@ -98,22 +100,34 @@ unsafe fn main_0() -> i32 { }); assert!(((a.v) == (6))); (unsafe { - let _o: *mut MoveOnly = &mut a; + let _o: *mut MoveOnly = &mut a as *mut MoveOnly; MoveOnly::operator_assign_pmutMoveOnly(&mut a, _o) }); assert!(((a.v) == (6))); let mut vec_: Vec = Vec::new(); vec_.push(MoveOnly::MoveOnly({ 7 })); let mut d: MoveOnly = MoveOnly::MoveOnly({ 8 }); - (unsafe { MoveOnly::operator_assign_pmutMoveOnly(&mut vec_[(0_usize)], &mut d) }); + (unsafe { + MoveOnly::operator_assign_pmutMoveOnly(&mut vec_[(0_usize)], &mut d as *mut MoveOnly) + }); assert!(((vec_[(0_usize)].v) == (8))); assert!(((d.v) == (0))); let mut m: ConstMoveAssign = ConstMoveAssign::ConstMoveAssign(); let mut m1: ConstMoveAssign = ConstMoveAssign::ConstMoveAssign(); let mut m2: ConstMoveAssign = ConstMoveAssign::ConstMoveAssign(); let cm: ConstMoveAssign = ConstMoveAssign::ConstMoveAssign(); - (unsafe { ConstMoveAssign::operator_assign_pmutConstMoveAssign(&mut m1, &mut m) }); - (unsafe { ConstMoveAssign::operator_assign_pconstConstMoveAssign(&mut m2, &cm) }); + (unsafe { + ConstMoveAssign::operator_assign_pmutConstMoveAssign( + &mut m1, + &mut m as *mut ConstMoveAssign, + ) + }); + (unsafe { + ConstMoveAssign::operator_assign_pconstConstMoveAssign( + &mut m2, + &cm as *const ConstMoveAssign, + ) + }); assert!(((m1.mark) == (1))); assert!(((m2.mark) == (10))); return 0; diff --git a/tests/unit/out/unsafe/move_ctor.rs b/tests/unit/out/unsafe/move_ctor.rs index a7614be60..68b29cb03 100644 --- a/tests/unit/out/unsafe/move_ctor.rs +++ b/tests/unit/out/unsafe/move_ctor.rs @@ -55,7 +55,7 @@ pub unsafe fn by_value_0(mut m: MoveOnly) -> i32 { } pub unsafe fn make_1(mut v: i32) -> MoveOnly { let mut m: MoveOnly = MoveOnly::MoveOnly({ v }); - return MoveOnly::MoveOnly_pmutMoveOnly({ &mut m }); + return MoveOnly::MoveOnly_pmutMoveOnly({ &mut m as *mut MoveOnly }); } pub fn main() { unsafe { @@ -64,19 +64,22 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut a: MoveOnly = MoveOnly::MoveOnly({ 1 }); - let mut b: MoveOnly = MoveOnly::MoveOnly_pmutMoveOnly({ &mut a }); + let mut b: MoveOnly = MoveOnly::MoveOnly_pmutMoveOnly({ &mut a as *mut MoveOnly }); assert!(((b.v) == (1))); assert!(((a.v) == (0))); - let mut c: MoveOnly = MoveOnly::MoveOnly_pmutMoveOnly({ &mut b }); + let mut c: MoveOnly = MoveOnly::MoveOnly_pmutMoveOnly({ &mut b as *mut MoveOnly }); assert!(((c.v) == (1))); assert!(((b.v) == (0))); - let mut d: MoveOnly = MoveOnly::MoveOnly_pmutMoveOnly({ &mut c }); + let mut d: MoveOnly = MoveOnly::MoveOnly_pmutMoveOnly({ &mut c as *mut MoveOnly }); assert!(((d.v) == (1))); assert!(((c.v) == (0))); let mut e: MoveOnly = (unsafe { make_1(5) }); assert!(((e.v) == (5))); assert!(((unsafe { by_value_0(MoveOnly::MoveOnly({ 6 },),) }) == (6))); - assert!(((unsafe { by_value_0(MoveOnly::MoveOnly_pmutMoveOnly({ &mut e },),) }) == (5))); + assert!( + ((unsafe { by_value_0(MoveOnly::MoveOnly_pmutMoveOnly({ &mut e as *mut MoveOnly },),) }) + == (5)) + ); assert!(((e.v) == (0))); let mut vec_: Vec = Vec::new(); vec_.push(MoveOnly::MoveOnly({ 7 })); @@ -85,9 +88,9 @@ unsafe fn main_0() -> i32 { assert!(((vec_[(0_usize)].v) == (7)) && ((vec_[(1_usize)].v) == (8))); assert!(((f.v) == (0))); let mut m: ConstMove = ConstMove::ConstMove(); - let mut m1: ConstMove = ConstMove::ConstMove_pmutConstMove({ &mut m }); + let mut m1: ConstMove = ConstMove::ConstMove_pmutConstMove({ &mut m as *mut ConstMove }); let cm: ConstMove = ConstMove::ConstMove(); - let mut m2: ConstMove = ConstMove::ConstMove_pconstConstMove({ &cm }); + let mut m2: ConstMove = ConstMove::ConstMove_pconstConstMove({ &cm as *const ConstMove }); assert!(((m1.mark) == (1))); assert!(((m2.mark) == (10))); return 0; diff --git a/tests/unit/out/unsafe/move_this.rs b/tests/unit/out/unsafe/move_this.rs index a06da1535..b40345870 100644 --- a/tests/unit/out/unsafe/move_this.rs +++ b/tests/unit/out/unsafe/move_this.rs @@ -35,16 +35,16 @@ impl Chain { } pub unsafe fn add_i32_rref(&mut self, mut n: i32) -> *mut Chain { self.v += n; - return (self as *mut Chain); + return &mut (*(self as *mut Chain)) as *mut Chain; } pub unsafe fn take(&mut self) -> Chain { - return Chain::Chain_pmutChain({ (self as *mut Chain) }); + return Chain::Chain_pmutChain({ &mut (*(self as *mut Chain)) as *mut Chain }); } pub unsafe fn copy(&self) -> Chain { return Chain::Chain_pconstChain({ &(*(self as *const Chain)) as *const Chain }); } pub unsafe fn self_(&mut self) -> *mut Chain { - return (self as *mut Chain); + return &mut (*(self as *mut Chain)) as *mut Chain; } } impl Clone for Chain { diff --git a/tests/unit/out/unsafe/operator_arithmetic_free.rs b/tests/unit/out/unsafe/operator_arithmetic_free.rs index 60d571f11..28a79422d 100644 --- a/tests/unit/out/unsafe/operator_arithmetic_free.rs +++ b/tests/unit/out/unsafe/operator_arithmetic_free.rs @@ -46,7 +46,7 @@ pub unsafe fn operator_inc_7(a: *mut S) -> *mut S { (*a).v.prefix_inc(); return a; } -pub unsafe fn operator_post_inc_8(a: *mut S, _: i32) -> S { +pub unsafe fn operator_post_inc_8(a: *mut S, mut _a1: i32) -> S { let mut old: S = (*a); (*a).v.prefix_inc(); return old; @@ -55,7 +55,7 @@ pub unsafe fn operator_dec_9(a: *mut S) -> *mut S { (*a).v.prefix_dec(); return a; } -pub unsafe fn operator_post_dec_10(a: *mut S, _: i32) -> S { +pub unsafe fn operator_post_dec_10(a: *mut S, mut _a1: i32) -> S { let mut old: S = (*a); (*a).v.prefix_dec(); return old; diff --git a/tests/unit/out/unsafe/operator_arithmetic_member.rs b/tests/unit/out/unsafe/operator_arithmetic_member.rs index 3ba7c468b..c3166ce23 100644 --- a/tests/unit/out/unsafe/operator_arithmetic_member.rs +++ b/tests/unit/out/unsafe/operator_arithmetic_member.rs @@ -47,7 +47,7 @@ impl S { self.v.prefix_inc(); return &mut (*(self as *mut S)) as *mut S; } - pub unsafe fn operator_post_inc_i32(&mut self, _: i32) -> S { + pub unsafe fn operator_post_inc_i32(&mut self, mut _a0: i32) -> S { let mut old: S = (*(self as *mut S)); self.v.prefix_inc(); return old; @@ -56,7 +56,7 @@ impl S { self.v.prefix_dec(); return &mut (*(self as *mut S)) as *mut S; } - pub unsafe fn operator_post_dec_i32(&mut self, _: i32) -> S { + pub unsafe fn operator_post_dec_i32(&mut self, mut _a0: i32) -> S { let mut old: S = (*(self as *mut S)); self.v.prefix_dec(); return old; diff --git a/tests/unit/out/unsafe/operator_comparison_defaulted.rs b/tests/unit/out/unsafe/operator_comparison_defaulted.rs index 751931a1f..72c41b778 100644 --- a/tests/unit/out/unsafe/operator_comparison_defaulted.rs +++ b/tests/unit/out/unsafe/operator_comparison_defaulted.rs @@ -13,9 +13,9 @@ pub struct Eq { pub b: i32, } impl Eq { - pub unsafe fn operator_eq(&self, _arg0: *const Eq) -> bool { - return (((*(self as *const Eq)).a) == ((*_arg0).a)) - && (((*(self as *const Eq)).b) == ((*_arg0).b)); + pub unsafe fn operator_eq(&self, _a0: *const Eq) -> bool { + return (((*(self as *const Eq)).a) == ((*_a0).a)) + && (((*(self as *const Eq)).b) == ((*_a0).b)); } } impl std::cmp::PartialEq for Eq { @@ -31,24 +31,24 @@ pub struct Cmp { pub b: i32, } impl Cmp { - pub unsafe fn operator_cmp(&self, _arg0: *const Cmp) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Cmp) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const Cmp)).a).cmp(&((*_arg0).a)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Cmp)).a).cmp(&((*_a0).a)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } { - let mut cmp: std::cmp::Ordering = ((*(self as *const Cmp)).b).cmp(&((*_arg0).b)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Cmp)).b).cmp(&((*_a0).b)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } return std::cmp::Ordering::Equal; } - pub unsafe fn operator_eq(&self, _arg0: *const Cmp) -> bool { - return (((*(self as *const Cmp)).a) == ((*_arg0).a)) - && (((*(self as *const Cmp)).b) == ((*_arg0).b)); + pub unsafe fn operator_eq(&self, _a0: *const Cmp) -> bool { + return (((*(self as *const Cmp)).a) == ((*_a0).a)) + && (((*(self as *const Cmp)).b) == ((*_a0).b)); } } impl std::cmp::Ord for Cmp { @@ -73,12 +73,12 @@ pub struct Both { pub a: i32, } impl Both { - pub unsafe fn operator_eq(&self, _arg0: *const Both) -> bool { - return (((*(self as *const Both)).a) == ((*_arg0).a)); + pub unsafe fn operator_eq(&self, _a0: *const Both) -> bool { + return (((*(self as *const Both)).a) == ((*_a0).a)); } - pub unsafe fn operator_cmp(&self, _arg0: *const Both) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Both) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const Both)).a).cmp(&((*_arg0).a)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Both)).a).cmp(&((*_a0).a)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } @@ -108,9 +108,9 @@ pub struct OrdOnly { pub a: i32, } impl OrdOnly { - pub unsafe fn operator_cmp(&self, _arg0: *const OrdOnly) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const OrdOnly) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const OrdOnly)).a).cmp(&((*_arg0).a)); + let mut cmp: std::cmp::Ordering = ((*(self as *const OrdOnly)).a).cmp(&((*_a0).a)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } @@ -140,17 +140,17 @@ pub struct Inner { pub x: i32, } impl Inner { - pub unsafe fn operator_cmp(&self, _arg0: *const Inner) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Inner) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const Inner)).x).cmp(&((*_arg0).x)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Inner)).x).cmp(&((*_a0).x)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } return std::cmp::Ordering::Equal; } - pub unsafe fn operator_eq(&self, _arg0: *const Inner) -> bool { - return (((*(self as *const Inner)).x) == ((*_arg0).x)); + pub unsafe fn operator_eq(&self, _a0: *const Inner) -> bool { + return (((*(self as *const Inner)).x) == ((*_a0).x)); } } impl std::cmp::Ord for Inner { @@ -176,10 +176,10 @@ pub struct Outer { pub y: i32, } impl Outer { - pub unsafe fn operator_cmp(&self, _arg0: *const Outer) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Outer) -> std::cmp::Ordering { { let mut cmp: std::cmp::Ordering = (unsafe { - let _arg0: *const Inner = &(*_arg0).i as *const Inner; + let _arg0: *const Inner = &(*_a0).i as *const Inner; Inner::operator_cmp(&(*(self as *const Outer)).i, _arg0) }); if !(cmp == std::cmp::Ordering::Equal) { @@ -187,18 +187,18 @@ impl Outer { } } { - let mut cmp: std::cmp::Ordering = ((*(self as *const Outer)).y).cmp(&((*_arg0).y)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Outer)).y).cmp(&((*_a0).y)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } return std::cmp::Ordering::Equal; } - pub unsafe fn operator_eq(&self, _arg0: *const Outer) -> bool { + pub unsafe fn operator_eq(&self, _a0: *const Outer) -> bool { return (unsafe { - let _arg0: *const Inner = &(*_arg0).i as *const Inner; + let _arg0: *const Inner = &(*_a0).i as *const Inner; Inner::operator_eq(&(*(self as *const Outer)).i, _arg0) - }) && (((*(self as *const Outer)).y) == ((*_arg0).y)); + }) && (((*(self as *const Outer)).y) == ((*_a0).y)); } } impl std::cmp::Ord for Outer { @@ -223,33 +223,33 @@ pub struct Secondary { pub a: i32, } impl Secondary { - pub unsafe fn operator_eq(&self, _arg0: *const Secondary) -> bool { - return (((*(self as *const Secondary)).a) == ((*_arg0).a)); + pub unsafe fn operator_eq(&self, _a0: *const Secondary) -> bool { + return (((*(self as *const Secondary)).a) == ((*_a0).a)); } - pub unsafe fn operator_ne(&self, _arg0: *const Secondary) -> bool { + pub unsafe fn operator_ne(&self, _a0: *const Secondary) -> bool { return !(unsafe { - let _arg0: *const Secondary = _arg0; + let _arg0: *const Secondary = _a0; Secondary::operator_eq(&(*(self as *const Secondary)), _arg0) }); } - pub unsafe fn operator_cmp(&self, _arg0: *const Secondary) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Secondary) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const Secondary)).a).cmp(&((*_arg0).a)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Secondary)).a).cmp(&((*_a0).a)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } return std::cmp::Ordering::Equal; } - pub unsafe fn operator_lt(&self, _arg0: *const Secondary) -> bool { + pub unsafe fn operator_lt(&self, _a0: *const Secondary) -> bool { return (unsafe { - let _arg0: *const Secondary = _arg0; + let _arg0: *const Secondary = _a0; Secondary::operator_cmp(&(*(self as *const Secondary)), _arg0) }) == std::cmp::Ordering::Less; } - pub unsafe fn operator_ge(&self, _arg0: *const Secondary) -> bool { + pub unsafe fn operator_ge(&self, _a0: *const Secondary) -> bool { return (unsafe { - let _arg0: *const Secondary = _arg0; + let _arg0: *const Secondary = _a0; Secondary::operator_cmp(&(*(self as *const Secondary)), _arg0) }) != std::cmp::Ordering::Less; } diff --git a/tests/unit/out/unsafe/push_emplace_back.rs b/tests/unit/out/unsafe/push_emplace_back.rs index 9c295cd66..d6bfd0ab9 100644 --- a/tests/unit/out/unsafe/push_emplace_back.rs +++ b/tests/unit/out/unsafe/push_emplace_back.rs @@ -58,18 +58,22 @@ pub unsafe fn emplace_local_from_field_4(mut jpg: *mut JPEGData, mut cond: bool) } else { dest = (&mut (*jpg).app_data as *mut Vec>); } - (*dest).push( - core::slice::from_raw_parts( + { + let __arg = core::slice::from_raw_parts( head.as_mut_ptr(), (head.as_mut_ptr().offset((3) as isize)).offset_from(head.as_mut_ptr()) as usize, ) .iter() .map(|x| u8::try_from(x.clone()).ok().unwrap()) - .collect(), - ); + .collect(); + (*dest).push(__arg) + }; } pub unsafe fn nested_emplace_move_5(mut bw: *mut Writer) { - (*(*bw).output).push(std::mem::take(&mut (*bw).chunk)); + { + let __arg = std::mem::take(&mut (*bw).chunk); + (*(*bw).output).push(__arg) + }; } pub unsafe fn self_ref_push_6(mut comps: *mut Vec) { { diff --git a/tests/unit/out/unsafe/rule_of_five.rs b/tests/unit/out/unsafe/rule_of_five.rs index eaf5d228a..28bb95962 100644 --- a/tests/unit/out/unsafe/rule_of_five.rs +++ b/tests/unit/out/unsafe/rule_of_five.rs @@ -107,7 +107,7 @@ impl Default for Buffer { pub unsafe fn make_3(mut size: i32) -> Buffer { let mut b: Buffer = Buffer::Buffer({ size }); let _dtor_b = ScopedDestructorUnsafe::new(&raw mut b, Buffer::destructor); - return Buffer::Buffer_pmutBuffer({ &mut b }); + return Buffer::Buffer_pmutBuffer({ &mut b as *mut Buffer }); } pub fn main() { unsafe { @@ -123,7 +123,7 @@ unsafe fn main_0() -> i32 { assert!((((alive_0) == (2)) && ((copies_1) == (1))) && ((moves_2) == (0))); b.data[(0) as usize] = 100; assert!(((a.data[(0) as usize]) == (0))); - let mut c: Buffer = Buffer::Buffer_pmutBuffer({ &mut a }); + let mut c: Buffer = Buffer::Buffer_pmutBuffer({ &mut a as *mut Buffer }); let _dtor_c = ScopedDestructorUnsafe::new(&raw mut c, Buffer::destructor); assert!(((alive_0) == (3)) && ((moves_2) == (1))); assert!(((a.size) == (0)) && ((a.data[(0) as usize]) == (-1_i32))); @@ -133,10 +133,10 @@ unsafe fn main_0() -> i32 { assert!(((d.size) == (2)) && ((moves_2) == (2))); (unsafe { Buffer::operator_assign_pconstBuffer(&mut d, &b as *const Buffer) }); assert!((((d.size) == (4)) && ((d.data[(0) as usize]) == (100))) && ((copies_1) == (2))); - (unsafe { Buffer::operator_assign_pmutBuffer(&mut d, &mut c) }); + (unsafe { Buffer::operator_assign_pmutBuffer(&mut d, &mut c as *mut Buffer) }); assert!((((d.data[(0) as usize]) == (0)) && ((c.size) == (0))) && ((moves_2) == (3))); (unsafe { - let _o: *mut Buffer = &mut d; + let _o: *mut Buffer = &mut d as *mut Buffer; Buffer::operator_assign_pmutBuffer(&mut d, _o) }); assert!(((d.size) == (4)) && ((moves_2) == (3))); diff --git a/tests/unit/out/unsafe/rule_of_three.rs b/tests/unit/out/unsafe/rule_of_three.rs index fe1b8cb58..c615f6a11 100644 --- a/tests/unit/out/unsafe/rule_of_three.rs +++ b/tests/unit/out/unsafe/rule_of_three.rs @@ -107,11 +107,11 @@ unsafe fn main_0() -> i32 { assert!(((copies_1) == (2))); assert!(((unsafe { sum_2(&a as *const Buffer,) }) == (6))); assert!(((unsafe { sum_2(&b as *const Buffer,) }) == (106))); - let mut d: Buffer = Buffer::Buffer_pconstBuffer({ &mut a }); + let mut d: Buffer = Buffer::Buffer_pconstBuffer({ &a as *const Buffer }); let _dtor_d = ScopedDestructorUnsafe::new(&raw mut d, Buffer::destructor); assert!(((alive_0) == (4)) && ((copies_1) == (3))); assert!(((a.size) == (4)) && ((a.data[(3) as usize]) == (3))); - (unsafe { Buffer::operator_assign(&mut d, &mut b) }); + (unsafe { Buffer::operator_assign(&mut d, &b as *const Buffer) }); assert!(((copies_1) == (4))); assert!(((b.data[(0) as usize]) == (100)) && ((d.data[(0) as usize]) == (100))); } diff --git a/tests/unit/out/unsafe/rvalue_ref_general.rs b/tests/unit/out/unsafe/rvalue_ref_general.rs index c5b6ce67c..12c523d4b 100644 --- a/tests/unit/out/unsafe/rvalue_ref_general.rs +++ b/tests/unit/out/unsafe/rvalue_ref_general.rs @@ -30,7 +30,7 @@ unsafe fn main_0() -> i32 { assert!(((*i6) == (*i3))); assert!(((*i7) == (*i4))); let mut i8: i32 = 3; - let i9: *mut i32 = &mut i8; + let i9: *mut i32 = &mut i8 as *mut i32; assert!(((*i9) == (3))); let mut p1: *mut i32 = (&mut i1 as *mut i32); let mut p2: *mut i32 = (i3); diff --git a/tests/unit/out/unsafe/rvalue_struct.rs b/tests/unit/out/unsafe/rvalue_struct.rs index 8d31bde04..af9a0225a 100644 --- a/tests/unit/out/unsafe/rvalue_struct.rs +++ b/tests/unit/out/unsafe/rvalue_struct.rs @@ -25,7 +25,7 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut s1: S = S::S({ 1 }, { 2 }); - let s2: *mut S = &mut s1; + let s2: *mut S = &mut s1 as *mut S; assert!((((*s2).a) == (1))); assert!((((*s2).b) == (2))); return 0; diff --git a/tests/unit/out/unsafe/unique_ptr.rs b/tests/unit/out/unsafe/unique_ptr.rs index 3c79812b0..2358a54b5 100644 --- a/tests/unit/out/unsafe/unique_ptr.rs +++ b/tests/unit/out/unsafe/unique_ptr.rs @@ -15,6 +15,12 @@ impl SafePointer { pub unsafe fn inc(&mut self) { (*self.ptr.as_deref_mut().unwrap()).prefix_inc(); } + pub unsafe fn SafePointer_pmutSafePointer(_a0: *mut SafePointer) -> Self { + let mut this = Self { + ptr: (*_a0).ptr.take(), + }; + this + } } #[repr(C)] #[derive(Copy, Clone, Default)] diff --git a/tests/unit/out/unsafe/unique_ptr_nested.rs b/tests/unit/out/unsafe/unique_ptr_nested.rs index 02c01c143..21bf245ae 100644 --- a/tests/unit/out/unsafe/unique_ptr_nested.rs +++ b/tests/unit/out/unsafe/unique_ptr_nested.rs @@ -17,6 +17,14 @@ pub struct Inner { pub struct Outer { pub inner: Option>, } +impl Outer { + pub unsafe fn Outer_pmutOuter(_a0: *mut Outer) -> Self { + let mut this = Self { + inner: (*_a0).inner.take(), + }; + this + } +} pub fn main() { unsafe { std::process::exit(main_0() as i32); diff --git a/tests/unit/out/unsafe/vector_with_allocator.rs b/tests/unit/out/unsafe/vector_with_allocator.rs index f7025a5dd..44d0acdb4 100644 --- a/tests/unit/out/unsafe/vector_with_allocator.rs +++ b/tests/unit/out/unsafe/vector_with_allocator.rs @@ -13,7 +13,7 @@ impl TestAllocator_int_ { pub unsafe fn allocate(&mut self, mut n: usize) -> *mut i32 { return Box::leak((0..n).map(|_| 0_i32).collect::>()).as_mut_ptr(); } - pub unsafe fn deallocate(&mut self, mut p: *mut i32, _: usize) { + pub unsafe fn deallocate(&mut self, mut p: *mut i32, mut _a1: usize) { ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( p, libcc2rs::malloc_usable_size(p as *mut ::libc::c_void) / ::std::mem::size_of::(), @@ -27,7 +27,7 @@ impl TestAllocator_double_ { pub unsafe fn allocate(&mut self, mut n: usize) -> *mut f64 { return Box::leak((0..n).map(|_| 0.0_f64).collect::>()).as_mut_ptr(); } - pub unsafe fn deallocate(&mut self, mut p: *mut f64, _: usize) { + pub unsafe fn deallocate(&mut self, mut p: *mut f64, mut _a1: usize) { ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( p, libcc2rs::malloc_usable_size(p as *mut ::libc::c_void) / ::std::mem::size_of::(), From e46e1ad262f670ba5ccab9f3895e9c4c2bdf75e7 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 10:04:27 +0100 Subject: [PATCH 04/11] Translate nameless C++ params as _a1, _a2, etc --- cpp2rust/converter/converter_lib.cpp | 6 +- tests/unit/out/refcount/empty_main.rs | 4 +- .../out/refcount/operator_arithmetic_free.rs | 6 +- .../refcount/operator_arithmetic_member.rs | 10 +- .../refcount/operator_comparison_defaulted.rs | 100 +++++++++--------- .../out/refcount/vector_with_allocator.rs | 10 +- tests/unit/out/unsafe/empty_main.rs | 2 +- .../out/unsafe/operator_arithmetic_free.rs | 4 +- .../out/unsafe/operator_arithmetic_member.rs | 4 +- .../unsafe/operator_comparison_defaulted.rs | 70 ++++++------ .../unit/out/unsafe/vector_with_allocator.rs | 4 +- 11 files changed, 113 insertions(+), 107 deletions(-) diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index a7c6500c3..7a0317345 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -652,12 +652,10 @@ std::string GetNamedDeclAsString(const clang::NamedDecl *decl) { llvm::dyn_cast(pdecl->getDeclContext()); const auto *ctor = llvm::dyn_cast_or_null(fn); if (pdecl->isExplicitObjectParameter() || - (ctor && ctor->isCopyOrMoveConstructor())) { + (ctor && ctor->isCopyConstructor())) { name = "self"; - } else if (fn && fn->isDefaulted() && IsComparisonOperator(fn)) { - name = std::format("_arg{}", pdecl->getFunctionScopeIndex()); } else { - name = "_"; + name = std::format("_a{}", pdecl->getFunctionScopeIndex()); } } else if (auto *pdecl = llvm::dyn_cast(decl)) { // Expanded parameter packs share one name across the expansion diff --git a/tests/unit/out/refcount/empty_main.rs b/tests/unit/out/refcount/empty_main.rs index 4e280a57e..be7ceea31 100644 --- a/tests/unit/out/refcount/empty_main.rs +++ b/tests/unit/out/refcount/empty_main.rs @@ -22,6 +22,8 @@ pub fn main() { (*argv.borrow_mut()).push(Ptr::null()); ::std::process::exit(main_0(::std::env::args().len() as i32, argv.as_pointer())); } -fn main_0(_: i32, _: Ptr>) -> i32 { +fn main_0(_a0: i32, _a1: Ptr>) -> i32 { + let _a0: Value = Rc::new(RefCell::new(_a0)); + let _a1: Value>> = Rc::new(RefCell::new(_a1)); return 0; } diff --git a/tests/unit/out/refcount/operator_arithmetic_free.rs b/tests/unit/out/refcount/operator_arithmetic_free.rs index 4ed526dab..ebbf39a7a 100644 --- a/tests/unit/out/refcount/operator_arithmetic_free.rs +++ b/tests/unit/out/refcount/operator_arithmetic_free.rs @@ -86,7 +86,8 @@ pub fn operator_inc_7(a: Ptr) -> Ptr { (*(*a.upgrade().deref()).v.borrow_mut()).prefix_inc(); return (a).clone(); } -pub fn operator_post_inc_8(a: Ptr, _: i32) -> S { +pub fn operator_post_inc_8(a: Ptr, _a1: i32) -> S { + let _a1: Value = Rc::new(RefCell::new(_a1)); let old: Value = Rc::new(RefCell::new((*a.upgrade().deref()).clone())); (*(*a.upgrade().deref()).v.borrow_mut()).prefix_inc(); return (*old.borrow()).clone(); @@ -95,7 +96,8 @@ pub fn operator_dec_9(a: Ptr) -> Ptr { (*(*a.upgrade().deref()).v.borrow_mut()).prefix_dec(); return (a).clone(); } -pub fn operator_post_dec_10(a: Ptr, _: i32) -> S { +pub fn operator_post_dec_10(a: Ptr, _a1: i32) -> S { + let _a1: Value = Rc::new(RefCell::new(_a1)); let old: Value = Rc::new(RefCell::new((*a.upgrade().deref()).clone())); (*(*a.upgrade().deref()).v.borrow_mut()).prefix_dec(); return (*old.borrow()).clone(); diff --git a/tests/unit/out/refcount/operator_arithmetic_member.rs b/tests/unit/out/refcount/operator_arithmetic_member.rs index 5dcf3ff74..b1065522d 100644 --- a/tests/unit/out/refcount/operator_arithmetic_member.rs +++ b/tests/unit/out/refcount/operator_arithmetic_member.rs @@ -123,9 +123,9 @@ pub trait SImpl { fn operator_pos_const(&self) -> S; fn operator_neg_const(&self) -> S; fn operator_inc(&self) -> Ptr; - fn operator_post_inc_i32(&self, _: i32) -> S; + fn operator_post_inc_i32(&self, _a0: i32) -> S; fn operator_dec(&self) -> Ptr; - fn operator_post_dec_i32(&self, _: i32) -> S; + fn operator_post_dec_i32(&self, _a0: i32) -> S; } impl SImpl for Ptr { fn operator_add_pconstS_const(&self, o: Ptr) -> S { @@ -182,7 +182,8 @@ impl SImpl for Ptr { (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_inc(); return (*self).clone(); } - fn operator_post_inc_i32(&self, _: i32) -> S { + fn operator_post_inc_i32(&self, _a0: i32) -> S { + let _a0: Value = Rc::new(RefCell::new(_a0)); let old: Value = Rc::new(RefCell::new((*(*self).upgrade().deref()).clone())); (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_inc(); return (*old.borrow()).clone(); @@ -191,7 +192,8 @@ impl SImpl for Ptr { (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_dec(); return (*self).clone(); } - fn operator_post_dec_i32(&self, _: i32) -> S { + fn operator_post_dec_i32(&self, _a0: i32) -> S { + let _a0: Value = Rc::new(RefCell::new(_a0)); let old: Value = Rc::new(RefCell::new((*(*self).upgrade().deref()).clone())); (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_dec(); return (*old.borrow()).clone(); diff --git a/tests/unit/out/refcount/operator_comparison_defaulted.rs b/tests/unit/out/refcount/operator_comparison_defaulted.rs index 696557263..8d8c3fa81 100644 --- a/tests/unit/out/refcount/operator_comparison_defaulted.rs +++ b/tests/unit/out/refcount/operator_comparison_defaulted.rs @@ -527,21 +527,21 @@ fn main_0() -> i32 { return 0; } pub trait BothImpl { - fn operator_eq(&self, _arg0: Ptr) -> bool; - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; + fn operator_eq(&self, _a0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; } impl BothImpl for Ptr { - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return { let _lhs = (*(*(*self).upgrade().deref()).a.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).a.borrow()) + _lhs == (*(*_a0.upgrade().deref()).a.borrow()) }; } - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).a.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).a.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).a.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -551,15 +551,15 @@ impl BothImpl for Ptr { } } pub trait CmpImpl { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; - fn operator_eq(&self, _arg0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; + fn operator_eq(&self, _a0: Ptr) -> bool; } impl CmpImpl for Ptr { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).a.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).a.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).a.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -568,7 +568,7 @@ impl CmpImpl for Ptr { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).b.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).b.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).b.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -576,40 +576,40 @@ impl CmpImpl for Ptr { } return std::cmp::Ordering::Equal; } - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return ({ let _lhs = (*(*(*self).upgrade().deref()).a.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).a.borrow()) + _lhs == (*(*_a0.upgrade().deref()).a.borrow()) }) && ({ let _lhs = (*(*(*self).upgrade().deref()).b.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).b.borrow()) + _lhs == (*(*_a0.upgrade().deref()).b.borrow()) }); } } pub trait EqImpl { - fn operator_eq(&self, _arg0: Ptr) -> bool; + fn operator_eq(&self, _a0: Ptr) -> bool; } impl EqImpl for Ptr { - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return ({ let _lhs = (*(*(*self).upgrade().deref()).a.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).a.borrow()) + _lhs == (*(*_a0.upgrade().deref()).a.borrow()) }) && ({ let _lhs = (*(*(*self).upgrade().deref()).b.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).b.borrow()) + _lhs == (*(*_a0.upgrade().deref()).b.borrow()) }); } } pub trait InnerImpl { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; - fn operator_eq(&self, _arg0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; + fn operator_eq(&self, _a0: Ptr) -> bool; } impl InnerImpl for Ptr { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).x.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).x.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).x.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -617,22 +617,22 @@ impl InnerImpl for Ptr { } return std::cmp::Ordering::Equal; } - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return { let _lhs = (*(*(*self).upgrade().deref()).x.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).x.borrow()) + _lhs == (*(*_a0.upgrade().deref()).x.borrow()) }; } } pub trait OrdOnlyImpl { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; } impl OrdOnlyImpl for Ptr { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).a.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).a.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).a.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -642,15 +642,15 @@ impl OrdOnlyImpl for Ptr { } } pub trait OuterImpl { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; - fn operator_eq(&self, _arg0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; + fn operator_eq(&self, _a0: Ptr) -> bool; } impl OuterImpl for Ptr { - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( ({ - let _arg0: Ptr = (*_arg0.upgrade().deref()).i.as_pointer(); + let _arg0: Ptr = (*_a0.upgrade().deref()).i.as_pointer(); InnerImpl::operator_cmp(&(*(*self).upgrade().deref()).i.as_pointer(), _arg0) }), )); @@ -661,7 +661,7 @@ impl OuterImpl for Ptr { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).y.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).y.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).y.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -669,41 +669,41 @@ impl OuterImpl for Ptr { } return std::cmp::Ordering::Equal; } - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return ({ - let _arg0: Ptr = (*_arg0.upgrade().deref()).i.as_pointer(); + let _arg0: Ptr = (*_a0.upgrade().deref()).i.as_pointer(); InnerImpl::operator_eq(&(*(*self).upgrade().deref()).i.as_pointer(), _arg0) }) && ({ let _lhs = (*(*(*self).upgrade().deref()).y.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).y.borrow()) + _lhs == (*(*_a0.upgrade().deref()).y.borrow()) }); } } pub trait SecondaryImpl { - fn operator_eq(&self, _arg0: Ptr) -> bool; - fn operator_ne(&self, _arg0: Ptr) -> bool; - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering; - fn operator_lt(&self, _arg0: Ptr) -> bool; - fn operator_ge(&self, _arg0: Ptr) -> bool; + fn operator_eq(&self, _a0: Ptr) -> bool; + fn operator_ne(&self, _a0: Ptr) -> bool; + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering; + fn operator_lt(&self, _a0: Ptr) -> bool; + fn operator_ge(&self, _a0: Ptr) -> bool; } impl SecondaryImpl for Ptr { - fn operator_eq(&self, _arg0: Ptr) -> bool { + fn operator_eq(&self, _a0: Ptr) -> bool { return { let _lhs = (*(*(*self).upgrade().deref()).a.borrow()); - _lhs == (*(*_arg0.upgrade().deref()).a.borrow()) + _lhs == (*(*_a0.upgrade().deref()).a.borrow()) }; } - fn operator_ne(&self, _arg0: Ptr) -> bool { + fn operator_ne(&self, _a0: Ptr) -> bool { return !({ - let _arg0: Ptr = (_arg0).clone(); + let _arg0: Ptr = (_a0).clone(); SecondaryImpl::operator_eq(&(*self), _arg0) }); } - fn operator_cmp(&self, _arg0: Ptr) -> std::cmp::Ordering { + fn operator_cmp(&self, _a0: Ptr) -> std::cmp::Ordering { { let cmp: Value = Rc::new(RefCell::new( (*(*(*self).upgrade().deref()).a.borrow()) - .cmp(&(*(*_arg0.upgrade().deref()).a.borrow())), + .cmp(&(*(*_a0.upgrade().deref()).a.borrow())), )); if !((*cmp.borrow()) == std::cmp::Ordering::Equal) { return (*cmp.borrow_mut()).clone(); @@ -711,15 +711,15 @@ impl SecondaryImpl for Ptr { } return std::cmp::Ordering::Equal; } - fn operator_lt(&self, _arg0: Ptr) -> bool { + fn operator_lt(&self, _a0: Ptr) -> bool { return ({ - let _arg0: Ptr = (_arg0).clone(); + let _arg0: Ptr = (_a0).clone(); SecondaryImpl::operator_cmp(&(*self), _arg0) }) == std::cmp::Ordering::Less; } - fn operator_ge(&self, _arg0: Ptr) -> bool { + fn operator_ge(&self, _a0: Ptr) -> bool { return ({ - let _arg0: Ptr = (_arg0).clone(); + let _arg0: Ptr = (_a0).clone(); SecondaryImpl::operator_cmp(&(*self), _arg0) }) != std::cmp::Ordering::Less; } diff --git a/tests/unit/out/refcount/vector_with_allocator.rs b/tests/unit/out/refcount/vector_with_allocator.rs index 4246ce5ea..288910bdf 100644 --- a/tests/unit/out/refcount/vector_with_allocator.rs +++ b/tests/unit/out/refcount/vector_with_allocator.rs @@ -341,7 +341,7 @@ fn main_0() -> i32 { } pub trait TestAllocator_double_Impl { fn allocate(&self, n: usize) -> Ptr; - fn deallocate(&self, p: Ptr, _: usize); + fn deallocate(&self, p: Ptr, _a1: usize); } impl TestAllocator_double_Impl for Ptr { fn allocate(&self, n: usize) -> Ptr { @@ -352,14 +352,15 @@ impl TestAllocator_double_Impl for Ptr { .collect::>(), ); } - fn deallocate(&self, p: Ptr, _: usize) { + fn deallocate(&self, p: Ptr, _a1: usize) { let p: Value> = Rc::new(RefCell::new(p)); + let _a1: Value = Rc::new(RefCell::new(_a1)); (*p.borrow()).delete_array(); } } pub trait TestAllocator_int_Impl { fn allocate(&self, n: usize) -> Ptr; - fn deallocate(&self, p: Ptr, _: usize); + fn deallocate(&self, p: Ptr, _a1: usize); } impl TestAllocator_int_Impl for Ptr { fn allocate(&self, n: usize) -> Ptr { @@ -370,8 +371,9 @@ impl TestAllocator_int_Impl for Ptr { .collect::>(), ); } - fn deallocate(&self, p: Ptr, _: usize) { + fn deallocate(&self, p: Ptr, _a1: usize) { let p: Value> = Rc::new(RefCell::new(p)); + let _a1: Value = Rc::new(RefCell::new(_a1)); (*p.borrow()).delete_array(); } } diff --git a/tests/unit/out/unsafe/empty_main.rs b/tests/unit/out/unsafe/empty_main.rs index c92775cf8..08a4a0a4b 100644 --- a/tests/unit/out/unsafe/empty_main.rs +++ b/tests/unit/out/unsafe/empty_main.rs @@ -19,6 +19,6 @@ pub fn main() { argv.push(::std::ptr::null_mut()); unsafe { ::std::process::exit(main_0((argv.len() - 1) as i32, argv.as_mut_ptr()) as i32) } } -unsafe fn main_0(_: i32, _: *mut *mut libc::c_char) -> i32 { +unsafe fn main_0(mut _a0: i32, mut _a1: *mut *mut libc::c_char) -> i32 { return 0; } diff --git a/tests/unit/out/unsafe/operator_arithmetic_free.rs b/tests/unit/out/unsafe/operator_arithmetic_free.rs index 60d571f11..28a79422d 100644 --- a/tests/unit/out/unsafe/operator_arithmetic_free.rs +++ b/tests/unit/out/unsafe/operator_arithmetic_free.rs @@ -46,7 +46,7 @@ pub unsafe fn operator_inc_7(a: *mut S) -> *mut S { (*a).v.prefix_inc(); return a; } -pub unsafe fn operator_post_inc_8(a: *mut S, _: i32) -> S { +pub unsafe fn operator_post_inc_8(a: *mut S, mut _a1: i32) -> S { let mut old: S = (*a); (*a).v.prefix_inc(); return old; @@ -55,7 +55,7 @@ pub unsafe fn operator_dec_9(a: *mut S) -> *mut S { (*a).v.prefix_dec(); return a; } -pub unsafe fn operator_post_dec_10(a: *mut S, _: i32) -> S { +pub unsafe fn operator_post_dec_10(a: *mut S, mut _a1: i32) -> S { let mut old: S = (*a); (*a).v.prefix_dec(); return old; diff --git a/tests/unit/out/unsafe/operator_arithmetic_member.rs b/tests/unit/out/unsafe/operator_arithmetic_member.rs index 3ba7c468b..c3166ce23 100644 --- a/tests/unit/out/unsafe/operator_arithmetic_member.rs +++ b/tests/unit/out/unsafe/operator_arithmetic_member.rs @@ -47,7 +47,7 @@ impl S { self.v.prefix_inc(); return &mut (*(self as *mut S)) as *mut S; } - pub unsafe fn operator_post_inc_i32(&mut self, _: i32) -> S { + pub unsafe fn operator_post_inc_i32(&mut self, mut _a0: i32) -> S { let mut old: S = (*(self as *mut S)); self.v.prefix_inc(); return old; @@ -56,7 +56,7 @@ impl S { self.v.prefix_dec(); return &mut (*(self as *mut S)) as *mut S; } - pub unsafe fn operator_post_dec_i32(&mut self, _: i32) -> S { + pub unsafe fn operator_post_dec_i32(&mut self, mut _a0: i32) -> S { let mut old: S = (*(self as *mut S)); self.v.prefix_dec(); return old; diff --git a/tests/unit/out/unsafe/operator_comparison_defaulted.rs b/tests/unit/out/unsafe/operator_comparison_defaulted.rs index 751931a1f..72c41b778 100644 --- a/tests/unit/out/unsafe/operator_comparison_defaulted.rs +++ b/tests/unit/out/unsafe/operator_comparison_defaulted.rs @@ -13,9 +13,9 @@ pub struct Eq { pub b: i32, } impl Eq { - pub unsafe fn operator_eq(&self, _arg0: *const Eq) -> bool { - return (((*(self as *const Eq)).a) == ((*_arg0).a)) - && (((*(self as *const Eq)).b) == ((*_arg0).b)); + pub unsafe fn operator_eq(&self, _a0: *const Eq) -> bool { + return (((*(self as *const Eq)).a) == ((*_a0).a)) + && (((*(self as *const Eq)).b) == ((*_a0).b)); } } impl std::cmp::PartialEq for Eq { @@ -31,24 +31,24 @@ pub struct Cmp { pub b: i32, } impl Cmp { - pub unsafe fn operator_cmp(&self, _arg0: *const Cmp) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Cmp) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const Cmp)).a).cmp(&((*_arg0).a)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Cmp)).a).cmp(&((*_a0).a)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } { - let mut cmp: std::cmp::Ordering = ((*(self as *const Cmp)).b).cmp(&((*_arg0).b)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Cmp)).b).cmp(&((*_a0).b)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } return std::cmp::Ordering::Equal; } - pub unsafe fn operator_eq(&self, _arg0: *const Cmp) -> bool { - return (((*(self as *const Cmp)).a) == ((*_arg0).a)) - && (((*(self as *const Cmp)).b) == ((*_arg0).b)); + pub unsafe fn operator_eq(&self, _a0: *const Cmp) -> bool { + return (((*(self as *const Cmp)).a) == ((*_a0).a)) + && (((*(self as *const Cmp)).b) == ((*_a0).b)); } } impl std::cmp::Ord for Cmp { @@ -73,12 +73,12 @@ pub struct Both { pub a: i32, } impl Both { - pub unsafe fn operator_eq(&self, _arg0: *const Both) -> bool { - return (((*(self as *const Both)).a) == ((*_arg0).a)); + pub unsafe fn operator_eq(&self, _a0: *const Both) -> bool { + return (((*(self as *const Both)).a) == ((*_a0).a)); } - pub unsafe fn operator_cmp(&self, _arg0: *const Both) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Both) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const Both)).a).cmp(&((*_arg0).a)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Both)).a).cmp(&((*_a0).a)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } @@ -108,9 +108,9 @@ pub struct OrdOnly { pub a: i32, } impl OrdOnly { - pub unsafe fn operator_cmp(&self, _arg0: *const OrdOnly) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const OrdOnly) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const OrdOnly)).a).cmp(&((*_arg0).a)); + let mut cmp: std::cmp::Ordering = ((*(self as *const OrdOnly)).a).cmp(&((*_a0).a)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } @@ -140,17 +140,17 @@ pub struct Inner { pub x: i32, } impl Inner { - pub unsafe fn operator_cmp(&self, _arg0: *const Inner) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Inner) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const Inner)).x).cmp(&((*_arg0).x)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Inner)).x).cmp(&((*_a0).x)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } return std::cmp::Ordering::Equal; } - pub unsafe fn operator_eq(&self, _arg0: *const Inner) -> bool { - return (((*(self as *const Inner)).x) == ((*_arg0).x)); + pub unsafe fn operator_eq(&self, _a0: *const Inner) -> bool { + return (((*(self as *const Inner)).x) == ((*_a0).x)); } } impl std::cmp::Ord for Inner { @@ -176,10 +176,10 @@ pub struct Outer { pub y: i32, } impl Outer { - pub unsafe fn operator_cmp(&self, _arg0: *const Outer) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Outer) -> std::cmp::Ordering { { let mut cmp: std::cmp::Ordering = (unsafe { - let _arg0: *const Inner = &(*_arg0).i as *const Inner; + let _arg0: *const Inner = &(*_a0).i as *const Inner; Inner::operator_cmp(&(*(self as *const Outer)).i, _arg0) }); if !(cmp == std::cmp::Ordering::Equal) { @@ -187,18 +187,18 @@ impl Outer { } } { - let mut cmp: std::cmp::Ordering = ((*(self as *const Outer)).y).cmp(&((*_arg0).y)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Outer)).y).cmp(&((*_a0).y)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } return std::cmp::Ordering::Equal; } - pub unsafe fn operator_eq(&self, _arg0: *const Outer) -> bool { + pub unsafe fn operator_eq(&self, _a0: *const Outer) -> bool { return (unsafe { - let _arg0: *const Inner = &(*_arg0).i as *const Inner; + let _arg0: *const Inner = &(*_a0).i as *const Inner; Inner::operator_eq(&(*(self as *const Outer)).i, _arg0) - }) && (((*(self as *const Outer)).y) == ((*_arg0).y)); + }) && (((*(self as *const Outer)).y) == ((*_a0).y)); } } impl std::cmp::Ord for Outer { @@ -223,33 +223,33 @@ pub struct Secondary { pub a: i32, } impl Secondary { - pub unsafe fn operator_eq(&self, _arg0: *const Secondary) -> bool { - return (((*(self as *const Secondary)).a) == ((*_arg0).a)); + pub unsafe fn operator_eq(&self, _a0: *const Secondary) -> bool { + return (((*(self as *const Secondary)).a) == ((*_a0).a)); } - pub unsafe fn operator_ne(&self, _arg0: *const Secondary) -> bool { + pub unsafe fn operator_ne(&self, _a0: *const Secondary) -> bool { return !(unsafe { - let _arg0: *const Secondary = _arg0; + let _arg0: *const Secondary = _a0; Secondary::operator_eq(&(*(self as *const Secondary)), _arg0) }); } - pub unsafe fn operator_cmp(&self, _arg0: *const Secondary) -> std::cmp::Ordering { + pub unsafe fn operator_cmp(&self, _a0: *const Secondary) -> std::cmp::Ordering { { - let mut cmp: std::cmp::Ordering = ((*(self as *const Secondary)).a).cmp(&((*_arg0).a)); + let mut cmp: std::cmp::Ordering = ((*(self as *const Secondary)).a).cmp(&((*_a0).a)); if !(cmp == std::cmp::Ordering::Equal) { return cmp; } } return std::cmp::Ordering::Equal; } - pub unsafe fn operator_lt(&self, _arg0: *const Secondary) -> bool { + pub unsafe fn operator_lt(&self, _a0: *const Secondary) -> bool { return (unsafe { - let _arg0: *const Secondary = _arg0; + let _arg0: *const Secondary = _a0; Secondary::operator_cmp(&(*(self as *const Secondary)), _arg0) }) == std::cmp::Ordering::Less; } - pub unsafe fn operator_ge(&self, _arg0: *const Secondary) -> bool { + pub unsafe fn operator_ge(&self, _a0: *const Secondary) -> bool { return (unsafe { - let _arg0: *const Secondary = _arg0; + let _arg0: *const Secondary = _a0; Secondary::operator_cmp(&(*(self as *const Secondary)), _arg0) }) != std::cmp::Ordering::Less; } diff --git a/tests/unit/out/unsafe/vector_with_allocator.rs b/tests/unit/out/unsafe/vector_with_allocator.rs index f7025a5dd..44d0acdb4 100644 --- a/tests/unit/out/unsafe/vector_with_allocator.rs +++ b/tests/unit/out/unsafe/vector_with_allocator.rs @@ -13,7 +13,7 @@ impl TestAllocator_int_ { pub unsafe fn allocate(&mut self, mut n: usize) -> *mut i32 { return Box::leak((0..n).map(|_| 0_i32).collect::>()).as_mut_ptr(); } - pub unsafe fn deallocate(&mut self, mut p: *mut i32, _: usize) { + pub unsafe fn deallocate(&mut self, mut p: *mut i32, mut _a1: usize) { ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( p, libcc2rs::malloc_usable_size(p as *mut ::libc::c_void) / ::std::mem::size_of::(), @@ -27,7 +27,7 @@ impl TestAllocator_double_ { pub unsafe fn allocate(&mut self, mut n: usize) -> *mut f64 { return Box::leak((0..n).map(|_| 0.0_f64).collect::>()).as_mut_ptr(); } - pub unsafe fn deallocate(&mut self, mut p: *mut f64, _: usize) { + pub unsafe fn deallocate(&mut self, mut p: *mut f64, mut _a1: usize) { ::std::mem::drop(Box::from_raw(::std::slice::from_raw_parts_mut( p, libcc2rs::malloc_usable_size(p as *mut ::libc::c_void) / ::std::mem::size_of::(), From 942f9cd5b1ca77dd2b5f31322e48c9a3129e5be5 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 10:29:32 +0100 Subject: [PATCH 05/11] Add rules for rest of STL types move and copy --- cpp2rust/converter/converter.cpp | 26 ------------------- cpp2rust/converter/converter.h | 1 - .../converter/models/converter_refcount.cpp | 4 --- rules/array/src.cpp | 10 +++++++ rules/array/tgt_refcount.rs | 4 +++ rules/array/tgt_unsafe.rs | 8 ++++++ rules/deque/src.cpp | 18 +++++++++++++ rules/deque/tgt_refcount.rs | 8 ++++++ rules/deque/tgt_unsafe.rs | 16 ++++++++++++ rules/map/src.cpp | 5 ++++ rules/map/tgt_refcount.rs | 11 ++++++++ rules/map/tgt_unsafe.rs | 4 +++ rules/pair/src.cpp | 15 +++++++++++ rules/pair/tgt_refcount.rs | 21 +++++++++++++++ rules/pair/tgt_unsafe.rs | 12 +++++++++ rules/string/src.cpp | 12 +++++++++ rules/string/tgt_refcount.rs | 16 ++++++++++++ rules/string/tgt_unsafe.rs | 16 ++++++++++++ rules/vector/src.cpp | 9 +++++++ rules/vector/tgt_unsafe.rs | 8 ++++++ tests/unit/out/refcount/unique_ptr.rs | 11 ++++++++ tests/unit/out/unsafe/huffman.rs | 20 +++++++++----- 22 files changed, 218 insertions(+), 37 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 84e8d9ff7..07aed1c85 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1726,28 +1726,6 @@ void Converter::ConvertVAArgCall(clang::CallExpr *expr) { } } -bool Converter::ConvertMemberAssignmentCall(clang::CallExpr *expr) { - auto *member_call = clang::dyn_cast(expr); - if (!member_call) { - return false; - } - auto *callee = member_call->getMethodDecl(); - if (!callee || (!callee->isCopyAssignmentOperator() && - !callee->isMoveAssignmentOperator())) { - return false; - } - auto *object = member_call->getImplicitObjectArgument(); - if (clang::isa(object->IgnoreParenImpCasts())) { - return true; - } - if (IsUserDefinedDecl(callee->getParent()) || - Mapper::Contains(member_call->getCallee())) { - return false; - } - ConvertAssignment(object, member_call->getArg(0), "="); - return true; -} - bool Converter::VisitCallExpr(clang::CallExpr *expr) { if (IsBuiltinVaStart(expr) || IsBuiltinVaEnd(expr) || IsBuiltinVaCopy(expr)) { ConvertVAArgCall(expr); @@ -1770,10 +1748,6 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) { return false; } - if (ConvertMemberAssignmentCall(expr)) { - return false; - } - if (auto plugin_str = TryPluginConvert(expr)) { StrCat(*plugin_str); return false; diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 54a453d14..894c12ce2 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -333,7 +333,6 @@ class Converter : public clang::RecursiveASTVisitor { void DefineImplicitMembers(clang::CXXRecordDecl *decl); - bool ConvertMemberAssignmentCall(clang::CallExpr *expr); virtual bool VisitCallExpr(clang::CallExpr *expr); virtual bool VisitIntegerLiteral(clang::IntegerLiteral *expr); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index dbc423431..08fff8b99 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1073,10 +1073,6 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) { return Converter::VisitCallExpr(expr); } - if (ConvertMemberAssignmentCall(expr)) { - return false; - } - if (auto *opcall = clang::dyn_cast(expr); opcall && !IsUserOperatorCall(opcall) && !Mapper::Contains(expr->getCallee())) { diff --git a/rules/array/src.cpp b/rules/array/src.cpp index 4429fe38e..e6a94502b 100644 --- a/rules/array/src.cpp +++ b/rules/array/src.cpp @@ -29,3 +29,13 @@ template std::array &f5(std::array &dst, std::array &&src) { return dst.operator=(std::move(src)); } + +template +std::array f6(const std::array &o) { + return std::array(o); +} + +template +std::array &f7(std::array &dst, const std::array &src) { + return dst.operator=(src); +} diff --git a/rules/array/tgt_refcount.rs b/rules/array/tgt_refcount.rs index e558b8eeb..7b1fd4963 100644 --- a/rules/array/tgt_refcount.rs +++ b/rules/array/tgt_refcount.rs @@ -16,3 +16,7 @@ fn f3(a0: Ptr) -> Ptr { fn f5(a0: Ptr>, a1: &mut Vec) { a0.write(std::mem::take(&mut *a1)) } + +fn f7(a0: Ptr>, a1: Vec) { + a0.write(a1.clone()) +} diff --git a/rules/array/tgt_unsafe.rs b/rules/array/tgt_unsafe.rs index dd98ee0fc..b9bda11da 100644 --- a/rules/array/tgt_unsafe.rs +++ b/rules/array/tgt_unsafe.rs @@ -26,3 +26,11 @@ unsafe fn f4(a0: &mut Vec) -> Vec { unsafe fn f5(a0: &mut Vec, a1: &mut Vec) { *a0 = std::mem::take(&mut *a1) } + +unsafe fn f6(a0: Vec) -> Vec { + a0.clone() +} + +unsafe fn f7(a0: &mut Vec, a1: Vec) { + *a0 = a1.clone() +} diff --git a/rules/deque/src.cpp b/rules/deque/src.cpp index b7c1bac32..1024ff652 100644 --- a/rules/deque/src.cpp +++ b/rules/deque/src.cpp @@ -22,3 +22,21 @@ template void f7(std::deque> &o, const std::vector &value) { return o.push_back(value); } + +template std::deque f8(const std::deque &o) { + return std::deque(o); +} + +template std::deque f9(std::deque &&o) { + return std::deque(std::move(o)); +} + +template +std::deque &f10(std::deque &dst, const std::deque &src) { + return dst.operator=(src); +} + +template +std::deque &f11(std::deque &dst, std::deque &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/deque/tgt_refcount.rs b/rules/deque/tgt_refcount.rs index 8ff487e6f..d3915854c 100644 --- a/rules/deque/tgt_refcount.rs +++ b/rules/deque/tgt_refcount.rs @@ -16,3 +16,11 @@ fn f2(a0: Ptr) -> Ptr { fn f7(a0: Ptr>>>, a1: Value>) { a0.with_mut(|__v: &mut Vec>>| __v.push(a1)) } + +fn f10(a0: Ptr>, a1: Vec) { + a0.write(a1.clone()) +} + +fn f11(a0: Ptr>, a1: &mut Vec) { + a0.write(std::mem::take(&mut *a1)) +} diff --git a/rules/deque/tgt_unsafe.rs b/rules/deque/tgt_unsafe.rs index 8382d48f9..193ff3c79 100644 --- a/rules/deque/tgt_unsafe.rs +++ b/rules/deque/tgt_unsafe.rs @@ -32,3 +32,19 @@ unsafe fn f5(a0: &mut Vec) -> T1 { unsafe fn f7(a0: &mut Vec>, a1: Vec) { a0.push(a1) } + +unsafe fn f8(a0: Vec) -> Vec { + a0.clone() +} + +unsafe fn f9(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} + +unsafe fn f10(a0: &mut Vec, a1: Vec) { + *a0 = a1.clone() +} + +unsafe fn f11(a0: &mut Vec, a1: &mut Vec) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/rules/map/src.cpp b/rules/map/src.cpp index f1479d0e9..121a14051 100644 --- a/rules/map/src.cpp +++ b/rules/map/src.cpp @@ -126,3 +126,8 @@ template std::map &f25(std::map &dst, std::map &&src) { return dst.operator=(std::move(src)); } + +template +std::map &f26(std::map &dst, const std::map &src) { + return dst.operator=(src); +} diff --git a/rules/map/tgt_refcount.rs b/rules/map/tgt_refcount.rs index 457c23b73..c0fba36ab 100644 --- a/rules/map/tgt_refcount.rs +++ b/rules/map/tgt_refcount.rs @@ -151,3 +151,14 @@ fn f25( let __src = a1.with_mut(|__v: &mut BTreeMap>| std::mem::take(__v)); a0.write(__src) } + +fn f26( + a0: Ptr>>, + a1: BTreeMap>, +) { + a0.write( + a1.iter() + .map(|(k, v)| (k.clone(), Rc::new(RefCell::new(v.borrow().clone())))) + .collect(), + ) +} diff --git a/rules/map/tgt_unsafe.rs b/rules/map/tgt_unsafe.rs index 8024cad2b..91f23ba31 100644 --- a/rules/map/tgt_unsafe.rs +++ b/rules/map/tgt_unsafe.rs @@ -110,3 +110,7 @@ unsafe fn f24(a0: &mut BTreeMap>) -> BTreeMap> { unsafe fn f25(a0: &mut BTreeMap>, a1: &mut BTreeMap>) { *a0 = std::mem::take(&mut *a1) } + +unsafe fn f26(a0: &mut BTreeMap>, a1: BTreeMap>) { + *a0 = a1.clone() +} diff --git a/rules/pair/src.cpp b/rules/pair/src.cpp index 24d4ec4c4..dbf2fbf50 100644 --- a/rules/pair/src.cpp +++ b/rules/pair/src.cpp @@ -45,3 +45,18 @@ template auto f10(T1 &&a0, T2 &&a1) { template T1 &f11(std::pair &a0) { return a0.first; } + +template +std::pair f12(std::pair &&a0) { + return std::pair(std::move(a0)); +} + +template +std::pair &f13(std::pair &dst, const std::pair &src) { + return dst.operator=(src); +} + +template +std::pair &f14(std::pair &dst, std::pair &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/pair/tgt_refcount.rs b/rules/pair/tgt_refcount.rs index d8a49175a..e69c4d842 100644 --- a/rules/pair/tgt_refcount.rs +++ b/rules/pair/tgt_refcount.rs @@ -68,3 +68,24 @@ fn f10(a0: T1, a1: T2) -> (Value, Value) { fn f11(a0: (Value, Value)) -> Value { a0.0 } + +fn f12(a0: &mut (Value, Value)) -> (Value, Value) { + std::mem::take(&mut *a0) +} + +fn f13( + a0: Ptr<(Value, Value)>, + a1: (Value, Value), +) { + a0.write(( + Rc::new(RefCell::new(a1.0.borrow().clone())), + Rc::new(RefCell::new(a1.1.borrow().clone())), + )) +} + +fn f14( + a0: Ptr<(Value, Value)>, + a1: &mut (Value, Value), +) { + a0.write(std::mem::take(&mut *a1)) +} diff --git a/rules/pair/tgt_unsafe.rs b/rules/pair/tgt_unsafe.rs index c00a09c9e..cfeaa58a5 100644 --- a/rules/pair/tgt_unsafe.rs +++ b/rules/pair/tgt_unsafe.rs @@ -33,3 +33,15 @@ unsafe fn f10(a0: T1, a1: T2) -> (T1, T2) { unsafe fn f11(a0: (T1, T2)) -> T1 { a0.0 } + +unsafe fn f12(a0: &mut (T1, T2)) -> (T1, T2) { + std::mem::take(&mut *a0) +} + +unsafe fn f13(a0: &mut (T1, T2), a1: (T1, T2)) { + *a0 = a1.clone() +} + +unsafe fn f14(a0: &mut (T1, T2), a1: &mut (T1, T2)) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/rules/string/src.cpp b/rules/string/src.cpp index 1d6bfab9c..0a3581e8c 100644 --- a/rules/string/src.cpp +++ b/rules/string/src.cpp @@ -75,3 +75,15 @@ void f24(std::string &o) { return o.clear(); } void f25(std::string &o) { return o.shrink_to_fit(); } char &f26(std::string &o, std::size_t idx) { return o.at(idx); } + +std::string f27(const std::string &o) { return std::string(o); } + +std::string f28(std::string &&o) { return std::string(std::move(o)); } + +std::string &f29(std::string &dst, const std::string &src) { + return dst.operator=(src); +} + +std::string &f30(std::string &dst, std::string &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/string/tgt_refcount.rs b/rules/string/tgt_refcount.rs index 389e68fa9..3550c267d 100644 --- a/rules/string/tgt_refcount.rs +++ b/rules/string/tgt_refcount.rs @@ -174,3 +174,19 @@ fn f24(a0: &mut Vec) { fn f25(a0: &mut Vec) { a0.shrink_to_fit() } + +fn f27(a0: Vec) -> Vec { + a0.clone() +} + +fn f28(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} + +fn f29(a0: Ptr>, a1: Vec) { + a0.write(a1.clone()) +} + +fn f30(a0: Ptr>, a1: &mut Vec) { + a0.write(std::mem::take(&mut *a1)) +} diff --git a/rules/string/tgt_unsafe.rs b/rules/string/tgt_unsafe.rs index b36e9d9b7..e2c2bd91c 100644 --- a/rules/string/tgt_unsafe.rs +++ b/rules/string/tgt_unsafe.rs @@ -164,3 +164,19 @@ unsafe fn f26(a0: &mut Vec, a1: usize) -> *mut libc::c_char { &mut a0[a1 as usize] } } + +unsafe fn f27(a0: Vec) -> Vec { + a0.clone() +} + +unsafe fn f28(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} + +unsafe fn f29(a0: &mut Vec, a1: Vec) { + *a0 = a1.clone() +} + +unsafe fn f30(a0: &mut Vec, a1: &mut Vec) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/rules/vector/src.cpp b/rules/vector/src.cpp index 39b424fd9..73cb285f0 100644 --- a/rules/vector/src.cpp +++ b/rules/vector/src.cpp @@ -536,3 +536,12 @@ template > std::vector f108(std::vector &&o) { return std::vector(std::move(o)); } + +template std::vector f109(const std::vector &o) { + return std::vector(o); +} + +template > +std::vector f110(const std::vector &o) { + return std::vector(o); +} diff --git a/rules/vector/tgt_unsafe.rs b/rules/vector/tgt_unsafe.rs index 22abe970b..542283391 100644 --- a/rules/vector/tgt_unsafe.rs +++ b/rules/vector/tgt_unsafe.rs @@ -481,3 +481,11 @@ unsafe fn f107(a0: &mut Vec) -> Vec { unsafe fn f108(a0: &mut Vec) -> Vec { std::mem::take(&mut *a0) } + +unsafe fn f109(a0: Vec) -> Vec { + a0.clone() +} + +unsafe fn f110(a0: Vec) -> Vec { + a0.clone() +} diff --git a/tests/unit/out/refcount/unique_ptr.rs b/tests/unit/out/refcount/unique_ptr.rs index 057d2497d..91ab24ae6 100644 --- a/tests/unit/out/refcount/unique_ptr.rs +++ b/tests/unit/out/refcount/unique_ptr.rs @@ -10,6 +10,17 @@ use std::rc::{Rc, Weak}; pub struct SafePointer { pub ptr: Value>>, } +impl SafePointer { + pub fn SafePointer_pmutSafePointer(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + ptr: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).ptr.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for SafePointer { fn byte_size() -> usize { 8 diff --git a/tests/unit/out/unsafe/huffman.rs b/tests/unit/out/unsafe/huffman.rs index ea15aba8e..a34c73a7f 100644 --- a/tests/unit/out/unsafe/huffman.rs +++ b/tests/unit/out/unsafe/huffman.rs @@ -26,20 +26,18 @@ pub unsafe fn Swap_0(a: *mut MinHeapNode, b: *mut MinHeapNode) { left: (*a).left, right: (*a).right, }; - (*a) = (MinHeapNode { + (*a) = MinHeapNode { data: (*b).data, freq: (*b).freq, left: (*b).left, right: (*b).right, - }) - .clone(); - (*b) = (MinHeapNode { + }; + (*b) = MinHeapNode { data: t.data, freq: t.freq, left: t.left, right: t.right, - }) - .clone(); + }; } #[repr(C)] #[derive(Default)] @@ -129,6 +127,16 @@ impl MinHeap { i.prefix_dec(); } } + pub unsafe fn MinHeap_pmutMinHeap(_a0: *mut MinHeap) -> Self { + let mut this = Self { + size: (*_a0).size, + capacity: (*_a0).capacity, + arr: (*_a0).arr.take(), + next: (*_a0).next, + alloc: (*_a0).alloc.take(), + }; + this + } } pub unsafe fn AllocMinHeap_1(mut capacity: i32) -> Option> { let mut minHeap: Option> = Some(Box::new(MinHeap { From c02b2a539ff8c7f40f3830f4d0af69aaf93d744f Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 10:39:27 +0100 Subject: [PATCH 06/11] Add rule for builtin memcpy --- cpp2rust/converter/converter.cpp | 10 ---------- cpp2rust/converter/converter_lib.cpp | 19 ------------------- cpp2rust/converter/converter_lib.h | 2 -- .../converter/models/converter_refcount.cpp | 10 ---------- rules/builtin/src.cpp | 6 ++++++ rules/builtin/tgt_refcount.rs | 5 +++++ rules/builtin/tgt_unsafe.rs | 7 +++++++ .../out/refcount/defaulted_move_cross_tu.rs | 13 +++++++++++-- .../out/unsafe/defaulted_move_cross_tu.rs | 11 ++++++++++- .../unit/out/refcount/copy_move_defaulted.rs | 13 +++++++++++-- tests/unit/out/unsafe/copy_move_defaulted.rs | 12 +++++++++++- 11 files changed, 61 insertions(+), 47 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 07aed1c85..2135271db 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1732,16 +1732,6 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) { return false; } - if (IsMemberMemcpy(expr)) { - ConvertAssignment( - clang::cast(expr->getArg(0)->IgnoreImpCasts()) - ->getSubExpr(), - clang::cast(expr->getArg(1)->IgnoreImpCasts()) - ->getSubExpr(), - "="); - return false; - } - // p->~T() on a scalar is a no-op if (clang::isa( expr->getCallee()->IgnoreParenImpCasts())) { diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 91c0ab8b3..2e21efeac 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -354,25 +354,6 @@ bool HasDefaultedCopyConstructor(const clang::RecordDecl *decl) { return !cxx->defaultedCopyConstructorIsDeleted(); } -bool IsMemberMemcpy(const clang::CallExpr *expr) { - const auto *fn = expr->getDirectCallee(); - if (!fn || fn->getBuiltinID() != clang::Builtin::BI__builtin_memcpy) { - return false; - } - auto member = [](const clang::Expr *arg) -> const clang::MemberExpr * { - const auto *unary = - clang::dyn_cast(arg->IgnoreImpCasts()); - if (!unary || unary->getOpcode() != clang::UO_AddrOf) { - return nullptr; - } - return clang::dyn_cast( - unary->getSubExpr()->IgnoreImpCasts()); - }; - const auto *dst = member(expr->getArg(0)); - const auto *src = member(expr->getArg(1)); - return dst && src && dst->getType() == src->getType(); -} - bool HasCallableCopyConstructor(const clang::RecordDecl *decl) { auto *cxx = clang::dyn_cast(decl); if (!cxx) { diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index d6f05a2a8..1eae1ccfd 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -76,8 +76,6 @@ bool IsUserDefinedCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor); bool IsUserDefinedMoveAssignment(const clang::CXXMethodDecl *method); -bool IsMemberMemcpy(const clang::CallExpr *expr); - bool IsUserDefinedMoveConstructorOrAssignment( const clang::CXXMethodDecl *method); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 08fff8b99..1a02e5d98 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1053,16 +1053,6 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) { return false; } - if (IsMemberMemcpy(expr)) { - ConvertAssignment( - clang::cast(expr->getArg(0)->IgnoreImpCasts()) - ->getSubExpr(), - clang::cast(expr->getArg(1)->IgnoreImpCasts()) - ->getSubExpr(), - "="); - return false; - } - // p->~T() on a scalar is a no-op if (clang::isa( expr->getCallee()->IgnoreParenImpCasts())) { diff --git a/rules/builtin/src.cpp b/rules/builtin/src.cpp index f52cf5a88..d22f82392 100644 --- a/rules/builtin/src.cpp +++ b/rules/builtin/src.cpp @@ -1,6 +1,8 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +#include + #if defined(__linux__) #include #elif !defined(__APPLE__) @@ -26,3 +28,7 @@ bool f10(long long a, long long b, long long *r) { return __builtin_mul_overflow #if defined(__x86_64__) || defined(__i386__) void f11(void) { return __builtin_ia32_pause(); } #endif + +void *f14(void *dst, const void *src, size_t n) { + return __builtin_memcpy(dst, src, n); +} diff --git a/rules/builtin/tgt_refcount.rs b/rules/builtin/tgt_refcount.rs index 4e1afbbc4..d1dd3570a 100644 --- a/rules/builtin/tgt_refcount.rs +++ b/rules/builtin/tgt_refcount.rs @@ -23,3 +23,8 @@ fn f13(a0: i64, a1: i64, a2: Ptr) -> bool { a2.write(val); ovf } + +fn f14(a0: AnyPtr, a1: AnyPtr, a2: usize) -> AnyPtr { + a0.memcpy(&a1, a2 as usize); + a0.clone() +} diff --git a/rules/builtin/tgt_unsafe.rs b/rules/builtin/tgt_unsafe.rs index 1d0e7cb87..95bdb6082 100644 --- a/rules/builtin/tgt_unsafe.rs +++ b/rules/builtin/tgt_unsafe.rs @@ -50,3 +50,10 @@ unsafe fn f13(a0: i64, a1: i64, a2: *mut i64) -> bool { *a2 = val; ovf } + +unsafe fn f14(a0: *mut u8, a1: *const u8, a2: usize) -> *mut u8 { + if a2 != 0 { + ::std::ptr::copy_nonoverlapping(a1, a0, a2 as usize) + } + a0 +} diff --git a/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs b/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs index 577d60b4d..5dab9d5fd 100644 --- a/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs +++ b/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs @@ -98,8 +98,17 @@ impl SImpl for Ptr { ((*(*self).upgrade().deref()).v.as_pointer() as Ptr>).write(std::mem::take( &mut (*(*_a0.upgrade().deref()).v.borrow_mut()), )); - let __rhs = (*(*_a0.upgrade().deref()).n.borrow()).clone(); - (*(*(*self).upgrade().deref()).n.borrow_mut()) = __rhs; + { + (((*(*self).upgrade().deref()).n.as_pointer()) as Ptr) + .to_any() + .memcpy( + &(((*_a0.upgrade().deref()).n.as_pointer()) as Ptr).to_any(), + 8_usize as usize, + ); + (((*(*self).upgrade().deref()).n.as_pointer()) as Ptr) + .to_any() + .clone() + }; return (*self).clone(); } } diff --git a/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs b/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs index 1db3eff4e..762860a11 100644 --- a/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs +++ b/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs @@ -53,7 +53,16 @@ impl S { } pub unsafe fn operator_assign_pmutS(&mut self, _a0: *mut S) -> *mut S { self.v = std::mem::take(&mut (*_a0).v); - self.n = ((*_a0).n).clone(); + { + if 8_usize != 0 { + ::std::ptr::copy_nonoverlapping( + ((&mut (*_a0).n as *mut [i32; 2]) as *const [i32; 2] as *const ::libc::c_void), + ((&mut self.n as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void), + 8_usize as usize, + ) + } + ((&mut self.n as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void) + }; return &mut (*(self as *mut S)) as *mut S; } } diff --git a/tests/unit/out/refcount/copy_move_defaulted.rs b/tests/unit/out/refcount/copy_move_defaulted.rs index e451fd040..eb66537a9 100644 --- a/tests/unit/out/refcount/copy_move_defaulted.rs +++ b/tests/unit/out/refcount/copy_move_defaulted.rs @@ -519,8 +519,17 @@ impl BufferImpl for Ptr { )); let __rhs = (*(*_a0.upgrade().deref()).n.borrow()); (*(*(*self).upgrade().deref()).n.borrow_mut()) = __rhs; - let __rhs = (*(*_a0.upgrade().deref()).arr.borrow()).clone(); - (*(*(*self).upgrade().deref()).arr.borrow_mut()) = __rhs; + { + (((*(*self).upgrade().deref()).arr.as_pointer()) as Ptr) + .to_any() + .memcpy( + &(((*_a0.upgrade().deref()).arr.as_pointer()) as Ptr).to_any(), + 8_usize as usize, + ); + (((*(*self).upgrade().deref()).arr.as_pointer()) as Ptr) + .to_any() + .clone() + }; return (*self).clone(); } } diff --git a/tests/unit/out/unsafe/copy_move_defaulted.rs b/tests/unit/out/unsafe/copy_move_defaulted.rs index 0d38c53d8..8f4db2a3f 100644 --- a/tests/unit/out/unsafe/copy_move_defaulted.rs +++ b/tests/unit/out/unsafe/copy_move_defaulted.rs @@ -153,7 +153,17 @@ impl Buffer { pub unsafe fn operator_assign_pmutBuffer(&mut self, _a0: *mut Buffer) -> *mut Buffer { self.data = std::mem::take(&mut (*_a0).data); self.n = (*_a0).n; - self.arr = ((*_a0).arr).clone(); + { + if 8_usize != 0 { + ::std::ptr::copy_nonoverlapping( + ((&mut (*_a0).arr as *mut [i32; 2]) as *const [i32; 2] + as *const ::libc::c_void), + ((&mut self.arr as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void), + 8_usize as usize, + ) + } + ((&mut self.arr as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void) + }; return &mut (*(self as *mut Buffer)) as *mut Buffer; } } From a95b94d25febadf6936fdaf472cd91d13647671d Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 12:58:07 +0100 Subject: [PATCH 07/11] Add todo --- cpp2rust/converter/converter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 2135271db..5136b28b3 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -253,6 +253,7 @@ Converter::ConvertRValue(clang::Expr *expr, std::string Converter::ConvertFreshRValue( clang::Expr *expr, std::optional implicit_convert_to) { auto str = ConvertRValue(expr, implicit_convert_to); + // TODO: set freshness correctly to avoid stale computed_expr_type_ if (expr->isGLValue()) { SetValueFreshness(expr->getType()); } From 6c220ee13c23c35117b6f4b956922b53faa823a5 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 13:00:20 +0100 Subject: [PATCH 08/11] Add more rules for move assignment and constructor --- rules/array/src.cpp | 10 ++++++++++ rules/array/tgt_refcount.rs | 4 ++++ rules/array/tgt_unsafe.rs | 8 ++++++++ rules/builtin/src.cpp | 6 ++++++ rules/builtin/tgt_refcount.rs | 5 +++++ rules/builtin/tgt_unsafe.rs | 7 +++++++ rules/deque/src.cpp | 18 ++++++++++++++++++ rules/deque/tgt_refcount.rs | 8 ++++++++ rules/deque/tgt_unsafe.rs | 16 ++++++++++++++++ rules/map/src.cpp | 5 +++++ rules/map/tgt_refcount.rs | 11 +++++++++++ rules/map/tgt_unsafe.rs | 4 ++++ rules/pair/src.cpp | 15 +++++++++++++++ rules/pair/tgt_refcount.rs | 21 +++++++++++++++++++++ rules/pair/tgt_unsafe.rs | 12 ++++++++++++ rules/string/src.cpp | 12 ++++++++++++ rules/string/tgt_refcount.rs | 16 ++++++++++++++++ rules/string/tgt_unsafe.rs | 16 ++++++++++++++++ rules/vector/src.cpp | 9 +++++++++ rules/vector/tgt_unsafe.rs | 8 ++++++++ 20 files changed, 211 insertions(+) diff --git a/rules/array/src.cpp b/rules/array/src.cpp index 4429fe38e..e6a94502b 100644 --- a/rules/array/src.cpp +++ b/rules/array/src.cpp @@ -29,3 +29,13 @@ template std::array &f5(std::array &dst, std::array &&src) { return dst.operator=(std::move(src)); } + +template +std::array f6(const std::array &o) { + return std::array(o); +} + +template +std::array &f7(std::array &dst, const std::array &src) { + return dst.operator=(src); +} diff --git a/rules/array/tgt_refcount.rs b/rules/array/tgt_refcount.rs index e558b8eeb..7b1fd4963 100644 --- a/rules/array/tgt_refcount.rs +++ b/rules/array/tgt_refcount.rs @@ -16,3 +16,7 @@ fn f3(a0: Ptr) -> Ptr { fn f5(a0: Ptr>, a1: &mut Vec) { a0.write(std::mem::take(&mut *a1)) } + +fn f7(a0: Ptr>, a1: Vec) { + a0.write(a1.clone()) +} diff --git a/rules/array/tgt_unsafe.rs b/rules/array/tgt_unsafe.rs index dd98ee0fc..b9bda11da 100644 --- a/rules/array/tgt_unsafe.rs +++ b/rules/array/tgt_unsafe.rs @@ -26,3 +26,11 @@ unsafe fn f4(a0: &mut Vec) -> Vec { unsafe fn f5(a0: &mut Vec, a1: &mut Vec) { *a0 = std::mem::take(&mut *a1) } + +unsafe fn f6(a0: Vec) -> Vec { + a0.clone() +} + +unsafe fn f7(a0: &mut Vec, a1: Vec) { + *a0 = a1.clone() +} diff --git a/rules/builtin/src.cpp b/rules/builtin/src.cpp index f52cf5a88..d22f82392 100644 --- a/rules/builtin/src.cpp +++ b/rules/builtin/src.cpp @@ -1,6 +1,8 @@ // Copyright (c) 2022-present INESC-ID. // Distributed under the MIT license that can be found in the LICENSE file. +#include + #if defined(__linux__) #include #elif !defined(__APPLE__) @@ -26,3 +28,7 @@ bool f10(long long a, long long b, long long *r) { return __builtin_mul_overflow #if defined(__x86_64__) || defined(__i386__) void f11(void) { return __builtin_ia32_pause(); } #endif + +void *f14(void *dst, const void *src, size_t n) { + return __builtin_memcpy(dst, src, n); +} diff --git a/rules/builtin/tgt_refcount.rs b/rules/builtin/tgt_refcount.rs index 4e1afbbc4..d1dd3570a 100644 --- a/rules/builtin/tgt_refcount.rs +++ b/rules/builtin/tgt_refcount.rs @@ -23,3 +23,8 @@ fn f13(a0: i64, a1: i64, a2: Ptr) -> bool { a2.write(val); ovf } + +fn f14(a0: AnyPtr, a1: AnyPtr, a2: usize) -> AnyPtr { + a0.memcpy(&a1, a2 as usize); + a0.clone() +} diff --git a/rules/builtin/tgt_unsafe.rs b/rules/builtin/tgt_unsafe.rs index 1d0e7cb87..95bdb6082 100644 --- a/rules/builtin/tgt_unsafe.rs +++ b/rules/builtin/tgt_unsafe.rs @@ -50,3 +50,10 @@ unsafe fn f13(a0: i64, a1: i64, a2: *mut i64) -> bool { *a2 = val; ovf } + +unsafe fn f14(a0: *mut u8, a1: *const u8, a2: usize) -> *mut u8 { + if a2 != 0 { + ::std::ptr::copy_nonoverlapping(a1, a0, a2 as usize) + } + a0 +} diff --git a/rules/deque/src.cpp b/rules/deque/src.cpp index b7c1bac32..1024ff652 100644 --- a/rules/deque/src.cpp +++ b/rules/deque/src.cpp @@ -22,3 +22,21 @@ template void f7(std::deque> &o, const std::vector &value) { return o.push_back(value); } + +template std::deque f8(const std::deque &o) { + return std::deque(o); +} + +template std::deque f9(std::deque &&o) { + return std::deque(std::move(o)); +} + +template +std::deque &f10(std::deque &dst, const std::deque &src) { + return dst.operator=(src); +} + +template +std::deque &f11(std::deque &dst, std::deque &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/deque/tgt_refcount.rs b/rules/deque/tgt_refcount.rs index 8ff487e6f..d3915854c 100644 --- a/rules/deque/tgt_refcount.rs +++ b/rules/deque/tgt_refcount.rs @@ -16,3 +16,11 @@ fn f2(a0: Ptr) -> Ptr { fn f7(a0: Ptr>>>, a1: Value>) { a0.with_mut(|__v: &mut Vec>>| __v.push(a1)) } + +fn f10(a0: Ptr>, a1: Vec) { + a0.write(a1.clone()) +} + +fn f11(a0: Ptr>, a1: &mut Vec) { + a0.write(std::mem::take(&mut *a1)) +} diff --git a/rules/deque/tgt_unsafe.rs b/rules/deque/tgt_unsafe.rs index 8382d48f9..193ff3c79 100644 --- a/rules/deque/tgt_unsafe.rs +++ b/rules/deque/tgt_unsafe.rs @@ -32,3 +32,19 @@ unsafe fn f5(a0: &mut Vec) -> T1 { unsafe fn f7(a0: &mut Vec>, a1: Vec) { a0.push(a1) } + +unsafe fn f8(a0: Vec) -> Vec { + a0.clone() +} + +unsafe fn f9(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} + +unsafe fn f10(a0: &mut Vec, a1: Vec) { + *a0 = a1.clone() +} + +unsafe fn f11(a0: &mut Vec, a1: &mut Vec) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/rules/map/src.cpp b/rules/map/src.cpp index f1479d0e9..121a14051 100644 --- a/rules/map/src.cpp +++ b/rules/map/src.cpp @@ -126,3 +126,8 @@ template std::map &f25(std::map &dst, std::map &&src) { return dst.operator=(std::move(src)); } + +template +std::map &f26(std::map &dst, const std::map &src) { + return dst.operator=(src); +} diff --git a/rules/map/tgt_refcount.rs b/rules/map/tgt_refcount.rs index 457c23b73..c0fba36ab 100644 --- a/rules/map/tgt_refcount.rs +++ b/rules/map/tgt_refcount.rs @@ -151,3 +151,14 @@ fn f25( let __src = a1.with_mut(|__v: &mut BTreeMap>| std::mem::take(__v)); a0.write(__src) } + +fn f26( + a0: Ptr>>, + a1: BTreeMap>, +) { + a0.write( + a1.iter() + .map(|(k, v)| (k.clone(), Rc::new(RefCell::new(v.borrow().clone())))) + .collect(), + ) +} diff --git a/rules/map/tgt_unsafe.rs b/rules/map/tgt_unsafe.rs index 8024cad2b..91f23ba31 100644 --- a/rules/map/tgt_unsafe.rs +++ b/rules/map/tgt_unsafe.rs @@ -110,3 +110,7 @@ unsafe fn f24(a0: &mut BTreeMap>) -> BTreeMap> { unsafe fn f25(a0: &mut BTreeMap>, a1: &mut BTreeMap>) { *a0 = std::mem::take(&mut *a1) } + +unsafe fn f26(a0: &mut BTreeMap>, a1: BTreeMap>) { + *a0 = a1.clone() +} diff --git a/rules/pair/src.cpp b/rules/pair/src.cpp index 24d4ec4c4..dbf2fbf50 100644 --- a/rules/pair/src.cpp +++ b/rules/pair/src.cpp @@ -45,3 +45,18 @@ template auto f10(T1 &&a0, T2 &&a1) { template T1 &f11(std::pair &a0) { return a0.first; } + +template +std::pair f12(std::pair &&a0) { + return std::pair(std::move(a0)); +} + +template +std::pair &f13(std::pair &dst, const std::pair &src) { + return dst.operator=(src); +} + +template +std::pair &f14(std::pair &dst, std::pair &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/pair/tgt_refcount.rs b/rules/pair/tgt_refcount.rs index d8a49175a..e69c4d842 100644 --- a/rules/pair/tgt_refcount.rs +++ b/rules/pair/tgt_refcount.rs @@ -68,3 +68,24 @@ fn f10(a0: T1, a1: T2) -> (Value, Value) { fn f11(a0: (Value, Value)) -> Value { a0.0 } + +fn f12(a0: &mut (Value, Value)) -> (Value, Value) { + std::mem::take(&mut *a0) +} + +fn f13( + a0: Ptr<(Value, Value)>, + a1: (Value, Value), +) { + a0.write(( + Rc::new(RefCell::new(a1.0.borrow().clone())), + Rc::new(RefCell::new(a1.1.borrow().clone())), + )) +} + +fn f14( + a0: Ptr<(Value, Value)>, + a1: &mut (Value, Value), +) { + a0.write(std::mem::take(&mut *a1)) +} diff --git a/rules/pair/tgt_unsafe.rs b/rules/pair/tgt_unsafe.rs index c00a09c9e..cfeaa58a5 100644 --- a/rules/pair/tgt_unsafe.rs +++ b/rules/pair/tgt_unsafe.rs @@ -33,3 +33,15 @@ unsafe fn f10(a0: T1, a1: T2) -> (T1, T2) { unsafe fn f11(a0: (T1, T2)) -> T1 { a0.0 } + +unsafe fn f12(a0: &mut (T1, T2)) -> (T1, T2) { + std::mem::take(&mut *a0) +} + +unsafe fn f13(a0: &mut (T1, T2), a1: (T1, T2)) { + *a0 = a1.clone() +} + +unsafe fn f14(a0: &mut (T1, T2), a1: &mut (T1, T2)) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/rules/string/src.cpp b/rules/string/src.cpp index 1d6bfab9c..0a3581e8c 100644 --- a/rules/string/src.cpp +++ b/rules/string/src.cpp @@ -75,3 +75,15 @@ void f24(std::string &o) { return o.clear(); } void f25(std::string &o) { return o.shrink_to_fit(); } char &f26(std::string &o, std::size_t idx) { return o.at(idx); } + +std::string f27(const std::string &o) { return std::string(o); } + +std::string f28(std::string &&o) { return std::string(std::move(o)); } + +std::string &f29(std::string &dst, const std::string &src) { + return dst.operator=(src); +} + +std::string &f30(std::string &dst, std::string &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/string/tgt_refcount.rs b/rules/string/tgt_refcount.rs index 389e68fa9..3550c267d 100644 --- a/rules/string/tgt_refcount.rs +++ b/rules/string/tgt_refcount.rs @@ -174,3 +174,19 @@ fn f24(a0: &mut Vec) { fn f25(a0: &mut Vec) { a0.shrink_to_fit() } + +fn f27(a0: Vec) -> Vec { + a0.clone() +} + +fn f28(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} + +fn f29(a0: Ptr>, a1: Vec) { + a0.write(a1.clone()) +} + +fn f30(a0: Ptr>, a1: &mut Vec) { + a0.write(std::mem::take(&mut *a1)) +} diff --git a/rules/string/tgt_unsafe.rs b/rules/string/tgt_unsafe.rs index b36e9d9b7..e2c2bd91c 100644 --- a/rules/string/tgt_unsafe.rs +++ b/rules/string/tgt_unsafe.rs @@ -164,3 +164,19 @@ unsafe fn f26(a0: &mut Vec, a1: usize) -> *mut libc::c_char { &mut a0[a1 as usize] } } + +unsafe fn f27(a0: Vec) -> Vec { + a0.clone() +} + +unsafe fn f28(a0: &mut Vec) -> Vec { + std::mem::take(&mut *a0) +} + +unsafe fn f29(a0: &mut Vec, a1: Vec) { + *a0 = a1.clone() +} + +unsafe fn f30(a0: &mut Vec, a1: &mut Vec) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/rules/vector/src.cpp b/rules/vector/src.cpp index 39b424fd9..73cb285f0 100644 --- a/rules/vector/src.cpp +++ b/rules/vector/src.cpp @@ -536,3 +536,12 @@ template > std::vector f108(std::vector &&o) { return std::vector(std::move(o)); } + +template std::vector f109(const std::vector &o) { + return std::vector(o); +} + +template > +std::vector f110(const std::vector &o) { + return std::vector(o); +} diff --git a/rules/vector/tgt_unsafe.rs b/rules/vector/tgt_unsafe.rs index 22abe970b..542283391 100644 --- a/rules/vector/tgt_unsafe.rs +++ b/rules/vector/tgt_unsafe.rs @@ -481,3 +481,11 @@ unsafe fn f107(a0: &mut Vec) -> Vec { unsafe fn f108(a0: &mut Vec) -> Vec { std::mem::take(&mut *a0) } + +unsafe fn f109(a0: Vec) -> Vec { + a0.clone() +} + +unsafe fn f110(a0: Vec) -> Vec { + a0.clone() +} From 392a53c6bbd041c8a5daa4639e6a68462ca2ef66 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 13:19:25 +0100 Subject: [PATCH 09/11] Materialize temporary when calling method --- cpp2rust/converter/converter.cpp | 5 +---- cpp2rust/converter/converter_lib.cpp | 19 +++++++++++++++++++ cpp2rust/converter/converter_lib.h | 4 ++++ .../converter/models/converter_refcount.cpp | 6 +----- 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 5136b28b3..40295d5d6 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -2669,11 +2669,8 @@ void Converter::ConvertGenericBinaryOperator(clang::BinaryOperator *expr) { } bool Converter::IsReferenceType(const clang::Expr *expr) const { - const auto *e = expr->IgnoreCasts(); + const auto *e = IgnoreStdMove(expr->IgnoreCasts())->IgnoreCasts(); if (const auto *call = clang::dyn_cast(e)) { - if (call->isCallToStdMove()) { - return IsReferenceType(call->getArg(0)); - } return !clang::isa(call) && GetReturnTypeOfFunction(call)->isReferenceType(); } diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 2e21efeac..9f5755133 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -1347,6 +1347,25 @@ bool IsBuiltinVaCopy(const clang::CallExpr *expr) { return false; } +const clang::Expr *IgnoreStdMove(const clang::Expr *expr) { + while (true) { + const auto *call = + clang::dyn_cast(expr->IgnoreParenImpCasts()); + if (!call || !call->isCallToStdMove()) { + return expr; + } + expr = call->getArg(0); + } +} + +bool IsTemporaryObject(const clang::Expr *expr) { + const auto *operand = IgnoreStdMove(expr); + if (operand != expr) { + return !operand->isGLValue(); + } + return !expr->isLValue(); +} + bool ContainsVAArgExpr(const clang::Stmt *stmt) { if (clang::isa(stmt)) { return true; diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index 1eae1ccfd..6d1a41ea6 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -243,6 +243,10 @@ bool IsBuiltinVaEnd(const clang::CallExpr *expr); bool IsBuiltinVaCopy(const clang::CallExpr *expr); +const clang::Expr *IgnoreStdMove(const clang::Expr *expr); + +bool IsTemporaryObject(const clang::Expr *expr); + bool ContainsVAArgExpr(const clang::Stmt *stmt); clang::Expr *NormalizeToBool(clang::Expr *expr, clang::ASTContext &ctx); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 1a02e5d98..26d72fd80 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -2658,11 +2658,7 @@ void ConverterRefCount::SetUFCSReceiver(clang::Expr *base, bool is_arrow, } return; } - auto *moved = clang::dyn_cast(base->IgnoreParenImpCasts()); - bool is_moved_object = - moved && moved->isCallToStdMove() && moved->getArg(0)->isGLValue(); - if (!base->isLValue() && !is_moved_object && - base->getType()->isRecordType() && + if (IsTemporaryObject(base) && base->getType()->isRecordType() && !IsReferenceType(base->IgnoreImplicit())) { PushConversionKind push(*this, ConversionKind::FullRefCount); ufcs_receiver_ = From e3c78cef0c96d4ccac7b8290e1216ccd90ea329b Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 13:21:52 +0100 Subject: [PATCH 10/11] Merge emit_push_open and emit_push_close --- cpp2rust/converter/converter.h | 4 ++-- .../converter/models/converter_refcount.cpp | 16 +++++++--------- cpp2rust/converter/models/converter_refcount.h | 4 ++-- cpp2rust/converter/plugins/emplace_back.cpp | 18 +++++++----------- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 894c12ce2..b430fcc5d 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -998,8 +998,8 @@ class Converter : public clang::RecursiveASTVisitor { virtual bool emplace_back_plugin_convert(clang::CallExpr *call); virtual void emplace_back_plugin_construct_arg(clang::QualType elem_type, clang::CXXConstructExpr *ctor); - virtual void emplace_back_emit_push_open(clang::CXXMemberCallExpr *call); - virtual void emplace_back_emit_push_close(clang::CXXMemberCallExpr *call); + virtual void emplace_back_emit_push(clang::CXXMemberCallExpr *call, + std::string_view arg); virtual const char *GetPointerDerefPrefix(clang::QualType pointee_type); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 26d72fd80..f98f1b132 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -2504,20 +2504,18 @@ void ConverterRefCount::emplace_back_plugin_construct_arg( ConvertVarInit(elem_type, ctor); } -void ConverterRefCount::emplace_back_emit_push_open( - clang::CXXMemberCallExpr *call) { +void ConverterRefCount::emplace_back_emit_push(clang::CXXMemberCallExpr *call, + std::string_view arg) { auto *obj = GetCallObject(call); auto obj_type = obj->getType().getNonReferenceType(); if (obj_type->isPointerType()) { obj_type = obj_type->getPointeeType(); } - StrCat(ConvertObject(obj), ".with_mut(|__v: &mut ", - ToString(obj_type.getNonReferenceType()), "| __v.push("); -} - -void ConverterRefCount::emplace_back_emit_push_close( - clang::CXXMemberCallExpr *call) { - StrCat("))"); + StrCat(ConvertObject(obj), ".with_mut"); + PushParen outer(*this); + StrCat("|__v: &mut ", ToString(obj_type.getNonReferenceType()), "| __v.push"); + PushParen inner(*this); + StrCat(arg); } const char * diff --git a/cpp2rust/converter/models/converter_refcount.h b/cpp2rust/converter/models/converter_refcount.h index 818e06c94..b724f7746 100644 --- a/cpp2rust/converter/models/converter_refcount.h +++ b/cpp2rust/converter/models/converter_refcount.h @@ -239,8 +239,8 @@ class ConverterRefCount final : public Converter { void emplace_back_plugin_construct_arg(clang::QualType elem_type, clang::CXXConstructExpr *ctor) override; - void emplace_back_emit_push_open(clang::CXXMemberCallExpr *call) override; - void emplace_back_emit_push_close(clang::CXXMemberCallExpr *call) override; + void emplace_back_emit_push(clang::CXXMemberCallExpr *call, + std::string_view arg) override; const char *GetPointerDerefSuffix(clang::QualType pointee_type); const char *GetPointerDerefPrefix(clang::QualType pointee_type) override; diff --git a/cpp2rust/converter/plugins/emplace_back.cpp b/cpp2rust/converter/plugins/emplace_back.cpp index de2cde3dd..237d7c4c1 100644 --- a/cpp2rust/converter/plugins/emplace_back.cpp +++ b/cpp2rust/converter/plugins/emplace_back.cpp @@ -134,18 +134,16 @@ clang::CXXConstructExpr *buildConstructExpr(clang::CXXMemberCallExpr *call, } // namespace -void Converter::emplace_back_emit_push_open(clang::CXXMemberCallExpr *call) { +void Converter::emplace_back_emit_push(clang::CXXMemberCallExpr *call, + std::string_view arg) { { PushExprKind push(*this, ExprKind::LValue); auto callee = ToString(call->getCallee()); ReplaceAll(callee, "emplace_back", "push"); StrCat(callee); } - StrCat('('); -} - -void Converter::emplace_back_emit_push_close(clang::CXXMemberCallExpr *call) { - StrCat(')'); + PushParen paren(*this); + StrCat(arg); } bool Converter::emplace_back_plugin_convert(clang::CallExpr *call) { @@ -189,11 +187,9 @@ bool Converter::emplace_back_plugin_convert(clang::CallExpr *call) { arg = std::move(buf).str(); } - StrCat("{ let __arg = ", arg, ";"); - emplace_back_emit_push_open(member_call); - StrCat("__arg"); - emplace_back_emit_push_close(member_call); - StrCat('}'); + PushBrace brace(*this); + StrCat("let __arg = ", arg, ";"); + emplace_back_emit_push(member_call, "__arg"); return true; } From 7d431075d4378792b7eba93af14fc78c8c2b9793 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Mon, 14 Sep 2026 13:50:44 +0100 Subject: [PATCH 11/11] Always convert calls to move constructor --- cpp2rust/converter/converter.cpp | 5 +- cpp2rust/converter/converter_lib.cpp | 31 +- .../converter/models/converter_refcount.cpp | 3 +- tests/unit/out/refcount/bst.rs | 15 + .../unit/out/refcount/copy_move_defaulted.rs | 81 ++++- tests/unit/out/refcount/fft.rs | 199 +++++++---- tests/unit/out/refcount/fn_ptr_stable_sort.rs | 22 ++ tests/unit/out/refcount/huffman.rs | 70 ++-- tests/unit/out/refcount/kruskal.rs | 318 +++++++++++------- .../out/refcount/operator_arithmetic_free.rs | 13 +- .../refcount/operator_arithmetic_member.rs | 13 +- tests/unit/out/refcount/operator_traits.rs | 49 +++ tests/unit/out/refcount/push_emplace_back.rs | 11 +- tests/unit/out/refcount/this.rs | 13 +- tests/unit/out/refcount/unique_ptr.rs | 54 ++- tests/unit/out/refcount/unique_ptr_nested.rs | 10 + tests/unit/out/refcount/unique_ptr_struct.rs | 10 + tests/unit/out/unsafe/bst.rs | 10 + tests/unit/out/unsafe/copy_move_defaulted.rs | 53 ++- tests/unit/out/unsafe/fft.rs | 93 +++-- tests/unit/out/unsafe/fn_ptr_stable_sort.rs | 14 + tests/unit/out/unsafe/huffman.rs | 58 +++- tests/unit/out/unsafe/kruskal.rs | 144 +++++--- .../out/unsafe/operator_arithmetic_free.rs | 10 +- .../out/unsafe/operator_arithmetic_member.rs | 8 +- tests/unit/out/unsafe/operator_traits.rs | 26 ++ tests/unit/out/unsafe/push_emplace_back.rs | 8 +- tests/unit/out/unsafe/this.rs | 10 +- tests/unit/out/unsafe/unique_ptr.rs | 30 +- tests/unit/out/unsafe/unique_ptr_nested.rs | 9 + tests/unit/out/unsafe/unique_ptr_struct.rs | 9 + 31 files changed, 1042 insertions(+), 357 deletions(-) diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 40295d5d6..aef2305c5 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -3424,9 +3424,8 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { // Take suppress before recursing into the child. bool suppress = PushSuppressIteratorClone::take(*this); Convert(expr->getArg(0)); - if ((ctor->isCopyConstructor() || - (ctor->isMoveConstructor() && IsUserDefinedDecl(ctor->getParent()))) && - !suppress && !TypeIsCopyable(expr->getType())) { + if (ctor->isCopyConstructor() && !suppress && + !TypeIsCopyable(expr->getType())) { StrCat(".clone()"); } return false; diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 9f5755133..4fd508e65 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -286,24 +286,9 @@ bool IsUserDefinedCopyConstructor(const clang::CXXConstructorDecl *ctor) { IsUserDefinedDecl(ctor); } -static bool HasUserProvidedCopyMember(const clang::CXXRecordDecl *decl) { - return std::any_of(decl->method_begin(), decl->method_end(), [](auto *m) { - auto *ctor = clang::dyn_cast(m); - return m->isUserProvided() && - (ctor ? ctor->isCopyConstructor() : m->isCopyAssignmentOperator()); - }); -} - static bool IsTranslatedMoveMember(const clang::CXXMethodDecl *method) { - if (method->isDeleted() || !IsUserDefinedDecl(method->getParent())) { - return false; - } - if (method->isUserProvided()) { - return true; - } - return method->isDefaulted() && method->hasBody() && - (!method->isTrivial() || - HasUserProvidedCopyMember(method->getParent())); + return !method->isDeleted() && IsUserDefinedDecl(method->getParent()) && + method->hasBody(); } bool IsUserDefinedMoveConstructor(const clang::CXXConstructorDecl *ctor) { @@ -1348,14 +1333,12 @@ bool IsBuiltinVaCopy(const clang::CallExpr *expr) { } const clang::Expr *IgnoreStdMove(const clang::Expr *expr) { - while (true) { - const auto *call = - clang::dyn_cast(expr->IgnoreParenImpCasts()); - if (!call || !call->isCallToStdMove()) { - return expr; - } - expr = call->getArg(0); + if (const auto *call = + clang::dyn_cast(expr->IgnoreParenImpCasts()); + call && call->isCallToStdMove()) { + return call->getArg(0); } + return expr; } bool IsTemporaryObject(const clang::Expr *expr) { diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index f98f1b132..ac1533405 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1892,8 +1892,7 @@ bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { return false; } - if (ctor->isCopyOrMoveConstructor() && - !IsUserDefinedCopyOrMoveConstructor(ctor)) { + if (ctor->isCopyConstructor() && !IsUserDefinedCopyConstructor(ctor)) { StrCat(PushSuppressIteratorClone::take(*this) ? ConvertRValue(expr->getArg(0)) : ConvertFreshRValue(expr->getArg(0))); diff --git a/tests/unit/out/refcount/bst.rs b/tests/unit/out/refcount/bst.rs index 97e18ef6d..3be80045e 100644 --- a/tests/unit/out/refcount/bst.rs +++ b/tests/unit/out/refcount/bst.rs @@ -12,6 +12,21 @@ pub struct node_t { pub right: Value>, pub value: Value, } +impl node_t { + pub fn node_t_pmutnode_t(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + left: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).left.borrow()).clone(), + )), + right: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).right.borrow()).clone(), + )), + value: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).value.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for node_t { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { diff --git a/tests/unit/out/refcount/copy_move_defaulted.rs b/tests/unit/out/refcount/copy_move_defaulted.rs index eb66537a9..16559bb44 100644 --- a/tests/unit/out/refcount/copy_move_defaulted.rs +++ b/tests/unit/out/refcount/copy_move_defaulted.rs @@ -10,6 +10,15 @@ use std::rc::{Rc, Weak}; pub struct Inner { pub x: Value, } +impl Inner { + pub fn Inner_pmutInner(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + x: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).x.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for Inner { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { @@ -51,6 +60,19 @@ impl Explicit { let this: Ptr = __this.as_pointer(); Rc::try_unwrap(__this).ok().unwrap().into_inner() } + pub fn Explicit_pmutExplicit(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + inner: Rc::new(RefCell::new(Inner::Inner_pmutInner({ + (*_a0.upgrade().deref()).inner.as_pointer() + }))), + arr: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).arr.borrow()).clone(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } } impl Clone for Explicit { fn clone(&self) -> Self { @@ -97,6 +119,21 @@ pub struct Implicit { pub inner: Value, pub arr: Value>, } +impl Implicit { + pub fn Implicit_pmutImplicit(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + inner: Rc::new(RefCell::new(Inner::Inner_pmutInner({ + (*_a0.upgrade().deref()).inner.as_pointer() + }))), + arr: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).arr.borrow()).clone(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for Implicit { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { @@ -315,7 +352,9 @@ fn main_0() -> i32 { let _dtor_b = ScopedDestructor::new(&b, |__p| __p.destructor()); let c: Value = Rc::new(RefCell::new((*a.borrow()).clone())); let _dtor_c = ScopedDestructor::new(&c, |__p| __p.destructor()); - let d: Value = Rc::new(RefCell::new((*a.borrow()).clone())); + let d: Value = Rc::new(RefCell::new(Explicit::Explicit_pmutExplicit({ + a.as_pointer() + }))); let _dtor_d = ScopedDestructor::new(&d, |__p| __p.destructor()); assert!( (({ same_0(b.as_pointer(), a.as_pointer(),) }) @@ -327,7 +366,7 @@ fn main_0() -> i32 { let f: Value = Rc::new(RefCell::new(Explicit::Explicit({ 3 }))); let _dtor_f = ScopedDestructor::new(&f, |__p| __p.destructor()); (*e.borrow_mut()) = (*b.borrow()).clone(); - (*f.borrow_mut()) = (*c.borrow()).clone(); + ({ ExplicitImpl::operator_assign_pmutExplicit(&f.as_pointer(), c.as_pointer()) }); assert!( ({ same_0(e.as_pointer(), b.as_pointer(),) }) && ({ same_0(f.as_pointer(), c.as_pointer(),) }) @@ -350,7 +389,9 @@ fn main_0() -> i32 { arr: Rc::new(RefCell::new(Box::new([5, 6]))), })); let j: Value = Rc::new(RefCell::new((*i.borrow()).clone())); - let k: Value = Rc::new(RefCell::new((*i.borrow()).clone())); + let k: Value = Rc::new(RefCell::new(Implicit::Implicit_pmutImplicit({ + i.as_pointer() + }))); assert!( (((*(*j.borrow()).v.borrow()) == 5) && ((*(*(*j.borrow()).inner.borrow()).x.borrow()) == 50)) @@ -551,11 +592,45 @@ impl DefaultCopyUserMoveImpl for Ptr { } } pub trait ExplicitImpl { + fn operator_assign_pmutExplicit(&self, _a0: Ptr) -> Ptr; fn destructor(&self); } impl ExplicitImpl for Ptr { + fn operator_assign_pmutExplicit(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + ({ + let _arg0: Ptr = (*_a0.upgrade().deref()).inner.as_pointer(); + InnerImpl::operator_assign_pmutInner( + &(*(*self).upgrade().deref()).inner.as_pointer(), + _arg0, + ) + }); + { + (((*(*self).upgrade().deref()).arr.as_pointer()) as Ptr) + .to_any() + .memcpy( + &(((*_a0.upgrade().deref()).arr.as_pointer()) as Ptr).to_any(), + 8_usize as usize, + ); + (((*(*self).upgrade().deref()).arr.as_pointer()) as Ptr) + .to_any() + .clone() + }; + return (*self).clone(); + } fn destructor(&self) {} } +pub trait InnerImpl { + fn operator_assign_pmutInner(&self, _a0: Ptr) -> Ptr; +} +impl InnerImpl for Ptr { + fn operator_assign_pmutInner(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).x.borrow()); + (*(*(*self).upgrade().deref()).x.borrow_mut()) = __rhs; + return (*self).clone(); + } +} pub trait UserCopyDefaultMoveImpl { fn operator_assign_pconstUserCopyDefaultMove( &self, diff --git a/tests/unit/out/refcount/fft.rs b/tests/unit/out/refcount/fft.rs index 40b783543..e6174ffbf 100644 --- a/tests/unit/out/refcount/fft.rs +++ b/tests/unit/out/refcount/fft.rs @@ -86,19 +86,28 @@ pub fn fft_3(a: Ptr>>>, N: i32) -> Option>(), ))))); if ((*N.borrow()) == 1) { - let __rhs = Complex { - re: Rc::new(RefCell::new( - (*(*a.upgrade().deref()).as_ref().unwrap().borrow()[(0_usize) as usize] - .re - .borrow()), - )), - img: Rc::new(RefCell::new( - (*(*a.upgrade().deref()).as_ref().unwrap().borrow()[(0_usize) as usize] - .img - .borrow()), - )), - }; - (*y.borrow()).as_ref().unwrap().borrow_mut()[(0_usize) as usize] = __rhs; + ({ + let _arg0: Value = Rc::new(RefCell::new(Complex { + re: Rc::new(RefCell::new( + (*(*a.upgrade().deref()).as_ref().unwrap().borrow()[(0_usize) as usize] + .re + .borrow()), + )), + img: Rc::new(RefCell::new( + (*(*a.upgrade().deref()).as_ref().unwrap().borrow()[(0_usize) as usize] + .img + .borrow()), + )), + })); + ComplexImpl::operator_assign_pmutComplex( + &(*y.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset((0_usize)), + _arg0.as_pointer(), + ) + }); return (*y.borrow_mut()).take(); } let w: Value>>> = @@ -113,10 +122,20 @@ pub fn fft_3(a: Ptr>>>, N: i32) -> Option = Rc::new(RefCell::new(Complex { + re: Rc::new(RefCell::new((*alpha.borrow()).cos())), + img: Rc::new(RefCell::new((*alpha.borrow()).sin())), + })); + ComplexImpl::operator_assign_pmutComplex( + &(*w.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*i.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); (*i.borrow_mut()).postfix_inc(); } let A0: Value>>> = @@ -133,36 +152,54 @@ pub fn fft_3(a: Ptr>>>, N: i32) -> Option = Rc::new(RefCell::new(0)); 'loop_: while ((*i.borrow()) < ((*N.borrow()) / 2)) { - let __rhs = Complex { - re: Rc::new(RefCell::new( - (*(*a.upgrade().deref()).as_ref().unwrap().borrow() - [(((*i.borrow()) * 2) as usize) as usize] - .re - .borrow()), - )), - img: Rc::new(RefCell::new( - (*(*a.upgrade().deref()).as_ref().unwrap().borrow() - [(((*i.borrow()) * 2) as usize) as usize] - .img - .borrow()), - )), - }; - (*A0.borrow()).as_ref().unwrap().borrow_mut()[((*i.borrow()) as usize) as usize] = __rhs; - let __rhs = Complex { - re: Rc::new(RefCell::new( - (*(*a.upgrade().deref()).as_ref().unwrap().borrow() - [((((*i.borrow()) * 2) + 1) as usize) as usize] - .re - .borrow()), - )), - img: Rc::new(RefCell::new( - (*(*a.upgrade().deref()).as_ref().unwrap().borrow() - [((((*i.borrow()) * 2) + 1) as usize) as usize] - .img - .borrow()), - )), - }; - (*A1.borrow()).as_ref().unwrap().borrow_mut()[((*i.borrow()) as usize) as usize] = __rhs; + ({ + let _arg0: Value = Rc::new(RefCell::new(Complex { + re: Rc::new(RefCell::new( + (*(*a.upgrade().deref()).as_ref().unwrap().borrow() + [(((*i.borrow()) * 2) as usize) as usize] + .re + .borrow()), + )), + img: Rc::new(RefCell::new( + (*(*a.upgrade().deref()).as_ref().unwrap().borrow() + [(((*i.borrow()) * 2) as usize) as usize] + .img + .borrow()), + )), + })); + ComplexImpl::operator_assign_pmutComplex( + &(*A0.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*i.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(Complex { + re: Rc::new(RefCell::new( + (*(*a.upgrade().deref()).as_ref().unwrap().borrow() + [((((*i.borrow()) * 2) + 1) as usize) as usize] + .re + .borrow()), + )), + img: Rc::new(RefCell::new( + (*(*a.upgrade().deref()).as_ref().unwrap().borrow() + [((((*i.borrow()) * 2) + 1) as usize) as usize] + .img + .borrow()), + )), + })); + ComplexImpl::operator_assign_pmutComplex( + &(*A1.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*i.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); (*i.borrow_mut()).postfix_inc(); } let y0: Value>>> = Rc::new(RefCell::new( @@ -190,10 +227,20 @@ pub fn fft_3(a: Ptr>>>, N: i32) -> Option = Rc::new(RefCell::new(Complex { + re: Rc::new(RefCell::new((*(*yk.borrow()).re.borrow()))), + img: Rc::new(RefCell::new((*(*yk.borrow()).img.borrow()))), + })); + ComplexImpl::operator_assign_pmutComplex( + &(*y.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*k.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); let yk_n2: Value = Rc::new(RefCell::new( ({ let _z1: Complex = ((*y0.borrow()).as_ref().unwrap().borrow() @@ -215,11 +262,20 @@ pub fn fft_3(a: Ptr>>>, N: i32) -> Option = Rc::new(RefCell::new(Complex { + re: Rc::new(RefCell::new((*(*yk_n2.borrow()).re.borrow()))), + img: Rc::new(RefCell::new((*(*yk_n2.borrow()).img.borrow()))), + })); + ComplexImpl::operator_assign_pmutComplex( + &(*y.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset((((*k.borrow()) + ((*N.borrow()) / 2)) as usize)), + _arg0.as_pointer(), + ) + }); (*k.borrow_mut()).postfix_inc(); } return (*y.borrow_mut()).take(); @@ -237,11 +293,20 @@ fn main_0() -> i32 { ))))); let i: Value = Rc::new(RefCell::new(0)); 'loop_: while ((*i.borrow()) < (*N.borrow())) { - let __rhs = Complex { - re: Rc::new(RefCell::new((((*i.borrow()) as f64) + 1_f64))), - img: Rc::new(RefCell::new(0_f64)), - }; - (*a.borrow()).as_ref().unwrap().borrow_mut()[((*i.borrow()) as usize) as usize] = __rhs; + ({ + let _arg0: Value = Rc::new(RefCell::new(Complex { + re: Rc::new(RefCell::new((((*i.borrow()) as f64) + 1_f64))), + img: Rc::new(RefCell::new(0_f64)), + })); + ComplexImpl::operator_assign_pmutComplex( + &(*a.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*i.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); (*i.borrow_mut()).postfix_inc(); } let b: Value>>> = @@ -284,3 +349,15 @@ fn main_0() -> i32 { ); return 0; } +pub trait ComplexImpl { + fn operator_assign_pmutComplex(&self, _a0: Ptr) -> Ptr; +} +impl ComplexImpl for Ptr { + fn operator_assign_pmutComplex(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).re.borrow()); + (*(*(*self).upgrade().deref()).re.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).img.borrow()); + (*(*(*self).upgrade().deref()).img.borrow_mut()) = __rhs; + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/fn_ptr_stable_sort.rs b/tests/unit/out/refcount/fn_ptr_stable_sort.rs index be45ffe6f..b85b9d3e9 100644 --- a/tests/unit/out/refcount/fn_ptr_stable_sort.rs +++ b/tests/unit/out/refcount/fn_ptr_stable_sort.rs @@ -11,6 +11,16 @@ pub struct Item { pub key: Value, pub value: Value, } +impl Item { + pub fn Item_pmutItem(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + key: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).key.borrow()))), + value: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).value.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for Item { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { @@ -92,3 +102,15 @@ fn main_0() -> i32 { ); return 0; } +pub trait ItemImpl { + fn operator_assign_pmutItem(&self, _a0: Ptr) -> Ptr; +} +impl ItemImpl for Ptr { + fn operator_assign_pmutItem(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).key.borrow()); + (*(*(*self).upgrade().deref()).key.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).value.borrow()); + (*(*(*self).upgrade().deref()).value.borrow_mut()) = __rhs; + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/huffman.rs b/tests/unit/out/refcount/huffman.rs index 9b46de39d..0fd6ab809 100644 --- a/tests/unit/out/refcount/huffman.rs +++ b/tests/unit/out/refcount/huffman.rs @@ -55,24 +55,28 @@ pub fn Swap_0(a: Ptr, b: Ptr) { (*(*a.upgrade().deref()).right.borrow()).clone(), )), })); - let __rhs = MinHeapNode { - data: Rc::new(RefCell::new((*(*b.upgrade().deref()).data.borrow()))), - freq: Rc::new(RefCell::new((*(*b.upgrade().deref()).freq.borrow()))), - left: Rc::new(RefCell::new( - (*(*b.upgrade().deref()).left.borrow()).clone(), - )), - right: Rc::new(RefCell::new( - (*(*b.upgrade().deref()).right.borrow()).clone(), - )), - }; - a.write(__rhs); - let __rhs = MinHeapNode { - data: Rc::new(RefCell::new((*(*t.borrow()).data.borrow()))), - freq: Rc::new(RefCell::new((*(*t.borrow()).freq.borrow()))), - left: Rc::new(RefCell::new((*(*t.borrow()).left.borrow()).clone())), - right: Rc::new(RefCell::new((*(*t.borrow()).right.borrow()).clone())), - }; - b.write(__rhs); + ({ + let _arg0: Value = Rc::new(RefCell::new(MinHeapNode { + data: Rc::new(RefCell::new((*(*b.upgrade().deref()).data.borrow()))), + freq: Rc::new(RefCell::new((*(*b.upgrade().deref()).freq.borrow()))), + left: Rc::new(RefCell::new( + (*(*b.upgrade().deref()).left.borrow()).clone(), + )), + right: Rc::new(RefCell::new( + (*(*b.upgrade().deref()).right.borrow()).clone(), + )), + })); + MinHeapNodeImpl::operator_assign_pmutMinHeapNode(&a, _arg0.as_pointer()) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(MinHeapNode { + data: Rc::new(RefCell::new((*(*t.borrow()).data.borrow()))), + freq: Rc::new(RefCell::new((*(*t.borrow()).freq.borrow()))), + left: Rc::new(RefCell::new((*(*t.borrow()).left.borrow()).clone())), + right: Rc::new(RefCell::new((*(*t.borrow()).right.borrow()).clone())), + })); + MinHeapNodeImpl::operator_assign_pmutMinHeapNode(&b, _arg0.as_pointer()) + }); } #[derive(Default)] pub struct MinHeap { @@ -357,16 +361,22 @@ impl MinHeapImpl for Ptr { fn Alloc(&self, data: u8, freq: i32) -> Ptr { let data: Value = Rc::new(RefCell::new(data)); let freq: Value = Rc::new(RefCell::new(freq)); - (*(*(*self).upgrade().deref()).alloc.borrow()) - .as_ref() - .unwrap() - .borrow_mut()[((*(*(*self).upgrade().deref()).next.borrow()) as usize) as usize] = - MinHeapNode { + ({ + let _arg0: Value = Rc::new(RefCell::new(MinHeapNode { data: Rc::new(RefCell::new((*data.borrow()))), freq: Rc::new(RefCell::new((*freq.borrow()))), left: Rc::new(RefCell::new(Ptr::::null())), right: Rc::new(RefCell::new(Ptr::::null())), - }; + })); + MinHeapNodeImpl::operator_assign_pmutMinHeapNode( + &(*(*(*self).upgrade().deref()).alloc.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*(*(*self).upgrade().deref()).next.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); return ((*(*(*self).upgrade().deref()).alloc.borrow()) .as_ref() .unwrap() @@ -526,10 +536,22 @@ impl MinHeapImpl for Ptr { } pub trait MinHeapNodeImpl { fn IsLeaf(&self) -> bool; + fn operator_assign_pmutMinHeapNode(&self, _a0: Ptr) -> Ptr; } impl MinHeapNodeImpl for Ptr { fn IsLeaf(&self) -> bool { return ((*(*(*self).upgrade().deref()).left.borrow()).is_null()) && ((*(*(*self).upgrade().deref()).right.borrow()).is_null()); } + fn operator_assign_pmutMinHeapNode(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).data.borrow()); + (*(*(*self).upgrade().deref()).data.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).freq.borrow()); + (*(*(*self).upgrade().deref()).freq.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).left.borrow()).clone(); + (*(*(*self).upgrade().deref()).left.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).right.borrow()).clone(); + (*(*(*self).upgrade().deref()).right.borrow_mut()) = __rhs; + return (*self).clone(); + } } diff --git a/tests/unit/out/refcount/kruskal.rs b/tests/unit/out/refcount/kruskal.rs index de5b50f36..727b312b1 100644 --- a/tests/unit/out/refcount/kruskal.rs +++ b/tests/unit/out/refcount/kruskal.rs @@ -84,34 +84,51 @@ pub fn partition_0(arr: Ptr>>>, start: i32, end: i32) - .borrow()), )), })); - let __rhs = Edge { - u: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*start.borrow()) as usize) as usize] - .u - .borrow()), - )), - v: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*start.borrow()) as usize) as usize] - .v - .borrow()), - )), - weight: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*start.borrow()) as usize) as usize] - .weight - .borrow()), - )), - }; - (*arr.upgrade().deref()).as_ref().unwrap().borrow_mut()[((*pidx.borrow()) as usize) as usize] = - __rhs; - (*arr.upgrade().deref()).as_ref().unwrap().borrow_mut() - [((*start.borrow()) as usize) as usize] = Edge { - u: Rc::new(RefCell::new((*(*tmp.borrow()).u.borrow()))), - v: Rc::new(RefCell::new((*(*tmp.borrow()).v.borrow()))), - weight: Rc::new(RefCell::new((*(*tmp.borrow()).weight.borrow()))), - }; + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*start.borrow()) as usize) as usize] + .u + .borrow()), + )), + v: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*start.borrow()) as usize) as usize] + .v + .borrow()), + )), + weight: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*start.borrow()) as usize) as usize] + .weight + .borrow()), + )), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*arr.upgrade().deref()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*pidx.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new((*(*tmp.borrow()).u.borrow()))), + v: Rc::new(RefCell::new((*(*tmp.borrow()).v.borrow()))), + weight: Rc::new(RefCell::new((*(*tmp.borrow()).weight.borrow()))), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*arr.upgrade().deref()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*start.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); let i: Value = Rc::new(RefCell::new((*start.borrow()))); let j: Value = Rc::new(RefCell::new((*end.borrow()))); 'loop_: while ((*i.borrow()) < (*pidx.borrow())) && ((*j.borrow()) > (*pidx.borrow())) { @@ -134,54 +151,74 @@ pub fn partition_0(arr: Ptr>>>, start: i32, end: i32) - (*j.borrow_mut()).prefix_dec(); } if ((*i.borrow()) < (*pidx.borrow())) && ((*j.borrow()) > (*pidx.borrow())) { - (*tmp.borrow_mut()) = Edge { - u: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*i.borrow()) as usize) as usize] - .u - .borrow()), - )), - v: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*i.borrow()) as usize) as usize] - .v - .borrow()), - )), - weight: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*i.borrow()) as usize) as usize] - .weight - .borrow()), - )), - }; - let __rhs = Edge { - u: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*j.borrow()) as usize) as usize] - .u - .borrow()), - )), - v: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*j.borrow()) as usize) as usize] - .v - .borrow()), - )), - weight: Rc::new(RefCell::new( - (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() - [((*j.borrow()) as usize) as usize] - .weight - .borrow()), - )), - }; - (*arr.upgrade().deref()).as_ref().unwrap().borrow_mut() - [((*i.borrow()) as usize) as usize] = __rhs; - (*arr.upgrade().deref()).as_ref().unwrap().borrow_mut() - [((*j.borrow()) as usize) as usize] = Edge { - u: Rc::new(RefCell::new((*(*tmp.borrow()).u.borrow()))), - v: Rc::new(RefCell::new((*(*tmp.borrow()).v.borrow()))), - weight: Rc::new(RefCell::new((*(*tmp.borrow()).weight.borrow()))), - }; + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*i.borrow()) as usize) as usize] + .u + .borrow()), + )), + v: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*i.borrow()) as usize) as usize] + .v + .borrow()), + )), + weight: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*i.borrow()) as usize) as usize] + .weight + .borrow()), + )), + })); + EdgeImpl::operator_assign_pmutEdge(&tmp.as_pointer(), _arg0.as_pointer()) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*j.borrow()) as usize) as usize] + .u + .borrow()), + )), + v: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*j.borrow()) as usize) as usize] + .v + .borrow()), + )), + weight: Rc::new(RefCell::new( + (*(*arr.upgrade().deref()).as_ref().unwrap().borrow() + [((*j.borrow()) as usize) as usize] + .weight + .borrow()), + )), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*arr.upgrade().deref()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*i.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new((*(*tmp.borrow()).u.borrow()))), + v: Rc::new(RefCell::new((*(*tmp.borrow()).v.borrow()))), + weight: Rc::new(RefCell::new((*(*tmp.borrow()).weight.borrow()))), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*arr.upgrade().deref()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*j.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); (*i.borrow_mut()).postfix_inc(); (*j.borrow_mut()).postfix_dec(); } @@ -342,46 +379,81 @@ fn main_0() -> i32 { V: Rc::new(RefCell::new((*V.borrow()))), E: Rc::new(RefCell::new((*E.borrow()))), })); - (*(*graph.borrow()).edges.borrow()) - .as_ref() - .unwrap() - .borrow_mut()[(0_usize) as usize] = Edge { - u: Rc::new(RefCell::new(0)), - v: Rc::new(RefCell::new(1)), - weight: Rc::new(RefCell::new(10_f64)), - }; - (*(*graph.borrow()).edges.borrow()) - .as_ref() - .unwrap() - .borrow_mut()[(1_usize) as usize] = Edge { - u: Rc::new(RefCell::new(1)), - v: Rc::new(RefCell::new(3)), - weight: Rc::new(RefCell::new(15_f64)), - }; - (*(*graph.borrow()).edges.borrow()) - .as_ref() - .unwrap() - .borrow_mut()[(2_usize) as usize] = Edge { - u: Rc::new(RefCell::new(2)), - v: Rc::new(RefCell::new(3)), - weight: Rc::new(RefCell::new(4_f64)), - }; - (*(*graph.borrow()).edges.borrow()) - .as_ref() - .unwrap() - .borrow_mut()[(3_usize) as usize] = Edge { - u: Rc::new(RefCell::new(2)), - v: Rc::new(RefCell::new(0)), - weight: Rc::new(RefCell::new(6_f64)), - }; - (*(*graph.borrow()).edges.borrow()) - .as_ref() - .unwrap() - .borrow_mut()[(4_usize) as usize] = Edge { - u: Rc::new(RefCell::new(0)), - v: Rc::new(RefCell::new(3)), - weight: Rc::new(RefCell::new(5_f64)), - }; + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new(0)), + v: Rc::new(RefCell::new(1)), + weight: Rc::new(RefCell::new(10_f64)), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*(*graph.borrow()).edges.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset((0_usize)), + _arg0.as_pointer(), + ) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new(1)), + v: Rc::new(RefCell::new(3)), + weight: Rc::new(RefCell::new(15_f64)), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*(*graph.borrow()).edges.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset((1_usize)), + _arg0.as_pointer(), + ) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new(2)), + v: Rc::new(RefCell::new(3)), + weight: Rc::new(RefCell::new(4_f64)), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*(*graph.borrow()).edges.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset((2_usize)), + _arg0.as_pointer(), + ) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new(2)), + v: Rc::new(RefCell::new(0)), + weight: Rc::new(RefCell::new(6_f64)), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*(*graph.borrow()).edges.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset((3_usize)), + _arg0.as_pointer(), + ) + }); + ({ + let _arg0: Value = Rc::new(RefCell::new(Edge { + u: Rc::new(RefCell::new(0)), + v: Rc::new(RefCell::new(3)), + weight: Rc::new(RefCell::new(5_f64)), + })); + EdgeImpl::operator_assign_pmutEdge( + &(*(*graph.borrow()).edges.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset((4_usize)), + _arg0.as_pointer(), + ) + }); let total_weight: Value = Rc::new(RefCell::new(({ MSTKruskal_2(graph.as_pointer()) }))); assert!(((*total_weight.borrow()) == 19_f64)); return 0; @@ -487,3 +559,17 @@ impl DisjointSetImpl for Ptr { } } } +pub trait EdgeImpl { + fn operator_assign_pmutEdge(&self, _a0: Ptr) -> Ptr; +} +impl EdgeImpl for Ptr { + fn operator_assign_pmutEdge(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).u.borrow()); + (*(*(*self).upgrade().deref()).u.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).weight.borrow()); + (*(*(*self).upgrade().deref()).weight.borrow_mut()) = __rhs; + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/operator_arithmetic_free.rs b/tests/unit/out/refcount/operator_arithmetic_free.rs index ebbf39a7a..c9c56d04b 100644 --- a/tests/unit/out/refcount/operator_arithmetic_free.rs +++ b/tests/unit/out/refcount/operator_arithmetic_free.rs @@ -10,6 +10,15 @@ use std::rc::{Rc, Weak}; pub struct S { pub v: Value, } +impl S { + pub fn S_pmutS(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for S { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { @@ -90,7 +99,7 @@ pub fn operator_post_inc_8(a: Ptr, _a1: i32) -> S { let _a1: Value = Rc::new(RefCell::new(_a1)); let old: Value = Rc::new(RefCell::new((*a.upgrade().deref()).clone())); (*(*a.upgrade().deref()).v.borrow_mut()).prefix_inc(); - return (*old.borrow()).clone(); + return S::S_pmutS({ (old.as_pointer()).clone() }); } pub fn operator_dec_9(a: Ptr) -> Ptr { (*(*a.upgrade().deref()).v.borrow_mut()).prefix_dec(); @@ -100,7 +109,7 @@ pub fn operator_post_dec_10(a: Ptr, _a1: i32) -> S { let _a1: Value = Rc::new(RefCell::new(_a1)); let old: Value = Rc::new(RefCell::new((*a.upgrade().deref()).clone())); (*(*a.upgrade().deref()).v.borrow_mut()).prefix_dec(); - return (*old.borrow()).clone(); + return S::S_pmutS({ (old.as_pointer()).clone() }); } pub fn operator_add_11(a: Ptr, b: i32) -> S { let b: Value = Rc::new(RefCell::new(b)); diff --git a/tests/unit/out/refcount/operator_arithmetic_member.rs b/tests/unit/out/refcount/operator_arithmetic_member.rs index b1065522d..afd156339 100644 --- a/tests/unit/out/refcount/operator_arithmetic_member.rs +++ b/tests/unit/out/refcount/operator_arithmetic_member.rs @@ -10,6 +10,15 @@ use std::rc::{Rc, Weak}; pub struct S { pub v: Value, } +impl S { + pub fn S_pmutS(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for S { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { @@ -186,7 +195,7 @@ impl SImpl for Ptr { let _a0: Value = Rc::new(RefCell::new(_a0)); let old: Value = Rc::new(RefCell::new((*(*self).upgrade().deref()).clone())); (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_inc(); - return (*old.borrow()).clone(); + return S::S_pmutS({ (old.as_pointer()).clone() }); } fn operator_dec(&self) -> Ptr { (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_dec(); @@ -196,6 +205,6 @@ impl SImpl for Ptr { let _a0: Value = Rc::new(RefCell::new(_a0)); let old: Value = Rc::new(RefCell::new((*(*self).upgrade().deref()).clone())); (*(*(*self).upgrade().deref()).v.borrow_mut()).prefix_dec(); - return (*old.borrow()).clone(); + return S::S_pmutS({ (old.as_pointer()).clone() }); } } diff --git a/tests/unit/out/refcount/operator_traits.rs b/tests/unit/out/refcount/operator_traits.rs index 4ac3a136e..84de7546b 100644 --- a/tests/unit/out/refcount/operator_traits.rs +++ b/tests/unit/out/refcount/operator_traits.rs @@ -10,6 +10,15 @@ use std::rc::{Rc, Weak}; pub struct Lt { pub v: Value, } +impl Lt { + pub fn Lt_pmutLt(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl std::cmp::Ord for Lt { fn cmp(&self, other: &Self) -> std::cmp::Ordering { { @@ -111,6 +120,15 @@ impl ByteRepr for Eq { pub struct Cmp { pub v: Value, } +impl Cmp { + pub fn Cmp_pmutCmp(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl std::cmp::Ord for Cmp { fn cmp(&self, other: &Self) -> std::cmp::Ordering { { @@ -163,6 +181,15 @@ impl ByteRepr for Cmp { pub struct Free { pub v: Value, } +impl Free { + pub fn Free_pmutFree(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl std::cmp::Ord for Free { fn cmp(&self, other: &Self) -> std::cmp::Ordering { { @@ -492,6 +519,7 @@ fn main_0() -> i32 { pub trait CmpImpl { fn operator_cmp(&self, o: Ptr) -> std::cmp::Ordering; fn operator_eq(&self, o: Ptr) -> bool; + fn operator_assign_pmutCmp(&self, _a0: Ptr) -> Ptr; } impl CmpImpl for Ptr { fn operator_cmp(&self, o: Ptr) -> std::cmp::Ordering { @@ -504,6 +532,11 @@ impl CmpImpl for Ptr { _lhs == (*(*o.upgrade().deref()).v.borrow()) }; } + fn operator_assign_pmutCmp(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + return (*self).clone(); + } } pub trait EqImpl { fn operator_eq(&self, o: Ptr) -> bool; @@ -516,8 +549,19 @@ impl EqImpl for Ptr { }; } } +pub trait FreeImpl { + fn operator_assign_pmutFree(&self, _a0: Ptr) -> Ptr; +} +impl FreeImpl for Ptr { + fn operator_assign_pmutFree(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + return (*self).clone(); + } +} pub trait LtImpl { fn operator_lt(&self, o: Ptr) -> bool; + fn operator_assign_pmutLt(&self, _a0: Ptr) -> Ptr; } impl LtImpl for Ptr { fn operator_lt(&self, o: Ptr) -> bool { @@ -526,4 +570,9 @@ impl LtImpl for Ptr { _lhs < (*(*o.upgrade().deref()).v.borrow()) }; } + fn operator_assign_pmutLt(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + return (*self).clone(); + } } diff --git a/tests/unit/out/refcount/push_emplace_back.rs b/tests/unit/out/refcount/push_emplace_back.rs index 581d32446..232f74262 100644 --- a/tests/unit/out/refcount/push_emplace_back.rs +++ b/tests/unit/out/refcount/push_emplace_back.rs @@ -10,6 +10,15 @@ use std::rc::{Rc, Weak}; pub struct Chunk { pub data: Value, } +impl Chunk { + pub fn Chunk_pmutChunk(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + data: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).data.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for Chunk { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { @@ -181,7 +190,7 @@ pub fn nested_emplace_move_5(bw: Ptr) { let bw: Value> = Rc::new(RefCell::new(bw)); { let __arg = - std::mem::take(&mut (*(*(*bw.borrow()).upgrade().deref()).chunk.borrow()).clone()); + Chunk::Chunk_pmutChunk({ (*(*bw.borrow()).upgrade().deref()).chunk.as_pointer() }); (*(*(*bw.borrow()).upgrade().deref()).output.borrow()) .to_strong() .as_pointer() diff --git a/tests/unit/out/refcount/this.rs b/tests/unit/out/refcount/this.rs index a697f4c59..a0e8b7940 100644 --- a/tests/unit/out/refcount/this.rs +++ b/tests/unit/out/refcount/this.rs @@ -219,6 +219,7 @@ pub trait SImpl { fn reset(&self); fn copy_if_different_const(&self, other: Ptr) -> bool; fn copy_if_different(&self, other: Ptr) -> bool; + fn operator_assign_pmutS(&self, _a0: Ptr) -> Ptr; } impl SImpl for Ptr { fn returns_this_reference(&self) -> Ptr { @@ -258,7 +259,10 @@ impl SImpl for Ptr { (*self).delete(); } fn reset(&self) { - (*self).write(S::S1({ 0 })); + ({ + let _arg0: Value = Rc::new(RefCell::new(S::S1({ 0 }))); + SImpl::operator_assign_pmutS(&(*self), _arg0.as_pointer()) + }); } fn copy_if_different_const(&self, other: Ptr) -> bool { let other: Value> = Rc::new(RefCell::new(other)); @@ -282,4 +286,11 @@ impl SImpl for Ptr { (*(*(*self).upgrade().deref()).self__.borrow_mut()) = __rhs; return true; } + fn operator_assign_pmutS(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).a_.borrow()); + (*(*(*self).upgrade().deref()).a_.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).self__.borrow()).clone(); + (*(*(*self).upgrade().deref()).self__.borrow_mut()) = __rhs; + return (*self).clone(); + } } diff --git a/tests/unit/out/refcount/unique_ptr.rs b/tests/unit/out/refcount/unique_ptr.rs index 91ab24ae6..29cca8026 100644 --- a/tests/unit/out/refcount/unique_ptr.rs +++ b/tests/unit/out/refcount/unique_ptr.rs @@ -39,6 +39,16 @@ pub struct Pair { pub x: Value, pub y: Value, } +impl Pair { + pub fn Pair_pmutPair(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + x: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).x.borrow()))), + y: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).y.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for Pair { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { @@ -164,10 +174,20 @@ pub fn RndStuff_2() { ))))); let i: Value = Rc::new(RefCell::new(0)); 'loop_: while ((*i.borrow()) < 10) { - (*x3.borrow()).as_ref().unwrap().borrow_mut()[((*i.borrow()) as usize) as usize] = Pair { - x: Rc::new(RefCell::new(1)), - y: Rc::new(RefCell::new(2)), - }; + ({ + let _arg0: Value = Rc::new(RefCell::new(Pair { + x: Rc::new(RefCell::new(1)), + y: Rc::new(RefCell::new(2)), + })); + PairImpl::operator_assign_pmutPair( + &(*x3.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*i.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); (*i.borrow_mut()).prefix_inc(); } let p3_0: Value> = Rc::new(RefCell::new((*x3.borrow()).as_pointer())); @@ -229,10 +249,20 @@ pub fn RndStuff_2() { .to_owned_opt(); let i: Value = Rc::new(RefCell::new(0)); 'loop_: while ((*i.borrow()) < 50) { - (*x3.borrow()).as_ref().unwrap().borrow_mut()[((*i.borrow()) as usize) as usize] = Pair { - x: Rc::new(RefCell::new(-1_i32)), - y: Rc::new(RefCell::new(-2_i32)), - }; + ({ + let _arg0: Value = Rc::new(RefCell::new(Pair { + x: Rc::new(RefCell::new(-1_i32)), + y: Rc::new(RefCell::new(-2_i32)), + })); + PairImpl::operator_assign_pmutPair( + &(*x3.borrow()) + .as_ref() + .unwrap() + .as_pointer() + .offset(((*i.borrow()) as usize)), + _arg0.as_pointer(), + ) + }); (*i.borrow_mut()).prefix_inc(); } let p3_1: Value> = Rc::new(RefCell::new((*x3.borrow()).as_pointer())); @@ -306,8 +336,16 @@ fn main_0() -> i32 { } pub trait PairImpl { fn inc(&self, k: i32); + fn operator_assign_pmutPair(&self, _a0: Ptr) -> Ptr; } impl PairImpl for Ptr { + fn operator_assign_pmutPair(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).x.borrow()); + (*(*(*self).upgrade().deref()).x.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).y.borrow()); + (*(*(*self).upgrade().deref()).y.borrow_mut()) = __rhs; + return (*self).clone(); + } fn inc(&self, k: i32) { let k: Value = Rc::new(RefCell::new(k)); (*(*(*self).upgrade().deref()).x.borrow_mut()) += (*k.borrow()); diff --git a/tests/unit/out/refcount/unique_ptr_nested.rs b/tests/unit/out/refcount/unique_ptr_nested.rs index 31a78b45a..439293f0c 100644 --- a/tests/unit/out/refcount/unique_ptr_nested.rs +++ b/tests/unit/out/refcount/unique_ptr_nested.rs @@ -11,6 +11,16 @@ pub struct Inner { pub x: Value, pub y: Value, } +impl Inner { + pub fn Inner_pmutInner(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + x: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).x.borrow()))), + y: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).y.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for Inner { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { diff --git a/tests/unit/out/refcount/unique_ptr_struct.rs b/tests/unit/out/refcount/unique_ptr_struct.rs index 46bdd37ac..0db8e9b25 100644 --- a/tests/unit/out/refcount/unique_ptr_struct.rs +++ b/tests/unit/out/refcount/unique_ptr_struct.rs @@ -11,6 +11,16 @@ pub struct Point { pub x: Value, pub y: Value, } +impl Point { + pub fn Point_pmutPoint(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + x: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).x.borrow()))), + y: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).y.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl Clone for Point { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { diff --git a/tests/unit/out/unsafe/bst.rs b/tests/unit/out/unsafe/bst.rs index 1d5ffd9f1..dbcc05d87 100644 --- a/tests/unit/out/unsafe/bst.rs +++ b/tests/unit/out/unsafe/bst.rs @@ -13,6 +13,16 @@ pub struct node_t { pub right: *mut node_t, pub value: i32, } +impl node_t { + pub unsafe fn node_t_pmutnode_t(_a0: *mut node_t) -> Self { + let mut this = Self { + left: (*_a0).left, + right: (*_a0).right, + value: (*_a0).value, + }; + this + } +} pub unsafe fn find_0(mut node: *mut node_t, mut value: i32) -> *mut node_t { if ((value) < ((*node).value)) && (!(((*node).left).is_null())) { return (unsafe { find_0((*node).left, value) }); diff --git a/tests/unit/out/unsafe/copy_move_defaulted.rs b/tests/unit/out/unsafe/copy_move_defaulted.rs index 8f4db2a3f..191f9bdeb 100644 --- a/tests/unit/out/unsafe/copy_move_defaulted.rs +++ b/tests/unit/out/unsafe/copy_move_defaulted.rs @@ -11,6 +11,16 @@ use std::rc::Rc; pub struct Inner { pub x: i32, } +impl Inner { + pub unsafe fn Inner_pmutInner(_a0: *mut Inner) -> Self { + let mut this = Self { x: (*_a0).x }; + this + } + pub unsafe fn operator_assign_pmutInner(&mut self, _a0: *mut Inner) -> *mut Inner { + self.x = (*_a0).x; + return &mut (*(self as *mut Inner)) as *mut Inner; + } +} #[repr(C)] #[derive(Clone)] pub struct Explicit { @@ -27,6 +37,33 @@ impl Explicit { }; this } + pub unsafe fn Explicit_pmutExplicit(_a0: *mut Explicit) -> Self { + let mut this = Self { + v: (*_a0).v, + inner: Inner::Inner_pmutInner({ &mut (*_a0).inner as *mut Inner }), + arr: (*_a0).arr, + }; + this + } + pub unsafe fn operator_assign_pmutExplicit(&mut self, _a0: *mut Explicit) -> *mut Explicit { + self.v = (*_a0).v; + (unsafe { + let _arg0: *mut Inner = &mut (*_a0).inner as *mut Inner; + Inner::operator_assign_pmutInner(&mut self.inner, _arg0) + }); + { + if 8_usize != 0 { + ::std::ptr::copy_nonoverlapping( + ((&mut (*_a0).arr as *mut [i32; 2]) as *const [i32; 2] + as *const ::libc::c_void), + ((&mut self.arr as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void), + 8_usize as usize, + ) + } + ((&mut self.arr as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void) + }; + return &mut (*(self as *mut Explicit)) as *mut Explicit; + } pub unsafe fn destructor(&mut self) {} } impl Default for Explicit { @@ -45,6 +82,16 @@ pub struct Implicit { pub inner: Inner, pub arr: [i32; 2], } +impl Implicit { + pub unsafe fn Implicit_pmutImplicit(_a0: *mut Implicit) -> Self { + let mut this = Self { + v: (*_a0).v, + inner: Inner::Inner_pmutInner({ &mut (*_a0).inner as *mut Inner }), + arr: (*_a0).arr, + }; + this + } +} impl Default for Implicit { fn default() -> Self { Implicit { @@ -193,7 +240,7 @@ unsafe fn main_0() -> i32 { let _dtor_b = ScopedDestructorUnsafe::new(&raw mut b, Explicit::destructor); let mut c: Explicit = a.clone(); let _dtor_c = ScopedDestructorUnsafe::new(&raw mut c, Explicit::destructor); - let mut d: Explicit = a.clone(); + let mut d: Explicit = Explicit::Explicit_pmutExplicit({ &mut a as *mut Explicit }); let _dtor_d = ScopedDestructorUnsafe::new(&raw mut d, Explicit::destructor); assert!( ((unsafe { same_0(&b as *const Explicit, &a as *const Explicit,) }) @@ -205,7 +252,7 @@ unsafe fn main_0() -> i32 { let mut f: Explicit = Explicit::Explicit({ 3 }); let _dtor_f = ScopedDestructorUnsafe::new(&raw mut f, Explicit::destructor); e = (b).clone(); - f = (c).clone(); + (unsafe { Explicit::operator_assign_pmutExplicit(&mut f, &mut c as *mut Explicit) }); assert!( (unsafe { same_0(&e as *const Explicit, &b as *const Explicit,) }) && (unsafe { same_0(&f as *const Explicit, &c as *const Explicit,) }) @@ -227,7 +274,7 @@ unsafe fn main_0() -> i32 { arr: [5, 6], }; let mut j: Implicit = i; - let mut k: Implicit = i; + let mut k: Implicit = Implicit::Implicit_pmutImplicit({ &mut i as *mut Implicit }); assert!((((j.v) == (5)) && ((j.inner.x) == (50))) && ((j.arr[(1) as usize]) == (6))); assert!(((i.v) == (5)) && ((k.v) == (5))); let mut l: Implicit = Implicit { diff --git a/tests/unit/out/unsafe/fft.rs b/tests/unit/out/unsafe/fft.rs index 19ed836f2..d513a47e3 100644 --- a/tests/unit/out/unsafe/fft.rs +++ b/tests/unit/out/unsafe/fft.rs @@ -12,6 +12,13 @@ pub struct Complex { pub re: f64, pub img: f64, } +impl Complex { + pub unsafe fn operator_assign_pmutComplex(&mut self, _a0: *mut Complex) -> *mut Complex { + self.re = (*_a0).re; + self.img = (*_a0).img; + return &mut (*(self as *mut Complex)) as *mut Complex; + } +} pub unsafe fn Product_0(mut z1: Complex, mut z2: Complex) -> Complex { let mut ac: f64 = ((z1.re) * (z2.re)); let mut bd: f64 = ((z1.img) * (z2.img)); @@ -40,10 +47,13 @@ pub unsafe fn fft_3(a: *mut Option>, mut N: i32) -> Option>(), ); if ((N) == (1)) { - y.as_mut().unwrap()[(0_usize)] = Complex { - re: (*a).as_mut().unwrap()[(0_usize)].re, - img: (*a).as_mut().unwrap()[(0_usize)].img, - }; + (unsafe { + let mut _arg0: Complex = Complex { + re: (*a).as_mut().unwrap()[(0_usize)].re, + img: (*a).as_mut().unwrap()[(0_usize)].img, + }; + Complex::operator_assign_pmutComplex(&mut y.as_mut().unwrap()[(0_usize)], &mut _arg0) + }); return y.take(); } let mut w: Option> = Some( @@ -54,10 +64,13 @@ pub unsafe fn fft_3(a: *mut Option>, mut N: i32) -> Option> = Some( @@ -72,14 +85,26 @@ pub unsafe fn fft_3(a: *mut Option>, mut N: i32) -> Option> = @@ -97,10 +122,13 @@ pub unsafe fn fft_3(a: *mut Option>, mut N: i32) -> Option>, mut N: i32) -> Option i32 { ); let mut i: i32 = 0; 'loop_: while ((i) < (N)) { - a.as_mut().unwrap()[(i as usize)] = Complex { - re: ((i as f64) + (1_f64)), - img: 0_f64, - }; + (unsafe { + let mut _arg0: Complex = Complex { + re: ((i as f64) + (1_f64)), + img: 0_f64, + }; + Complex::operator_assign_pmutComplex(&mut a.as_mut().unwrap()[(i as usize)], &mut _arg0) + }); i.postfix_inc(); } let mut b: Option> = diff --git a/tests/unit/out/unsafe/fn_ptr_stable_sort.rs b/tests/unit/out/unsafe/fn_ptr_stable_sort.rs index a0fd886ad..0e5fd7a95 100644 --- a/tests/unit/out/unsafe/fn_ptr_stable_sort.rs +++ b/tests/unit/out/unsafe/fn_ptr_stable_sort.rs @@ -12,6 +12,20 @@ pub struct Item { pub key: i32, pub value: i32, } +impl Item { + pub unsafe fn Item_pmutItem(_a0: *mut Item) -> Self { + let mut this = Self { + key: (*_a0).key, + value: (*_a0).value, + }; + this + } + pub unsafe fn operator_assign_pmutItem(&mut self, _a0: *mut Item) -> *mut Item { + self.key = (*_a0).key; + self.value = (*_a0).value; + return &mut (*(self as *mut Item)) as *mut Item; + } +} pub unsafe fn Compare_0(a: *const Item, b: *const Item) -> bool { return (((*a).key) < ((*b).key)); } diff --git a/tests/unit/out/unsafe/huffman.rs b/tests/unit/out/unsafe/huffman.rs index a34c73a7f..aaf95ac8b 100644 --- a/tests/unit/out/unsafe/huffman.rs +++ b/tests/unit/out/unsafe/huffman.rs @@ -18,6 +18,16 @@ impl MinHeapNode { pub unsafe fn IsLeaf(&self) -> bool { return ((self.left).is_null()) && ((self.right).is_null()); } + pub unsafe fn operator_assign_pmutMinHeapNode( + &mut self, + _a0: *mut MinHeapNode, + ) -> *mut MinHeapNode { + self.data = (*_a0).data; + self.freq = (*_a0).freq; + self.left = (*_a0).left; + self.right = (*_a0).right; + return &mut (*(self as *mut MinHeapNode)) as *mut MinHeapNode; + } } pub unsafe fn Swap_0(a: *mut MinHeapNode, b: *mut MinHeapNode) { let mut t: MinHeapNode = MinHeapNode { @@ -26,18 +36,24 @@ pub unsafe fn Swap_0(a: *mut MinHeapNode, b: *mut MinHeapNode) { left: (*a).left, right: (*a).right, }; - (*a) = MinHeapNode { - data: (*b).data, - freq: (*b).freq, - left: (*b).left, - right: (*b).right, - }; - (*b) = MinHeapNode { - data: t.data, - freq: t.freq, - left: t.left, - right: t.right, - }; + (unsafe { + let mut _arg0: MinHeapNode = MinHeapNode { + data: (*b).data, + freq: (*b).freq, + left: (*b).left, + right: (*b).right, + }; + MinHeapNode::operator_assign_pmutMinHeapNode(&mut (*a), &mut _arg0) + }); + (unsafe { + let mut _arg0: MinHeapNode = MinHeapNode { + data: t.data, + freq: t.freq, + left: t.left, + right: t.right, + }; + MinHeapNode::operator_assign_pmutMinHeapNode(&mut (*b), &mut _arg0) + }); } #[repr(C)] #[derive(Default)] @@ -50,12 +66,18 @@ pub struct MinHeap { } impl MinHeap { pub unsafe fn Alloc(&mut self, mut data: libc::c_char, mut freq: i32) -> *mut MinHeapNode { - self.alloc.as_mut().unwrap()[(self.next as usize)] = MinHeapNode { - data: data, - freq: freq, - left: std::ptr::null_mut(), - right: std::ptr::null_mut(), - }; + (unsafe { + let mut _arg0: MinHeapNode = MinHeapNode { + data: data, + freq: freq, + left: std::ptr::null_mut(), + right: std::ptr::null_mut(), + }; + MinHeapNode::operator_assign_pmutMinHeapNode( + &mut self.alloc.as_mut().unwrap()[(self.next as usize)], + &mut _arg0, + ) + }); return (&mut self.alloc.as_mut().unwrap()[(self.next.postfix_inc() as usize)] as *mut MinHeapNode); } diff --git a/tests/unit/out/unsafe/kruskal.rs b/tests/unit/out/unsafe/kruskal.rs index cb3645305..e1a7d44fa 100644 --- a/tests/unit/out/unsafe/kruskal.rs +++ b/tests/unit/out/unsafe/kruskal.rs @@ -13,6 +13,14 @@ pub struct Edge { pub v: i32, pub weight: f64, } +impl Edge { + pub unsafe fn operator_assign_pmutEdge(&mut self, _a0: *mut Edge) -> *mut Edge { + self.u = (*_a0).u; + self.v = (*_a0).v; + self.weight = (*_a0).weight; + return &mut (*(self as *mut Edge)) as *mut Edge; + } +} pub unsafe fn partition_0(arr: *mut Option>, mut start: i32, mut end: i32) -> i32 { let pivot: *mut Edge = &mut (*arr).as_mut().unwrap()[(start as usize)] as *mut Edge; let mut count: i32 = 0; @@ -29,16 +37,22 @@ pub unsafe fn partition_0(arr: *mut Option>, mut start: i32, mut end v: (*arr).as_mut().unwrap()[(pidx as usize)].v, weight: (*arr).as_mut().unwrap()[(pidx as usize)].weight, }; - (*arr).as_mut().unwrap()[(pidx as usize)] = Edge { - u: (*arr).as_mut().unwrap()[(start as usize)].u, - v: (*arr).as_mut().unwrap()[(start as usize)].v, - weight: (*arr).as_mut().unwrap()[(start as usize)].weight, - }; - (*arr).as_mut().unwrap()[(start as usize)] = Edge { - u: tmp.u, - v: tmp.v, - weight: tmp.weight, - }; + (unsafe { + let mut _arg0: Edge = Edge { + u: (*arr).as_mut().unwrap()[(start as usize)].u, + v: (*arr).as_mut().unwrap()[(start as usize)].v, + weight: (*arr).as_mut().unwrap()[(start as usize)].weight, + }; + Edge::operator_assign_pmutEdge(&mut (*arr).as_mut().unwrap()[(pidx as usize)], &mut _arg0) + }); + (unsafe { + let mut _arg0: Edge = Edge { + u: tmp.u, + v: tmp.v, + weight: tmp.weight, + }; + Edge::operator_assign_pmutEdge(&mut (*arr).as_mut().unwrap()[(start as usize)], &mut _arg0) + }); let mut i: i32 = start; let mut j: i32 = end; 'loop_: while ((i) < (pidx)) && ((j) > (pidx)) { @@ -49,21 +63,36 @@ pub unsafe fn partition_0(arr: *mut Option>, mut start: i32, mut end j.prefix_dec(); } if ((i) < (pidx)) && ((j) > (pidx)) { - tmp = Edge { - u: (*arr).as_mut().unwrap()[(i as usize)].u, - v: (*arr).as_mut().unwrap()[(i as usize)].v, - weight: (*arr).as_mut().unwrap()[(i as usize)].weight, - }; - (*arr).as_mut().unwrap()[(i as usize)] = Edge { - u: (*arr).as_mut().unwrap()[(j as usize)].u, - v: (*arr).as_mut().unwrap()[(j as usize)].v, - weight: (*arr).as_mut().unwrap()[(j as usize)].weight, - }; - (*arr).as_mut().unwrap()[(j as usize)] = Edge { - u: tmp.u, - v: tmp.v, - weight: tmp.weight, - }; + (unsafe { + let mut _arg0: Edge = Edge { + u: (*arr).as_mut().unwrap()[(i as usize)].u, + v: (*arr).as_mut().unwrap()[(i as usize)].v, + weight: (*arr).as_mut().unwrap()[(i as usize)].weight, + }; + Edge::operator_assign_pmutEdge(&mut tmp, &mut _arg0) + }); + (unsafe { + let mut _arg0: Edge = Edge { + u: (*arr).as_mut().unwrap()[(j as usize)].u, + v: (*arr).as_mut().unwrap()[(j as usize)].v, + weight: (*arr).as_mut().unwrap()[(j as usize)].weight, + }; + Edge::operator_assign_pmutEdge( + &mut (*arr).as_mut().unwrap()[(i as usize)], + &mut _arg0, + ) + }); + (unsafe { + let mut _arg0: Edge = Edge { + u: tmp.u, + v: tmp.v, + weight: tmp.weight, + }; + Edge::operator_assign_pmutEdge( + &mut (*arr).as_mut().unwrap()[(j as usize)], + &mut _arg0, + ) + }); i.postfix_inc(); j.postfix_dec(); } @@ -199,31 +228,46 @@ unsafe fn main_0() -> i32 { V: V, E: E, }; - graph.edges.as_mut().unwrap()[(0_usize)] = Edge { - u: 0, - v: 1, - weight: 10_f64, - }; - graph.edges.as_mut().unwrap()[(1_usize)] = Edge { - u: 1, - v: 3, - weight: 15_f64, - }; - graph.edges.as_mut().unwrap()[(2_usize)] = Edge { - u: 2, - v: 3, - weight: 4_f64, - }; - graph.edges.as_mut().unwrap()[(3_usize)] = Edge { - u: 2, - v: 0, - weight: 6_f64, - }; - graph.edges.as_mut().unwrap()[(4_usize)] = Edge { - u: 0, - v: 3, - weight: 5_f64, - }; + (unsafe { + let mut _arg0: Edge = Edge { + u: 0, + v: 1, + weight: 10_f64, + }; + Edge::operator_assign_pmutEdge(&mut graph.edges.as_mut().unwrap()[(0_usize)], &mut _arg0) + }); + (unsafe { + let mut _arg0: Edge = Edge { + u: 1, + v: 3, + weight: 15_f64, + }; + Edge::operator_assign_pmutEdge(&mut graph.edges.as_mut().unwrap()[(1_usize)], &mut _arg0) + }); + (unsafe { + let mut _arg0: Edge = Edge { + u: 2, + v: 3, + weight: 4_f64, + }; + Edge::operator_assign_pmutEdge(&mut graph.edges.as_mut().unwrap()[(2_usize)], &mut _arg0) + }); + (unsafe { + let mut _arg0: Edge = Edge { + u: 2, + v: 0, + weight: 6_f64, + }; + Edge::operator_assign_pmutEdge(&mut graph.edges.as_mut().unwrap()[(3_usize)], &mut _arg0) + }); + (unsafe { + let mut _arg0: Edge = Edge { + u: 0, + v: 3, + weight: 5_f64, + }; + Edge::operator_assign_pmutEdge(&mut graph.edges.as_mut().unwrap()[(4_usize)], &mut _arg0) + }); let mut total_weight: f64 = (unsafe { MSTKruskal_2(&mut graph as *mut Graph) }); assert!(((total_weight) == (19_f64))); return 0; diff --git a/tests/unit/out/unsafe/operator_arithmetic_free.rs b/tests/unit/out/unsafe/operator_arithmetic_free.rs index 28a79422d..04eb9c0ab 100644 --- a/tests/unit/out/unsafe/operator_arithmetic_free.rs +++ b/tests/unit/out/unsafe/operator_arithmetic_free.rs @@ -11,6 +11,12 @@ use std::rc::Rc; pub struct S { pub v: i32, } +impl S { + pub unsafe fn S_pmutS(_a0: *mut S) -> Self { + let mut this = Self { v: (*_a0).v }; + this + } +} pub unsafe fn operator_add_0(a: *const S, b: *const S) -> S { return S { v: (((*a).v) + ((*b).v)), @@ -49,7 +55,7 @@ pub unsafe fn operator_inc_7(a: *mut S) -> *mut S { pub unsafe fn operator_post_inc_8(a: *mut S, mut _a1: i32) -> S { let mut old: S = (*a); (*a).v.prefix_inc(); - return old; + return S::S_pmutS({ &mut old as *mut S }); } pub unsafe fn operator_dec_9(a: *mut S) -> *mut S { (*a).v.prefix_dec(); @@ -58,7 +64,7 @@ pub unsafe fn operator_dec_9(a: *mut S) -> *mut S { pub unsafe fn operator_post_dec_10(a: *mut S, mut _a1: i32) -> S { let mut old: S = (*a); (*a).v.prefix_dec(); - return old; + return S::S_pmutS({ &mut old as *mut S }); } pub unsafe fn operator_add_11(a: *const S, mut b: i32) -> S { return S { diff --git a/tests/unit/out/unsafe/operator_arithmetic_member.rs b/tests/unit/out/unsafe/operator_arithmetic_member.rs index c3166ce23..ade17adf5 100644 --- a/tests/unit/out/unsafe/operator_arithmetic_member.rs +++ b/tests/unit/out/unsafe/operator_arithmetic_member.rs @@ -50,7 +50,7 @@ impl S { pub unsafe fn operator_post_inc_i32(&mut self, mut _a0: i32) -> S { let mut old: S = (*(self as *mut S)); self.v.prefix_inc(); - return old; + return S::S_pmutS({ &mut old as *mut S }); } pub unsafe fn operator_dec(&mut self) -> *mut S { self.v.prefix_dec(); @@ -59,7 +59,11 @@ impl S { pub unsafe fn operator_post_dec_i32(&mut self, mut _a0: i32) -> S { let mut old: S = (*(self as *mut S)); self.v.prefix_dec(); - return old; + return S::S_pmutS({ &mut old as *mut S }); + } + pub unsafe fn S_pmutS(_a0: *mut S) -> Self { + let mut this = Self { v: (*_a0).v }; + this } } pub fn main() { diff --git a/tests/unit/out/unsafe/operator_traits.rs b/tests/unit/out/unsafe/operator_traits.rs index db355396f..b81350619 100644 --- a/tests/unit/out/unsafe/operator_traits.rs +++ b/tests/unit/out/unsafe/operator_traits.rs @@ -15,6 +15,14 @@ impl Lt { pub unsafe fn operator_lt(&self, o: *const Lt) -> bool { return ((self.v) < ((*o).v)); } + pub unsafe fn Lt_pmutLt(_a0: *mut Lt) -> Self { + let mut this = Self { v: (*_a0).v }; + this + } + pub unsafe fn operator_assign_pmutLt(&mut self, _a0: *mut Lt) -> *mut Lt { + self.v = (*_a0).v; + return &mut (*(self as *mut Lt)) as *mut Lt; + } } impl std::cmp::Ord for Lt { fn cmp(&self, other: &Self) -> std::cmp::Ordering { @@ -71,6 +79,14 @@ impl Cmp { pub unsafe fn operator_eq(&self, o: *const Cmp) -> bool { return ((self.v) == ((*o).v)); } + pub unsafe fn Cmp_pmutCmp(_a0: *mut Cmp) -> Self { + let mut this = Self { v: (*_a0).v }; + this + } + pub unsafe fn operator_assign_pmutCmp(&mut self, _a0: *mut Cmp) -> *mut Cmp { + self.v = (*_a0).v; + return &mut (*(self as *mut Cmp)) as *mut Cmp; + } } impl std::cmp::Ord for Cmp { fn cmp(&self, other: &Self) -> std::cmp::Ordering { @@ -93,6 +109,16 @@ impl std::cmp::Eq for Cmp {} pub struct Free { pub v: i32, } +impl Free { + pub unsafe fn Free_pmutFree(_a0: *mut Free) -> Self { + let mut this = Self { v: (*_a0).v }; + this + } + pub unsafe fn operator_assign_pmutFree(&mut self, _a0: *mut Free) -> *mut Free { + self.v = (*_a0).v; + return &mut (*(self as *mut Free)) as *mut Free; + } +} impl std::cmp::Ord for Free { fn cmp(&self, other: &Self) -> std::cmp::Ordering { unsafe { diff --git a/tests/unit/out/unsafe/push_emplace_back.rs b/tests/unit/out/unsafe/push_emplace_back.rs index d6bfd0ab9..7d9581e0f 100644 --- a/tests/unit/out/unsafe/push_emplace_back.rs +++ b/tests/unit/out/unsafe/push_emplace_back.rs @@ -11,6 +11,12 @@ use std::rc::Rc; pub struct Chunk { pub data: i32, } +impl Chunk { + pub unsafe fn Chunk_pmutChunk(_a0: *mut Chunk) -> Self { + let mut this = Self { data: (*_a0).data }; + this + } +} #[repr(C)] #[derive(Copy, Clone, Default)] pub struct Writer { @@ -71,7 +77,7 @@ pub unsafe fn emplace_local_from_field_4(mut jpg: *mut JPEGData, mut cond: bool) } pub unsafe fn nested_emplace_move_5(mut bw: *mut Writer) { { - let __arg = std::mem::take(&mut (*bw).chunk); + let __arg = Chunk::Chunk_pmutChunk({ &mut (*bw).chunk as *mut Chunk }); (*(*bw).output).push(__arg) }; } diff --git a/tests/unit/out/unsafe/this.rs b/tests/unit/out/unsafe/this.rs index 124382998..216d7a64e 100644 --- a/tests/unit/out/unsafe/this.rs +++ b/tests/unit/out/unsafe/this.rs @@ -77,7 +77,10 @@ impl S { ::std::mem::drop(Box::from_raw((self as *mut S))); } pub unsafe fn reset(&mut self) { - (*(self as *mut S)) = S::S1({ 0 }); + (unsafe { + let mut _arg0: S = S::S1({ 0 }); + S::operator_assign_pmutS(&mut (*(self as *mut S)), &mut _arg0) + }); } pub unsafe fn copy_if_different_const(&mut self, mut other: *const S) -> bool { if (((self as *mut S).cast_const()) == (other)) { @@ -95,6 +98,11 @@ impl S { self.self__ = (*other).self__; return true; } + pub unsafe fn operator_assign_pmutS(&mut self, _a0: *mut S) -> *mut S { + self.a_ = (*_a0).a_; + self.self__ = (*_a0).self__; + return &mut (*(self as *mut S)) as *mut S; + } } pub unsafe fn bump_0(mut p: *mut S) { (*p).a_.postfix_inc(); diff --git a/tests/unit/out/unsafe/unique_ptr.rs b/tests/unit/out/unsafe/unique_ptr.rs index 2358a54b5..d1a583eb1 100644 --- a/tests/unit/out/unsafe/unique_ptr.rs +++ b/tests/unit/out/unsafe/unique_ptr.rs @@ -28,6 +28,20 @@ pub struct Pair { pub x: i32, pub y: i32, } +impl Pair { + pub unsafe fn Pair_pmutPair(_a0: *mut Pair) -> Self { + let mut this = Self { + x: (*_a0).x, + y: (*_a0).y, + }; + this + } + pub unsafe fn operator_assign_pmutPair(&mut self, _a0: *mut Pair) -> *mut Pair { + self.x = (*_a0).x; + self.y = (*_a0).y; + return &mut (*(self as *mut Pair)) as *mut Pair; + } +} impl Pair { pub unsafe fn inc(&mut self, mut k: i32) { self.x += k; @@ -106,7 +120,10 @@ pub unsafe fn RndStuff_2() { ); let mut i: i32 = 0; 'loop_: while ((i) < (10)) { - x3.as_mut().unwrap()[(i as usize)] = Pair { x: 1, y: 2 }; + (unsafe { + let mut _arg0: Pair = Pair { x: 1, y: 2 }; + Pair::operator_assign_pmutPair(&mut x3.as_mut().unwrap()[(i as usize)], &mut _arg0) + }); i.prefix_inc(); } let mut p3_0: *mut Pair = x3 @@ -128,10 +145,13 @@ pub unsafe fn RndStuff_2() { ))); let mut i: i32 = 0; 'loop_: while ((i) < (50)) { - x3.as_mut().unwrap()[(i as usize)] = Pair { - x: -1_i32, - y: -2_i32, - }; + (unsafe { + let mut _arg0: Pair = Pair { + x: -1_i32, + y: -2_i32, + }; + Pair::operator_assign_pmutPair(&mut x3.as_mut().unwrap()[(i as usize)], &mut _arg0) + }); i.prefix_inc(); } let mut p3_1: *mut Pair = x3 diff --git a/tests/unit/out/unsafe/unique_ptr_nested.rs b/tests/unit/out/unsafe/unique_ptr_nested.rs index 21bf245ae..cadf33404 100644 --- a/tests/unit/out/unsafe/unique_ptr_nested.rs +++ b/tests/unit/out/unsafe/unique_ptr_nested.rs @@ -12,6 +12,15 @@ pub struct Inner { pub x: i32, pub y: i32, } +impl Inner { + pub unsafe fn Inner_pmutInner(_a0: *mut Inner) -> Self { + let mut this = Self { + x: (*_a0).x, + y: (*_a0).y, + }; + this + } +} #[repr(C)] #[derive(Default)] pub struct Outer { diff --git a/tests/unit/out/unsafe/unique_ptr_struct.rs b/tests/unit/out/unsafe/unique_ptr_struct.rs index cfa481494..c99889b7c 100644 --- a/tests/unit/out/unsafe/unique_ptr_struct.rs +++ b/tests/unit/out/unsafe/unique_ptr_struct.rs @@ -12,6 +12,15 @@ pub struct Point { pub x: i32, pub y: i32, } +impl Point { + pub unsafe fn Point_pmutPoint(_a0: *mut Point) -> Self { + let mut this = Self { + x: (*_a0).x, + y: (*_a0).y, + }; + this + } +} pub unsafe fn sum_0(mut p: Point) -> i32 { return ((p.x) + (p.y)); }