Skip to content

Commit 98ecad7

Browse files
authored
Add move rules for STL containers (#360)
Don't special case the move constructor of unique_ptr inside the converter. Instead add a rule for it. Also added move constructs and assignment rules for array, vector, map.
1 parent fd2ea09 commit 98ecad7

26 files changed

Lines changed: 165 additions & 47 deletions

‎cpp2rust/converter/converter.cpp‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1765,12 +1765,7 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) {
17651765
}
17661766

17671767
if (expr->isCallToStdMove()) {
1768-
if (IsUniquePtr(expr->getArg(0)->getType())) {
1769-
StrCat(std::format("{}.take()", ConvertLValue(expr->getArg(0))));
1770-
computed_expr_type_ = ComputedExprType::FreshValue;
1771-
return false;
1772-
}
1773-
StrCat(std::format("{}", ToString(expr->getArg(0))));
1768+
Convert(expr->getArg(0));
17741769
return false;
17751770
}
17761771

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,15 +1151,9 @@ bool ConverterRefCount::VisitStringLiteral(clang::StringLiteral *expr) {
11511151
bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) {
11521152
auto *sub_expr = expr->getSubExpr();
11531153

1154-
// return unique_ptr (implicit xvalue cast)
11551154
if (expr->isXValue() && sub_expr->isLValue()) {
11561155
Convert(sub_expr);
1157-
if (IsUniquePtr(sub_expr->getType())) {
1158-
StrCat(".take()");
1159-
computed_expr_type_ = ComputedExprType::FreshValue;
1160-
} else {
1161-
computed_expr_type_ = ComputedExprType::Value;
1162-
}
1156+
computed_expr_type_ = ComputedExprType::Value;
11631157
return false;
11641158
}
11651159

@@ -2578,6 +2572,10 @@ std::string ConverterRefCount::ConvertMappedMethodCall(
25782572

25792573
auto arg_idx = receiver_ph->n;
25802574
auto *arg = BuildUnifiedArgs(expr, args, num_args)[arg_idx];
2575+
if (auto *call = clang::dyn_cast<clang::CallExpr>(arg->IgnoreCasts());
2576+
call && call->isCallToStdMove()) {
2577+
arg = call->getArg(0);
2578+
}
25812579

25822580
if (!arg->getType()->isPointerType() && !IsReferenceType(arg)) {
25832581
return Converter::ConvertMappedMethodCall(expr, mc, args, num_args, ctx);

‎rules/array/src.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,13 @@ std::size_t f2(const std::array<T1, T2> &o) {
1919
template <typename T1, std::size_t T2> T1 *f3(std::array<T1, T2> &o) {
2020
return o.data();
2121
}
22+
23+
template <typename T1, std::size_t T2>
24+
std::array<T1, T2> f4(std::array<T1, T2> &&o) {
25+
return std::array<T1, T2>(std::move(o));
26+
}
27+
28+
template <typename T1, std::size_t T2>
29+
std::array<T1, T2> &f5(std::array<T1, T2> &dst, std::array<T1, T2> &&src) {
30+
return dst.operator=(std::move(src));
31+
}

‎rules/array/tgt_refcount.rs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ fn f1<T1>(a0: Ptr<T1>) -> Ptr<T1> {
1212
fn f3<T1>(a0: Ptr<T1>) -> Ptr<T1> {
1313
a0
1414
}
15+
16+
fn f5<T1: ByteRepr + Clone>(a0: Ptr<Vec<T1>>, a1: &mut Vec<T1>) {
17+
a0.write(std::mem::take(&mut *a1))
18+
}

‎rules/array/tgt_unsafe.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,11 @@ unsafe fn f2<T1>(a0: Vec<T1>) -> usize {
1818
unsafe fn f3<T1>(a0: &mut Vec<T1>) -> *mut T1 {
1919
a0.as_mut_ptr()
2020
}
21+
22+
unsafe fn f4<T1>(a0: &mut Vec<T1>) -> Vec<T1> {
23+
std::mem::take(&mut *a0)
24+
}
25+
26+
unsafe fn f5<T1>(a0: &mut Vec<T1>, a1: &mut Vec<T1>) {
27+
*a0 = std::mem::take(&mut *a1)
28+
}

‎rules/map/src.cpp‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,12 @@ template <typename T1, typename T2>
117117
T2 &f23(typename std::map<T1, T2>::iterator it) {
118118
return it->second;
119119
}
120+
121+
template <typename T1, typename T2> std::map<T1, T2> f24(std::map<T1, T2> &&o) {
122+
return std::map<T1, T2>(std::move(o));
123+
}
124+
125+
template <typename T1, typename T2>
126+
std::map<T1, T2> &f25(std::map<T1, T2> &dst, std::map<T1, T2> &&src) {
127+
return dst.operator=(std::move(src));
128+
}

‎rules/map/tgt_refcount.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,15 @@ fn f22<T1: Ord + Clone + 'static, T2: 'static>(a0: RefcountMapIter<T1, T2>) -> V
139139
fn f23<T1: Ord + Clone + 'static, T2: 'static>(a0: RefcountMapIter<T1, T2>) -> Value<T2> {
140140
a0.second()
141141
}
142+
143+
fn f24<T1: 'static, T2: 'static>(a0: Ptr<BTreeMap<T1, Value<T2>>>) -> BTreeMap<T1, Value<T2>> {
144+
a0.with_mut(|__v: &mut BTreeMap<T1, Value<T2>>| std::mem::take(__v))
145+
}
146+
147+
fn f25<T1: 'static, T2: 'static>(
148+
a0: Ptr<BTreeMap<T1, Value<T2>>>,
149+
a1: Ptr<BTreeMap<T1, Value<T2>>>,
150+
) {
151+
let __src = a1.with_mut(|__v: &mut BTreeMap<T1, Value<T2>>| std::mem::take(__v));
152+
a0.write(__src)
153+
}

‎rules/map/tgt_unsafe.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,11 @@ unsafe fn f22<T1: Ord + Clone, T2>(a0: UnsafeMapIterator<T1, T2>) -> *const T1 {
102102
unsafe fn f23<T1: Ord + Clone, T2>(a0: UnsafeMapIterator<T1, T2>) -> *mut T2 {
103103
a0.second()
104104
}
105+
106+
unsafe fn f24<T1, T2>(a0: &mut BTreeMap<T1, Box<T2>>) -> BTreeMap<T1, Box<T2>> {
107+
std::mem::take(&mut *a0)
108+
}
109+
110+
unsafe fn f25<T1, T2>(a0: &mut BTreeMap<T1, Box<T2>>, a1: &mut BTreeMap<T1, Box<T2>>) {
111+
*a0 = std::mem::take(&mut *a1)
112+
}

‎rules/unique_ptr/src.cpp‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,22 @@ template <typename T1> std::unique_ptr<T1> f10() {
5555
template <typename T1> std::unique_ptr<T1[]> f11() {
5656
return std::unique_ptr<T1[]>();
5757
}
58+
59+
template <typename T1> std::unique_ptr<T1> f12(std::unique_ptr<T1> &&o) {
60+
return std::unique_ptr<T1>(std::move(o));
61+
}
62+
63+
template <typename T1> std::unique_ptr<T1[]> f13(std::unique_ptr<T1[]> &&o) {
64+
return std::unique_ptr<T1[]>(std::move(o));
65+
}
66+
67+
template <typename T1>
68+
std::unique_ptr<T1> &f14(std::unique_ptr<T1> &dst, std::unique_ptr<T1> &&src) {
69+
return dst.operator=(std::move(src));
70+
}
71+
72+
template <typename T1>
73+
std::unique_ptr<T1[]> &f15(std::unique_ptr<T1[]> &dst,
74+
std::unique_ptr<T1[]> &&src) {
75+
return dst.operator=(std::move(src));
76+
}

‎rules/unique_ptr/tgt_refcount.rs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,19 @@ fn f10<T1>() -> Option<Value<T1>> {
5959
fn f11<T1>() -> Option<Value<Box<[T1]>>> {
6060
None
6161
}
62+
63+
fn f12<T1>(a0: &mut Option<Value<T1>>) -> Option<Value<T1>> {
64+
a0.take()
65+
}
66+
67+
fn f13<T1>(a0: &mut Option<Value<Box<[T1]>>>) -> Option<Value<Box<[T1]>>> {
68+
a0.take()
69+
}
70+
71+
fn f14<T1: ByteRepr>(a0: Ptr<Option<Value<T1>>>, a1: &mut Option<Value<T1>>) {
72+
a0.write(a1.take())
73+
}
74+
75+
fn f15<T1: ByteRepr>(a0: Ptr<Option<Value<Box<[T1]>>>>, a1: &mut Option<Value<Box<[T1]>>>) {
76+
a0.write(a1.take())
77+
}

0 commit comments

Comments
 (0)