@@ -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+
231236std::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
0 commit comments