diff --git a/rules/vector/tgt_refcount.rs b/rules/vector/tgt_refcount.rs index 5f48646b0d..75fcd876a9 100644 --- a/rules/vector/tgt_refcount.rs +++ b/rules/vector/tgt_refcount.rs @@ -93,6 +93,10 @@ fn f96(a0: Ptr) -> RandomAccessIterator { a0.end() } +fn f97(a0: Ptr>, a1: Ptr>) { + a0.swap_with(&a1, |__v| __v.with_mut(std::mem::take)) +} + fn f98(a0: Ptr>, a1: usize) -> Ptr { if a1 as usize >= (*a0.upgrade().deref()).len() { panic!("out of bounds access") diff --git a/rules/vector/tgt_unsafe.rs b/rules/vector/tgt_unsafe.rs index b1b8cfd8d1..0739641e97 100644 --- a/rules/vector/tgt_unsafe.rs +++ b/rules/vector/tgt_unsafe.rs @@ -175,7 +175,7 @@ unsafe fn f96(a0: Vec) -> UnsafeRandomAccessIterator { a0.end() } -unsafe fn f97(a0: &mut Vec, a1: &mut Vec) { +unsafe fn f97(a0: &mut Vec, a1: &mut Vec) { std::mem::swap(&mut *a0, &mut *a1) } diff --git a/tests/unit/out/refcount/vector.rs b/tests/unit/out/refcount/vector.rs index 3b52b3b4f1..052fe696c8 100644 --- a/tests/unit/out/refcount/vector.rs +++ b/tests/unit/out/refcount/vector.rs @@ -13,6 +13,27 @@ pub struct S { pub x: i32, } pub fn copy_0(mut copy_vector: Vec) {} +#[derive(Clone, Record, ByteRepr, VaArg, FnPtrArg, MoveCtor, MoveAssign, Default)] +#[byte_size(48)] +pub struct Foo { + #[offset(0)] + #[byte_size(24)] + pub a: Vec, + #[offset(24)] + #[byte_size(24)] + pub b: Vec, +} +impl Foo { + pub fn move_from(_a0: Ptr) -> Self { + Self { + a: field!(_a0, a).with_mut(std::mem::take), + b: field!(_a0, b).with_mut(std::mem::take), + } + } +} +pub fn exchange_1(x: Ptr>, y: Ptr>) { + x.swap_with(&(y).clone(), |__v| __v.with_mut(std::mem::take)); +} pub fn main() { __cpp2rust_init_globals(); std::process::exit(main_0()); @@ -332,6 +353,69 @@ fn main_0() -> i32 { }; field!(((v9[0_usize].read()).read()), x).write(2); assert!(({ ({ (*a.borrow()).x } == 2) })); + let v10: Value> = Rc::new(RefCell::new(Vec::from([1, 2, 3]))); + let v11: Value> = Rc::new(RefCell::new(Vec::from([4]))); + v10.as_pointer() + .swap_with(&v11.as_pointer(), |__v| __v.with_mut(std::mem::take)); + assert!( + ({ + ((((*v10.borrow()).len() == 1_usize) && ({ (*v10.borrow())[0_usize] } == 4)) + && ((*v11.borrow()).len() == 3_usize)) + && ({ (*v11.borrow())[2_usize] } == 3) + }) + ); + let foo: Value = Rc::new(RefCell::new(::default())); + { + let __a1 = 5; + (*foo.borrow_mut()).a.push(__a1) + }; + { + let __a1 = 6; + (*foo.borrow_mut()).b.push(__a1) + }; + { + let __a1 = 7; + (*foo.borrow_mut()).b.push(__a1) + }; + field_ref!(foo.as_pointer(), a) + .as_pointer() + .swap_with(&field_ref!(foo.as_pointer(), b).as_pointer(), |__v| { + __v.with_mut(std::mem::take) + }); + assert!( + ({ + (((*foo.borrow()).a.len() == 2_usize) + && ((vec_elem!(foo.as_pointer(), a, 1_usize).read()) == 7)) + && ((vec_elem!(foo.as_pointer(), b, 0_usize).read()) == 5) + }) + ); + ({ + exchange_1( + field_ref!(foo.as_pointer(), a).as_pointer(), + v10.as_pointer(), + ) + }); + assert!( + ({ + (((*foo.borrow()).a.len() == 1_usize) + && ((vec_elem!(foo.as_pointer(), a, 0_usize).read()) == 4)) + && ({ (*v10.borrow())[1_usize] } == 7) + }) + ); return 0; } +pub trait FooImpl { + fn move_assign(&self, _a0: Ptr) -> Ptr; +} +impl FooImpl for Ptr { + fn move_assign(&self, _a0: Ptr) -> Ptr { + field_ref!((*self), a) + .as_pointer() + .write(field!(_a0, a).with_mut(std::mem::take)); + field_ref!((*self), b) + .as_pointer() + .write(field!(_a0, b).with_mut(std::mem::take)); + return (*self).clone(); + } +} pub fn __cpp2rust_init_globals() {} diff --git a/tests/unit/out/unsafe/vector.rs b/tests/unit/out/unsafe/vector.rs index dd82b25c2e..82ae8a6aa5 100644 --- a/tests/unit/out/unsafe/vector.rs +++ b/tests/unit/out/unsafe/vector.rs @@ -12,6 +12,29 @@ pub struct S { pub x: i32, } pub unsafe fn copy_0(mut copy_vector: Vec) {} +#[repr(C)] +#[derive(Clone, VaArg, FnPtrArg, MoveCtorUnsafe, MoveAssignUnsafe, Default)] +pub struct Foo { + pub a: Vec, + pub b: Vec, +} +impl Foo { + pub unsafe fn move_from(_a0: *mut Foo) -> Self { + let mut this = Self { + a: std::mem::take(&mut (*_a0).a), + b: std::mem::take(&mut (*_a0).b), + }; + this + } + pub unsafe fn move_assign(&mut self, _a0: *mut Foo) -> *mut Foo { + self.a = std::mem::take(&mut (*_a0).a); + self.b = std::mem::take(&mut (*_a0).b); + return &mut (*(self as *mut Foo)); + } +} +pub unsafe fn exchange_1(x: *mut Vec, y: *mut Vec) { + std::mem::swap(&mut (*x), &mut (*y)); +} pub fn main() { unsafe { __cpp2rust_init_globals(); @@ -298,6 +321,35 @@ unsafe fn main_0() -> i32 { }; (*(*(*v9[(0_usize)]))).x = 2; assert!(((a.x) == (2))); + let mut v10: Vec = Vec::from([1, 2, 3]); + let mut v11: Vec = Vec::from([4]); + std::mem::swap(&mut v10, &mut v11); + assert!( + ((((v10.len()) == (1_usize)) && ((v10[(0_usize)]) == (4))) && ((v11.len()) == (3_usize))) + && ((v11[(2_usize)]) == (3)) + ); + let mut foo: Foo = ::default(); + { + let __a1 = 5; + foo.a.push(__a1) + }; + { + let __a1 = 6; + foo.b.push(__a1) + }; + { + let __a1 = 7; + foo.b.push(__a1) + }; + std::mem::swap(&mut foo.a, &mut foo.b); + assert!( + (((foo.a.len()) == (2_usize)) && ((foo.a[(1_usize)]) == (7))) + && ((foo.b[(0_usize)]) == (5)) + ); + (unsafe { exchange_1(&mut foo.a, &mut v10) }); + assert!( + (((foo.a.len()) == (1_usize)) && ((foo.a[(0_usize)]) == (4))) && ((v10[(1_usize)]) == (7)) + ); return 0; } pub unsafe fn __cpp2rust_init_globals() {} diff --git a/tests/unit/vector.cpp b/tests/unit/vector.cpp index 82935676c3..2f907cca43 100644 --- a/tests/unit/vector.cpp +++ b/tests/unit/vector.cpp @@ -7,6 +7,13 @@ struct S { void copy(std::vector copy_vector) {} +struct Foo { + std::vector a; + std::vector b; +}; + +static void exchange(std::vector &x, std::vector &y) { x.swap(y); } + int main() { std::vector v1; assert(v1.size() == 0); @@ -157,5 +164,18 @@ int main() { v9.push_back(&ppa); (**v9[0])->x = 2; assert(a.x == 2); + + std::vector v10 = {1, 2, 3}; + std::vector v11 = {4}; + v10.swap(v11); + assert(v10.size() == 1 && v10[0] == 4 && v11.size() == 3 && v11[2] == 3); + Foo foo; + foo.a.push_back(5); + foo.b.push_back(6); + foo.b.push_back(7); + foo.a.swap(foo.b); + assert(foo.a.size() == 2 && foo.a[1] == 7 && foo.b[0] == 5); + exchange(foo.a, v10); + assert(foo.a.size() == 1 && foo.a[0] == 4 && v10[1] == 7); return 0; }