From 35b7018b256f138e69ca5b7772bed39e780f66e8 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 5 Nov 2026 14:36:25 +0000 Subject: [PATCH 1/3] Keep std::pair member cells on move and assignment --- rules/pair/tgt_refcount.rs | 50 ++++++++++++++++++++--------- tests/unit/pair_member_identity.cpp | 40 +++++++++++++++++++++++ 2 files changed, 74 insertions(+), 16 deletions(-) create mode 100644 tests/unit/pair_member_identity.cpp diff --git a/rules/pair/tgt_refcount.rs b/rules/pair/tgt_refcount.rs index b6aa2218af..2976e40b81 100644 --- a/rules/pair/tgt_refcount.rs +++ b/rules/pair/tgt_refcount.rs @@ -31,25 +31,39 @@ fn f10(a0: T1, a1: T2) -> (Value, Value) { (Rc::new(RefCell::new(a0)), Rc::new(RefCell::new(a1))) } -fn f12(a0: &mut (Value, Value)) -> (Value, Value) { - std::mem::take(&mut *a0) +fn f12(a0: &mut (Value, Value)) -> (Value, Value) { + let __first: Ptr = a0.0.as_pointer(); + let __second: Ptr = a0.1.as_pointer(); + ( + Rc::new(RefCell::new(cpp_move!(__first))), + Rc::new(RefCell::new(cpp_move!(__second))), + ) } 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())), - )) + let __first = a1.0.borrow().clone(); + let __second = a1.1.borrow().clone(); + a0.with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) } -fn f14( +fn f14( a0: Ptr<(Value, Value)>, a1: &mut (Value, Value), ) { - a0.write(std::mem::take(&mut *a1)) + let __src_first: Ptr = a1.0.as_pointer(); + let __src_second: Ptr = a1.1.as_pointer(); + let __first = cpp_move!(__src_first); + let __second = cpp_move!(__src_second); + a0.with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) } fn f15(a0: (Value, Value)) -> Value { @@ -103,20 +117,24 @@ fn f25 + ByteRepr, T2: CppFrom + ByteRepr, T3, T4>( a0: Ptr<(Value, Value)>, a1: (Value, Value), ) { - a0.write(( - Rc::new(RefCell::new(T1::cpp_from(a1.0.as_pointer()))), - Rc::new(RefCell::new(T2::cpp_from(a1.1.as_pointer()))), - )) + let __first = T1::cpp_from(a1.0.as_pointer()); + let __second = T2::cpp_from(a1.1.as_pointer()); + a0.with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) } fn f26 + ByteRepr, T2: CppFrom + ByteRepr, T3, T4>( a0: Ptr<(Value, Value)>, a1: &mut (Value, Value), ) { - a0.write(( - Rc::new(RefCell::new(T1::cpp_from_move(a1.0.as_pointer()))), - Rc::new(RefCell::new(T2::cpp_from_move(a1.1.as_pointer()))), - )) + let __first = T1::cpp_from_move(a1.0.as_pointer()); + let __second = T2::cpp_from_move(a1.1.as_pointer()); + a0.with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) } fn f27(a0: (Value, Value)) -> Ptr<<(T2, T3) as TupleElement>::Type> diff --git a/tests/unit/pair_member_identity.cpp b/tests/unit/pair_member_identity.cpp new file mode 100644 index 0000000000..4cc5d5b284 --- /dev/null +++ b/tests/unit/pair_member_identity.cpp @@ -0,0 +1,40 @@ +#include +#include + +int main() { + std::pair p{1, 2}; + std::pair q{3, 4}; + int *f = &p.first; + p = q; + assert(*f == 3); + std::pair &alias = p; + p = alias; + assert(*f == 3); + + std::pair a{1, 2}; + int *pa = &a.first; + std::pair b = std::move(a); + *pa = 9; + assert(b.first == 1); + assert(a.first == 9); + + std::pair d{1, 2}; + std::pair s{3, 4}; + int *pd = &d.first; + int *ps = &s.first; + d = std::move(s); + assert(*pd == 3); + *ps = 5; + assert(d.first == 3); + assert(s.first == 5); + + std::pair w{1, 2}; + std::pair n{3, 4}; + long *pw = &w.first; + w = n; + assert(*pw == 3); + std::pair m{5, 6}; + w = std::move(m); + assert(*pw == 5); + return 0; +} From 5f6cec2102be87ad3d2fcac8c6b58a89c905355f Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 5 Nov 2026 14:46:52 +0000 Subject: [PATCH 2/3] Extend existing tests --- tests/unit/pair.cpp | 35 +++++++++++++++++++++++++ tests/unit/pair_member_identity.cpp | 40 ----------------------------- 2 files changed, 35 insertions(+), 40 deletions(-) delete mode 100644 tests/unit/pair_member_identity.cpp diff --git a/tests/unit/pair.cpp b/tests/unit/pair.cpp index c603bf5cfe..2c452a9e07 100644 --- a/tests/unit/pair.cpp +++ b/tests/unit/pair.cpp @@ -17,5 +17,40 @@ int main() { std::vector> const_ptr_pairs(1); const_ptr_pairs[0] = std::make_pair(arr + 1, n); assert(*const_ptr_pairs[0].first == 2 && const_ptr_pairs[0].second == 2); + + std::pair p{1, 2}; + std::pair q{3, 4}; + int *f = &p.first; + p = q; + assert(*f == 3); + std::pair &alias = p; + p = alias; + assert(*f == 3); + + std::pair a{1, 2}; + int *pa = &a.first; + std::pair b = std::move(a); + *pa = 9; + assert(b.first == 1); + assert(a.first == 9); + + std::pair d{1, 2}; + std::pair s{3, 4}; + int *pd = &d.first; + int *ps = &s.first; + d = std::move(s); + assert(*pd == 3); + *ps = 5; + assert(d.first == 3); + assert(s.first == 5); + + std::pair w{1, 2}; + std::pair narrow{3, 4}; + long *pw = &w.first; + w = narrow; + assert(*pw == 3); + std::pair m{5, 6}; + w = std::move(m); + assert(*pw == 5); return 0; } diff --git a/tests/unit/pair_member_identity.cpp b/tests/unit/pair_member_identity.cpp deleted file mode 100644 index 4cc5d5b284..0000000000 --- a/tests/unit/pair_member_identity.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include - -int main() { - std::pair p{1, 2}; - std::pair q{3, 4}; - int *f = &p.first; - p = q; - assert(*f == 3); - std::pair &alias = p; - p = alias; - assert(*f == 3); - - std::pair a{1, 2}; - int *pa = &a.first; - std::pair b = std::move(a); - *pa = 9; - assert(b.first == 1); - assert(a.first == 9); - - std::pair d{1, 2}; - std::pair s{3, 4}; - int *pd = &d.first; - int *ps = &s.first; - d = std::move(s); - assert(*pd == 3); - *ps = 5; - assert(d.first == 3); - assert(s.first == 5); - - std::pair w{1, 2}; - std::pair n{3, 4}; - long *pw = &w.first; - w = n; - assert(*pw == 3); - std::pair m{5, 6}; - w = std::move(m); - assert(*pw == 5); - return 0; -} From 5b4fdf5738f2451e7c816c5c3999edfa540a6b91 Mon Sep 17 00:00:00 2001 From: Lucian Popescu Date: Thu, 5 Nov 2026 15:18:51 +0000 Subject: [PATCH 3/3] Update tests --- tests/unit/out/refcount/pair.rs | 119 +++++++++++++++++++++++++++++--- tests/unit/out/unsafe/pair.rs | 31 +++++++++ 2 files changed, 140 insertions(+), 10 deletions(-) diff --git a/tests/unit/out/refcount/pair.rs b/tests/unit/out/refcount/pair.rs index 731a67930e..b3ed69bd89 100644 --- a/tests/unit/out/refcount/pair.rs +++ b/tests/unit/out/refcount/pair.rs @@ -62,16 +62,16 @@ fn main_0() -> i32 { ))) .as_pointer(),) { - (__tmp_1,) => const_ptr_pairs.decay().offset(0_usize).write(( - Rc::new(RefCell::new( - as CppFrom>>::cpp_from_move( - (*__tmp_1.upgrade().deref()).0.as_pointer(), - ), - )), - Rc::new(RefCell::new( - (((*__tmp_1.upgrade().deref()).1.as_pointer().read()) as u64), - )), - )), + (__tmp_1,) => { + let __first = as CppFrom>>::cpp_from_move( + (*__tmp_1.upgrade().deref()).0.as_pointer(), + ); + let __second = (((*__tmp_1.upgrade().deref()).1.as_pointer().read()) as u64); + const_ptr_pairs.decay().offset(0_usize).with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) + } }; assert!( ({ @@ -79,6 +79,105 @@ fn main_0() -> i32 { && ((*(*const_ptr_pairs.borrow())[0_usize].1.borrow()) == 2_u64) }) ); + let p: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new(1)), + Rc::new(RefCell::new(2)), + ))); + let q: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new(3)), + Rc::new(RefCell::new(4)), + ))); + let mut f: Ptr = ((*p.borrow()).0.as_pointer()); + { + let __first = (*q.borrow()).0.borrow().clone(); + let __second = (*q.borrow()).1.borrow().clone(); + p.as_pointer().with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) + }; + assert!(((f.read()) == 3)); + let alias: Ptr<(Value, Value)> = p.as_pointer(); + { + let __first = (*alias.upgrade().deref()).0.borrow().clone(); + let __second = (*alias.upgrade().deref()).1.borrow().clone(); + p.as_pointer().with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) + }; + assert!(((f.read()) == 3)); + let a: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new(1)), + Rc::new(RefCell::new(2)), + ))); + let mut pa: Ptr = ((*a.borrow()).0.as_pointer()); + let b: Value<(Value, Value)> = Rc::new(RefCell::new({ + let __first: Ptr = (*a.borrow()).0.as_pointer(); + let __second: Ptr = (*a.borrow()).1.as_pointer(); + ( + Rc::new(RefCell::new(cpp_move!(__first))), + Rc::new(RefCell::new(cpp_move!(__second))), + ) + })); + pa.write(9); + assert!(({ ((*(*b.borrow()).0.borrow()) == 1) })); + assert!(({ ((*(*a.borrow()).0.borrow()) == 9) })); + let d: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new(1)), + Rc::new(RefCell::new(2)), + ))); + let s: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new(3)), + Rc::new(RefCell::new(4)), + ))); + let mut pd: Ptr = ((*d.borrow()).0.as_pointer()); + let mut ps: Ptr = ((*s.borrow()).0.as_pointer()); + { + let __src_first: Ptr = (*s.borrow()).0.as_pointer(); + let __src_second: Ptr = (*s.borrow()).1.as_pointer(); + let __first = cpp_move!(__src_first); + let __second = cpp_move!(__src_second); + d.as_pointer().with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) + }; + assert!(((pd.read()) == 3)); + ps.write(5); + assert!(({ ((*(*d.borrow()).0.borrow()) == 3) })); + assert!(({ ((*(*s.borrow()).0.borrow()) == 5) })); + let w: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new((1 as i64))), + Rc::new(RefCell::new((2 as i64))), + ))); + let narrow: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new(3)), + Rc::new(RefCell::new(4)), + ))); + let mut pw: Ptr = ((*w.borrow()).0.as_pointer()); + { + let __first = (((*narrow.borrow()).0.as_pointer().read()) as i64); + let __second = (((*narrow.borrow()).1.as_pointer().read()) as i64); + w.as_pointer().with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) + }; + assert!(((pw.read()) == 3_i64)); + let m: Value<(Value, Value)> = Rc::new(RefCell::new(( + Rc::new(RefCell::new(5)), + Rc::new(RefCell::new(6)), + ))); + { + let __first = (((*m.borrow()).0.as_pointer().read()) as i64); + let __second = (((*m.borrow()).1.as_pointer().read()) as i64); + w.as_pointer().with(|__dst| { + *__dst.0.borrow_mut() = __first; + *__dst.1.borrow_mut() = __second; + }) + }; + assert!(((pw.read()) == 5_i64)); return 0; } pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/pair.rs b/tests/unit/out/unsafe/pair.rs index 341508f4ff..ea07a8b033 100644 --- a/tests/unit/out/unsafe/pair.rs +++ b/tests/unit/out/unsafe/pair.rs @@ -40,6 +40,37 @@ unsafe fn main_0() -> i32 { assert!( ((*const_ptr_pairs[(0_usize)].0) == (2)) && ((const_ptr_pairs[(0_usize)].1) == (2_u64)) ); + let mut p: (i32, i32) = (1, 2); + let mut q: (i32, i32) = (3, 4); + let mut f: *mut i32 = (&mut p.0 as *mut i32); + p = q.clone(); + assert!(((*f) == (3))); + let alias: *mut (i32, i32) = &mut p; + p = (*alias).clone(); + assert!(((*f) == (3))); + let mut a: (i32, i32) = (1, 2); + let mut pa: *mut i32 = (&mut a.0 as *mut i32); + let mut b: (i32, i32) = std::mem::take(&mut a); + (*pa) = 9; + assert!(((b.0) == (1))); + assert!(((a.0) == (9))); + let mut d: (i32, i32) = (1, 2); + let mut s: (i32, i32) = (3, 4); + let mut pd: *mut i32 = (&mut d.0 as *mut i32); + let mut ps: *mut i32 = (&mut s.0 as *mut i32); + d = std::mem::take(&mut s); + assert!(((*pd) == (3))); + (*ps) = 5; + assert!(((d.0) == (3))); + assert!(((s.0) == (5))); + let mut w: (i64, i64) = ((1 as i64), (2 as i64)); + let mut narrow: (i32, i32) = (3, 4); + let mut pw: *mut i64 = (&mut w.0 as *mut i64); + w = (((*&narrow.0) as i64), ((*&narrow.1) as i64)); + assert!(((*pw) == (3_i64))); + let mut m: (i32, i32) = (5, 6); + w = (((*&mut m.0) as i64), ((*&mut m.1) as i64)); + assert!(((*pw) == (5_i64))); return 0; } pub unsafe fn __cpp2rust_init_globals() {}