Skip to content

Commit 3444e8e

Browse files
committed
Merge branch 'master' into vec-decay
2 parents 0f95023 + b168af5 commit 3444e8e

38 files changed

Lines changed: 1897 additions & 1492 deletions

‎cpp2rust/converter/converter.cpp‎

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,11 @@ std::string Converter::ConvertPointerReceiver(clang::Expr *arg,
228228
return std::format("({} as {})", ConvertFreshObject(arg), param_type);
229229
}
230230

231+
std::string Converter::ConvertTemporaryPointer(
232+
clang::Expr *expr, std::optional<clang::QualType> implicit_convert_to) {
233+
return std::format("&mut {}", ConvertFreshRValue(expr, implicit_convert_to));
234+
}
235+
231236
std::string Converter::ConvertLValue(clang::Expr *expr) {
232237
PushExprKind push(*this, ExprKind::LValue);
233238
return ToString(expr);
@@ -3857,7 +3862,8 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
38573862
return false;
38583863
}
38593864

3860-
if (ctor->isDefaultConstructor() && !ctor->isUserProvided()) {
3865+
if (ctor->isDefaultConstructor() &&
3866+
!(ctor->isUserProvided() && IsUserDefinedDecl(ctor))) {
38613867
auto ty = expr->getType();
38623868
StrCat(GetDefaultAsString(ty));
38633869
SetFreshType(expr->getType());
@@ -5159,17 +5165,23 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg,
51595165
}
51605166

51615167
if (ph_ctx.needs_ptr_wrap()) {
5168+
if (clang::isa<clang::MaterializeTemporaryExpr>(arg)) {
5169+
return ConvertTemporaryPointer(arg, ph_ctx.implicit_convert_to);
5170+
}
51625171
return ConvertFreshObject(arg);
51635172
}
51645173

51655174
if (ph_ctx.needs_lvalue()) {
51665175
return ConvertBorrowMut(arg);
51675176
}
51685177

5169-
if (ph_ctx.access == TranslationRule::Access::kTake) {
5170-
if (clang::isa<clang::MaterializeTemporaryExpr>(arg)) {
5171-
return ConvertRValue(arg);
5172-
}
5178+
// The rule takes the argument by value from an rvalue reference parameter,
5179+
// e.g., push_back(T &&), and so C++ moves it.
5180+
auto param_type = GetParamType(expr, ph_ctx.arg_idx);
5181+
bool moved = ph_ctx.access == TranslationRule::Access::kTake ||
5182+
(ph_ctx.access == TranslationRule::Access::kMove && param_type &&
5183+
(*param_type)->isRValueReferenceType());
5184+
if (moved && !clang::isa<clang::MaterializeTemporaryExpr>(arg)) {
51735185
if (auto *record = arg->getType()->getAsCXXRecordDecl();
51745186
record && IsUserDefinedDecl(record)) {
51755187
for (auto *ctor : record->ctors()) {
@@ -5185,6 +5197,12 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg,
51855197
}
51865198
return ConvertFreshRValue(arg);
51875199
}
5200+
}
5201+
5202+
if (ph_ctx.access == TranslationRule::Access::kTake) {
5203+
if (clang::isa<clang::MaterializeTemporaryExpr>(arg)) {
5204+
return ConvertRValue(arg);
5205+
}
51885206
return ConvertTake(arg);
51895207
}
51905208

‎cpp2rust/converter/converter.h‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,13 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
10801080

10811081
virtual std::string ConvertPointerReceiver(clang::Expr *arg,
10821082
std::string_view param_type);
1083+
1084+
// A pointer to a new temporary with the value of the prvalue expr, which
1085+
// lives until the end of the statement.
1086+
virtual std::string
1087+
ConvertTemporaryPointer(clang::Expr *expr,
1088+
std::optional<clang::QualType> implicit_convert_to);
1089+
10831090
std::string
10841091
ConvertPointer(clang::Expr *expr,
10851092
std::optional<clang::QualType> implicit_convert_to = {},

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,8 +1984,8 @@ bool HasReceiver(clang::Expr *expr) {
19841984
return false;
19851985
}
19861986

1987-
std::optional<clang::QualType> GetParamImplicitConvertTarget(clang::Expr *expr,
1988-
unsigned arg_idx) {
1987+
std::optional<clang::QualType> GetParamType(clang::Expr *expr,
1988+
unsigned arg_idx) {
19891989
const clang::FunctionDecl *fn = nullptr;
19901990
if (auto *call = clang::dyn_cast<clang::CallExpr>(expr)) {
19911991
fn = call->getDirectCallee();
@@ -1999,7 +1999,16 @@ std::optional<clang::QualType> GetParamImplicitConvertTarget(clang::Expr *expr,
19991999
if (param_idx >= fn->getNumParams()) {
20002000
return std::nullopt;
20012001
}
2002-
return fn->getParamDecl(param_idx)->getType().getNonReferenceType();
2002+
return fn->getParamDecl(param_idx)->getType();
2003+
}
2004+
2005+
std::optional<clang::QualType> GetParamImplicitConvertTarget(clang::Expr *expr,
2006+
unsigned arg_idx) {
2007+
auto type = GetParamType(expr, arg_idx);
2008+
if (!type) {
2009+
return std::nullopt;
2010+
}
2011+
return type->getNonReferenceType();
20032012
}
20042013

20052014
bool IsAliasOfInit(clang::ASTContext &ctx, const clang::VarDecl *var) {

‎cpp2rust/converter/converter_lib.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,9 @@ bool ArgsMayAlias(const clang::Expr *a, const clang::Expr *b);
318318

319319
bool HasReceiver(clang::Expr *expr);
320320

321+
std::optional<clang::QualType> GetParamType(clang::Expr *expr,
322+
unsigned arg_idx);
323+
321324
std::optional<clang::QualType> GetParamImplicitConvertTarget(clang::Expr *expr,
322325
unsigned arg_idx);
323326

‎cpp2rust/converter/models/converter_refcount.cpp‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,12 @@ std::string ConverterRefCount::ConvertFreshObject(clang::Expr *expr) {
413413
return std::format("({}).clone()", std::move(str));
414414
}
415415

416+
std::string ConverterRefCount::ConvertTemporaryPointer(
417+
clang::Expr *expr, std::optional<clang::QualType> implicit_convert_to) {
418+
return std::format("Rc::new(RefCell::new({})).as_pointer()",
419+
ConvertFreshRValue(expr, implicit_convert_to));
420+
}
421+
416422
std::string ConverterRefCount::ConvertFresh(
417423
clang::Expr *expr, std::optional<clang::QualType> implicit_convert_to) {
418424
auto str = ToString(expr, implicit_convert_to);
@@ -2325,7 +2331,8 @@ bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) {
23252331
return false;
23262332
}
23272333

2328-
if (ctor->isDefaultConstructor() && !ctor->isUserProvided()) {
2334+
if (ctor->isDefaultConstructor() &&
2335+
!(ctor->isUserProvided() && IsUserDefinedDecl(ctor))) {
23292336
auto ty = expr->getType();
23302337
StrCat(GetDefaultAsString(ty));
23312338
SetFreshType(ty);

‎cpp2rust/converter/models/converter_refcount.h‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,11 @@ class ConverterRefCount final : public Converter {
399399
std::string_view param_type) override;
400400

401401
std::string AsPointerMethod(clang::QualType type) const;
402+
403+
std::string ConvertTemporaryPointer(
404+
clang::Expr *expr,
405+
std::optional<clang::QualType> implicit_convert_to) override;
406+
402407
bool WantsElementPtr() const { return object_shape_ == ObjectShape::Element; }
403408
std::string
404409
ConvertFresh(clang::Expr *expr,

‎libcc2rs/src/swap.rs‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,27 @@ macro_rules! cpp_swap_unsafe {
8585
}};
8686
}
8787

88+
// cpp_move!(p), or cpp_move_unsafe!(p), constructs a value from the one that
89+
// p points to as C++ does with T(std::move(*p)), like the temporary of the
90+
// swap.
91+
#[macro_export]
92+
macro_rules! cpp_move {
93+
($p:expr) => {{
94+
#[allow(unused_imports)]
95+
use $crate::__swap::{ConstructCopy, ConstructMove, ConstructNone};
96+
(&&&$crate::__swap::Construct(&$p)).construct()
97+
}};
98+
}
99+
100+
#[macro_export]
101+
macro_rules! cpp_move_unsafe {
102+
($p:expr) => {{
103+
#[allow(unused_imports)]
104+
use $crate::__swap::{ConstructCopyUnsafe, ConstructMoveUnsafe, ConstructNoneUnsafe};
105+
unsafe { (&&&$crate::__swap::ConstructUnsafe($p)).construct() }
106+
}};
107+
}
108+
88109
// Whether the type has none of the special members that the swap calls.
89110
macro_rules! trivial {
90111
($wrapper:ident, $ptr:ty, $none:ident, $($tr:ident: $bound:ident for $recv:ty),*) => {

0 commit comments

Comments
 (0)