diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 031f6e83..54a4274c 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -956,7 +956,7 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) { if (!record_decls_.MarkDefined(GetRecordName(decl))) { // Other translation units may instantiate members this one did not. - if (clang::isa(decl)) { + if (!decl->isAbstract()) { ConvertLateInstantiatedMethods(decl); } return false; @@ -967,25 +967,7 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) { return false; } - sema_->ForceDeclarationOfImplicitMembers(decl); - for (auto ctor : decl->ctors()) { - if (ctor->isCopyConstructor() && ctor->isImplicit() && - !ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted()) { - sema_->DefineImplicitCopyConstructor(decl->getLocation(), ctor); - } - } - for (auto *method : decl->methods()) { - if (IsComparisonOperator(method) && method->isDefaulted() && - !method->doesThisDeclarationHaveABody()) { -#if CLANG_VERSION_MAJOR >= 24 - auto kind = method->getDefaultedComparisonKind(); -#else - auto kind = sema_->getDefaultedComparisonKind(method); -#endif - sema_->DefineDefaultedComparison(decl->getLocation(), method, kind); - } - } - + DefineImplicitMembers(decl); EmitRustStructOrUnion(decl); } else if (decl->isUnion()) { if (!record_decls_.MarkDefined(GetRecordName(decl))) { @@ -1000,6 +982,44 @@ bool Converter::VisitCXXRecordDecl(clang::CXXRecordDecl *decl) { return false; } +void Converter::DefineImplicitMembers(clang::CXXRecordDecl *decl) { + clang::Scope tu_scope(nullptr, clang::Scope::DeclScope, + sema_->getDiagnostics()); + tu_scope.setEntity(ctx_.getTranslationUnitDecl()); + auto *saved_tu_scope = std::exchange(sema_->TUScope, &tu_scope); + sema_->ForceDeclarationOfImplicitMembers(decl); + for (auto ctor : decl->ctors()) { + if (ctor->isCopyConstructor() && ctor->isImplicit() && + !ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted()) { + sema_->DefineImplicitCopyConstructor(decl->getLocation(), ctor); + } + if (ctor->isMoveConstructor() && !ctor->isUserProvided() && + !ctor->doesThisDeclarationHaveABody() && !ctor->isDeleted() && + !HasDefaultedCopyConstructor(decl)) { + sema_->DefineImplicitMoveConstructor(decl->getLocation(), ctor); + } + } + for (auto *method : decl->methods()) { + if (method->isMoveAssignmentOperator() && !method->isUserProvided() && + !method->doesThisDeclarationHaveABody() && !method->isDeleted() && + !HasDefaultedCopyAssignment(decl)) { + sema_->DefineImplicitMoveAssignment(decl->getLocation(), method); + } + } + for (auto *method : decl->methods()) { + if (IsComparisonOperator(method) && method->isDefaulted() && + !method->doesThisDeclarationHaveABody()) { +#if CLANG_VERSION_MAJOR >= 24 + auto kind = method->getDefaultedComparisonKind(); +#else + auto kind = sema_->getDefaultedComparisonKind(method); +#endif + sema_->DefineDefaultedComparison(decl->getLocation(), method, kind); + } + } + sema_->TUScope = saved_tu_scope; +} + bool Converter::VisitCXXMethodDecl(clang::CXXMethodDecl *decl) { decl->dump(log()); if (!ShouldConvertMethod(decl)) { @@ -1087,7 +1107,8 @@ std::string Converter::GetCtorName(clang::CXXConstructorDecl *decl) { } bool Converter::VisitCXXConstructorDecl(clang::CXXConstructorDecl *decl) { - if (decl->isOutOfLine() || decl->isImplicit()) { + if (decl->isOutOfLine() || + (decl->isImplicit() && !IsConvertibleImplicitMember(decl))) { return false; } PushCurrFunction push_fn(*this, decl); @@ -1744,6 +1765,12 @@ bool Converter::VisitCallExpr(clang::CallExpr *expr) { return false; } + if (IsImplicitAssignmentCall(expr) && !Mapper::Contains(expr->getCallee())) { + auto *call = clang::cast(expr); + ConvertAssignment(call->getImplicitObjectArgument(), call->getArg(0), "="); + return false; + } + if (auto plugin_str = TryPluginConvert(expr)) { StrCat(*plugin_str); SetFreshType(expr->getType()); @@ -2691,7 +2718,7 @@ void Converter::ConvertGenericBinaryOperator(clang::BinaryOperator *expr) { } bool Converter::IsReferenceType(const clang::Expr *expr) const { - const auto *e = expr->IgnoreCasts(); + const auto *e = IgnoreStdMove(expr->IgnoreCasts())->IgnoreCasts(); if (const auto *call = clang::dyn_cast(e)) { return !clang::isa(call) && GetReturnTypeOfFunction(call)->isReferenceType(); @@ -3198,6 +3225,27 @@ bool Converter::VisitCXXThisExpr(clang::CXXThisExpr *expr) { return false; } +bool Converter::VisitOpaqueValueExpr(clang::OpaqueValueExpr *expr) { + Convert(expr->getSourceExpr()); + return false; +} + +bool Converter::VisitArrayInitIndexExpr(clang::ArrayInitIndexExpr *expr) { + StrCat("__i"); + computed_expr_type_ = ComputedExprType::FreshValue; + return false; +} + +bool Converter::VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr *expr) { + StrCat(std::format("std::array::from_fn::<_, {}, _>", + GetArraySize(expr->getType()))); + PushParen paren(*this); + StrCat("|__i: usize|"); + ConvertVarInit(expr->getSubExpr()->getType(), expr->getSubExpr()); + computed_expr_type_ = ComputedExprType::FreshValue; + return false; +} + bool Converter::VisitInitListExpr(clang::InitListExpr *expr) { if (auto form = expr->getSemanticForm()) expr = form; @@ -3467,16 +3515,6 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { } auto *ctor = expr->getConstructor(); - // Default move is translated using a bitwise .clone() implementation. - // Bitwise clone is only satisfied by default copy constructor. If the copy - // constructor is user defined, then default move calls copy constructor, - // which is wrong. - if (IsDefaultedMoveConstructor(ctor) && - !HasDefaultedCopyConstructor(ctor->getParent())) { - llvm::report_fatal_error("defaulted move constructor without a fieldwise " - "copy constructor is not supported"); - } - if (IsPassThroughConstructor(ctor)) { // Take suppress before recursing into the child. bool suppress = PushSuppressIteratorClone::take(*this); @@ -3496,7 +3534,6 @@ bool Converter::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { return false; } - assert(ctor->isUserProvided()); if (expr->getType()->isArrayType()) { ConvertArrayCXXConstructExpr(expr); } else { @@ -3908,6 +3945,10 @@ std::string Converter::ConvertVarDefaultInit(clang::QualType qual_type) { std::string Converter::GetOverloadedFunctionName(const clang::FunctionDecl *decl) { auto name = GetFunctionBaseName(decl); + if (auto *ctor = clang::dyn_cast(decl); + ctor && !ctor->getParent()->getIdentifier()) { + name = GetRecordName(ctor->getParent()); + } if (decl->getNumParams() != 0U) { name += '_'; @@ -4440,15 +4481,8 @@ void Converter::AddDefaultTrait(const clang::RecordDecl *decl) { if (auto *default_ctor = GetUserDefinedDefaultConstructor(cxx)) { StrCat(keyword_unsafe_); PushBrace unsafe_brace(*this); - Convert(clang::CXXConstructExpr::Create( - ctx_, ctx_.getCanonicalTagType(decl), clang::SourceLocation(), - default_ctor, - /*Elidable=*/false, llvm::ArrayRef(), - /*HadMultipleCandidates=*/false, - /*ListInitialization=*/false, - /*StdInitListInitialization=*/false, - /*ZeroInitialization=*/false, clang::CXXConstructionKind::Complete, - clang::SourceRange())); + Convert(MakeConstructExpr(ctx_, ctx_.getCanonicalTagType(decl), + default_ctor, {})); return; } } @@ -4683,7 +4717,24 @@ std::string Converter::ConvertPlaceholder(clang::Expr *expr, clang::Expr *arg, if (clang::isa(arg)) { return ConvertRValue(arg); } - return std::format("std::mem::take(&mut {})", ConvertLValue(arg)); + if (auto *record = arg->getType()->getAsCXXRecordDecl(); + record && IsUserDefinedDecl(record)) { + for (auto *ctor : record->ctors()) { + if (!IsConvertibleMoveConstructor(ctor)) { + continue; + } + Buffer buf(*this); + Convert(MakeConstructExpr(ctx_, arg->getType(), ctor, arg)); + return std::move(buf).str(); + } + if (TypeIsCopyable(arg->getType())) { + return ConvertRValue(arg); + } + return ConvertFreshRValue(arg); + } + auto lvalue = ConvertLValue(arg); + SetFresh(); + return std::format("std::mem::take(&mut {})", std::move(lvalue)); } if (ph_ctx.access == TranslationRule::Access::kMove) { diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index c4bab0e4..0dad2fe7 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -331,6 +331,8 @@ class Converter : public clang::RecursiveASTVisitor { virtual void ConvertVariadicArg(clang::Expr *arg); + void DefineImplicitMembers(clang::CXXRecordDecl *decl); + virtual bool VisitCallExpr(clang::CallExpr *expr); virtual bool VisitIntegerLiteral(clang::IntegerLiteral *expr); @@ -384,6 +386,9 @@ class Converter : public clang::RecursiveASTVisitor { virtual bool VisitCXXThisExpr(clang::CXXThisExpr *expr); virtual bool VisitInitListExpr(clang::InitListExpr *expr); + bool VisitOpaqueValueExpr(clang::OpaqueValueExpr *expr); + bool VisitArrayInitIndexExpr(clang::ArrayInitIndexExpr *expr); + virtual bool VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr *expr); virtual bool VisitCompoundLiteralExpr(clang::CompoundLiteralExpr *expr); @@ -1003,8 +1008,8 @@ class Converter : public clang::RecursiveASTVisitor { virtual bool emplace_back_plugin_convert(clang::CallExpr *call); virtual void emplace_back_plugin_construct_arg(clang::QualType elem_type, clang::CXXConstructExpr *ctor); - virtual void emplace_back_emit_push_open(clang::CXXMemberCallExpr *call); - virtual void emplace_back_emit_push_close(clang::CXXMemberCallExpr *call); + virtual void emplace_back_emit_push(clang::CXXMemberCallExpr *call, + std::string_view arg); virtual const char *GetPointerDerefPrefix(clang::QualType pointee_type); diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 7a031734..431cbb76 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -286,14 +286,38 @@ bool IsUserDefinedCopyConstructor(const clang::CXXConstructorDecl *ctor) { IsUserDefinedDecl(ctor); } -bool IsUserDefinedMoveConstructor(const clang::CXXConstructorDecl *ctor) { - return ctor->isMoveConstructor() && ctor->isUserProvided() && - IsUserDefinedDecl(ctor); +bool IsConvertibleCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor) { + return IsUserDefinedCopyConstructor(ctor) || + IsConvertibleMoveConstructor(ctor); } -bool IsUserDefinedCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor) { - return IsUserDefinedCopyConstructor(ctor) || - IsUserDefinedMoveConstructor(ctor); +static bool +IsConvertibleImplicitMemberParent(const clang::CXXRecordDecl *decl) { + return IsUserDefinedDecl(decl) && !decl->isAbstract() && + decl->getNumBases() == 0; +} + +bool IsConvertibleMoveConstructor(const clang::CXXConstructorDecl *ctor) { + return ctor->isMoveConstructor() && !ctor->isDeleted() && + IsConvertibleImplicitMemberParent(ctor->getParent()) && + (ctor->isUserProvided() || + !HasDefaultedCopyConstructor(ctor->getParent())) && + ctor->hasBody(); +} + +bool IsConvertibleMoveAssignment(const clang::CXXMethodDecl *method) { + return method->isMoveAssignmentOperator() && !method->isDeleted() && + IsConvertibleImplicitMemberParent(method->getParent()) && + (method->isUserProvided() || + !HasDefaultedCopyAssignment(method->getParent())) && + method->hasBody(); +} + +bool IsConvertibleImplicitMember(const clang::CXXMethodDecl *method) { + if (auto *ctor = clang::dyn_cast(method)) { + return IsConvertibleMoveConstructor(ctor); + } + return IsConvertibleMoveAssignment(method); } bool IsDefaultedMoveConstructor(const clang::CXXConstructorDecl *ctor) { @@ -328,6 +352,19 @@ bool HasDefaultedCopyConstructor(const clang::RecordDecl *decl) { return !cxx->defaultedCopyConstructorIsDeleted(); } +bool HasDefaultedCopyAssignment(const clang::RecordDecl *decl) { + auto *cxx = clang::dyn_cast(decl); + if (!cxx) { + return true; + } + for (const auto *method : cxx->methods()) { + if (method->isCopyAssignmentOperator()) { + return !method->isUserProvided() && !method->isDeleted(); + } + } + return true; +} + bool HasCallableCopyConstructor(const clang::RecordDecl *decl) { auto *cxx = clang::dyn_cast(decl); if (!cxx) { @@ -352,7 +389,7 @@ bool IsRValueConvertingConstructor(const clang::CXXConstructorDecl *ctor) { } bool IsPassThroughConstructor(const clang::CXXConstructorDecl *ctor) { - return !IsUserDefinedCopyOrMoveConstructor(ctor) && + return !IsConvertibleCopyOrMoveConstructor(ctor) && (ctor->isCopyOrMoveConstructor() || IsRValueConvertingConstructor(ctor)); } @@ -375,7 +412,8 @@ bool IsConvertibleCXXMethodDecl(const clang::CXXMethodDecl *decl) { if (llvm::isa(decl)) { return GetUserDefinedDestructor(decl->getParent()) != nullptr; } - return !decl->isImplicit() || IsComparisonOperator(decl); + return !decl->isImplicit() || IsComparisonOperator(decl) || + IsConvertibleImplicitMember(decl); } bool IsConvertibleFunctionDecl(const clang::FunctionDecl *decl) { @@ -805,6 +843,22 @@ bool IsSameTypeComparison(const clang::FunctionDecl *fn, is_record(fn->getParamDecl(1)->getType()); } +bool IsImplicitAssignmentCall(const clang::CallExpr *expr) { + const auto *call = clang::dyn_cast(expr); + if (!call) { + return false; + } + const auto *method = call->getMethodDecl(); + if (!method || !(method->isCopyAssignmentOperator() || + method->isMoveAssignmentOperator())) { + return false; + } + if (method->isUserProvided() && IsUserDefinedDecl(method)) { + return false; + } + return !IsConvertibleMoveAssignment(method); +} + bool IsUserOperatorCall(const clang::CXXOperatorCallExpr *expr) { const auto *callee = expr->getDirectCallee(); if (!callee) { @@ -814,6 +868,10 @@ bool IsUserOperatorCall(const clang::CXXOperatorCallExpr *expr) { method && method->isDefaulted() && IsComparisonOperator(method)) { return IsUserDefinedDecl(method->getParent()); } + if (const auto *method = clang::dyn_cast(callee); + method && IsConvertibleMoveAssignment(method)) { + return true; + } if (!callee->isUserProvided() || !IsUserDefinedDecl(callee)) { return false; } @@ -904,6 +962,9 @@ bool IsEmittableMethod(clang::CXXMethodDecl *method) { if (IsComparisonOperator(method)) { return method->hasBody(); } + if (IsConvertibleImplicitMember(method)) { + return method->hasBody(); + } // Compiler-generated members are covered by derived traits if (method->isImplicit()) { return false; @@ -921,6 +982,9 @@ bool IsMethodOnPtr(const clang::CXXMethodDecl *method) { clang::isa(method)) { return false; } + if (IsConvertibleImplicitMember(method)) { + return method->hasBody(); + } if (method->isImplicit() && !IsComparisonOperator(method)) { return false; } @@ -946,6 +1010,20 @@ clang::Expr *ToAddrOf(clang::ASTContext &ctx, clang::Expr *expr) { {}); } +clang::CXXConstructExpr *MakeConstructExpr(clang::ASTContext &ctx, + clang::QualType type, + clang::CXXConstructorDecl *ctor, + llvm::ArrayRef args) { + return clang::CXXConstructExpr::Create( + ctx, type, clang::SourceLocation(), ctor, + /*Elidable=*/false, args, + /*HadMultipleCandidates=*/false, + /*ListInitialization=*/false, + /*StdInitListInitialization=*/false, + /*ZeroInitialization=*/false, clang::CXXConstructionKind::Complete, + clang::SourceRange()); +} + std::vector GetNestedStructs(const clang::CXXRecordDecl *decl) { std::vector nested_record_decls; @@ -1310,6 +1388,23 @@ bool IsBuiltinVaCopy(const clang::CallExpr *expr) { return false; } +const clang::Expr *IgnoreStdMove(const clang::Expr *expr) { + if (const auto *call = + clang::dyn_cast(expr->IgnoreParenImpCasts()); + call && call->isCallToStdMove()) { + return call->getArg(0); + } + return expr; +} + +bool IsTemporaryObject(const clang::Expr *expr) { + const auto *operand = IgnoreStdMove(expr); + if (operand != expr) { + return !operand->isGLValue(); + } + return !expr->isLValue(); +} + bool ContainsVAArgExpr(const clang::Stmt *stmt) { if (clang::isa(stmt)) { return true; diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index df20998c..709940a7 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -70,12 +70,16 @@ bool IsOverloadedMethod(const clang::CXXMethodDecl *decl); bool IsUserDefinedCopyConstructor(const clang::CXXConstructorDecl *ctor); -bool IsUserDefinedMoveConstructor(const clang::CXXConstructorDecl *ctor); - -bool IsUserDefinedCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor); +bool IsConvertibleCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor); bool IsDefaultedMoveConstructor(const clang::CXXConstructorDecl *ctor); +bool IsConvertibleMoveConstructor(const clang::CXXConstructorDecl *ctor); + +bool IsConvertibleMoveAssignment(const clang::CXXMethodDecl *method); + +bool IsConvertibleImplicitMember(const clang::CXXMethodDecl *method); + clang::CXXConstructorDecl * GetUserDefinedCopyConstructor(const clang::RecordDecl *decl); @@ -83,6 +87,8 @@ bool HasCallableCopyConstructor(const clang::RecordDecl *decl); bool HasDefaultedCopyConstructor(const clang::RecordDecl *decl); +bool HasDefaultedCopyAssignment(const clang::RecordDecl *decl); + bool IsRValueConvertingConstructor(const clang::CXXConstructorDecl *ctor); bool IsPassThroughConstructor(const clang::CXXConstructorDecl *ctor); @@ -149,6 +155,7 @@ const char *GetOverloadedOperator(const clang::FunctionDecl *decl); std::string GetFunctionBaseName(const clang::FunctionDecl *decl); +bool IsImplicitAssignmentCall(const clang::CallExpr *expr); bool IsUserOperatorCall(const clang::CXXOperatorCallExpr *expr); bool IsSameTypeComparison(const clang::FunctionDecl *fn, @@ -165,6 +172,11 @@ bool RecordNeedsDestruction(const clang::CXXRecordDecl *decl); clang::Expr *ToAddrOf(clang::ASTContext &ctx, clang::Expr *expr); +clang::CXXConstructExpr *MakeConstructExpr(clang::ASTContext &ctx, + clang::QualType type, + clang::CXXConstructorDecl *ctor, + llvm::ArrayRef args); + std::vector GetNestedStructs(const clang::CXXRecordDecl *decl); @@ -240,6 +252,10 @@ bool IsBuiltinVaEnd(const clang::CallExpr *expr); bool IsBuiltinVaCopy(const clang::CallExpr *expr); +const clang::Expr *IgnoreStdMove(const clang::Expr *expr); + +bool IsTemporaryObject(const clang::Expr *expr); + bool ContainsVAArgExpr(const clang::Stmt *stmt); clang::Expr *NormalizeToBool(clang::Expr *expr, clang::ASTContext &ctx); diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index 8b6b7a19..7fd10b85 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -1067,6 +1067,12 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) { return false; } + if (IsImplicitAssignmentCall(expr) && !Mapper::Contains(expr->getCallee())) { + auto *call = clang::cast(expr); + ConvertAssignment(call->getImplicitObjectArgument(), call->getArg(0), "="); + return false; + } + if (expr->isCallToStdMove()) { return Converter::VisitCallExpr(expr); } @@ -1869,6 +1875,13 @@ bool ConverterRefCount::VisitCXXForRangeStmtString( return false; } +bool ConverterRefCount::VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr *expr) { + StrCat("Box::new"); + PushParen outer(*this); + PushConversionKind push(*this, ConversionKind::Unboxed); + return Converter::VisitArrayInitLoopExpr(expr); +} + void ConverterRefCount::ConvertArrayCXXConstructExpr( clang::CXXConstructExpr *expr) { StrCat("Box::new"); @@ -1910,17 +1923,8 @@ bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { return false; } - // Default move is translated using a bitwise .clone() implementation. - // Bitwise clone is only satisfied by default copy constructor. If the copy - // constructor is user defined, then default move calls copy constructor, - // which is wrong. - if (IsDefaultedMoveConstructor(ctor) && - !HasDefaultedCopyConstructor(ctor->getParent())) { - llvm::report_fatal_error("defaulted move constructor without a fieldwise " - "copy constructor is not supported"); - } if (ctor->isCopyOrMoveConstructor() && - !IsUserDefinedCopyOrMoveConstructor(ctor)) { + !IsConvertibleCopyOrMoveConstructor(ctor)) { StrCat(PushSuppressIteratorClone::take(*this) ? ConvertRValue(expr->getArg(0)) : ConvertFreshRValue(expr->getArg(0))); @@ -1934,7 +1938,6 @@ bool ConverterRefCount::VisitCXXConstructExpr(clang::CXXConstructExpr *expr) { return false; } - assert(ctor->isUserProvided()); if (expr->getType()->isArrayType()) { ConvertArrayCXXConstructExpr(expr); } else { @@ -2536,20 +2539,18 @@ void ConverterRefCount::emplace_back_plugin_construct_arg( ConvertVarInit(elem_type, ctor); } -void ConverterRefCount::emplace_back_emit_push_open( - clang::CXXMemberCallExpr *call) { +void ConverterRefCount::emplace_back_emit_push(clang::CXXMemberCallExpr *call, + std::string_view arg) { auto *obj = GetCallObject(call); auto obj_type = obj->getType().getNonReferenceType(); if (obj_type->isPointerType()) { obj_type = obj_type->getPointeeType(); } - StrCat(ConvertObject(obj), ".with_mut(|__v: &mut ", - ToString(obj_type.getNonReferenceType()), "| __v.push("); -} - -void ConverterRefCount::emplace_back_emit_push_close( - clang::CXXMemberCallExpr *call) { - StrCat("))"); + StrCat(ConvertObject(obj), ".with_mut"); + PushParen outer(*this); + StrCat("|__v: &mut ", ToString(obj_type.getNonReferenceType()), "| __v.push"); + PushParen inner(*this); + StrCat(arg); } const char * @@ -2692,7 +2693,7 @@ void ConverterRefCount::SetUFCSReceiver(clang::Expr *base, bool is_arrow, } return; } - if (!base->isLValue() && base->getType()->isRecordType() && + if (IsTemporaryObject(base) && base->getType()->isRecordType() && !IsReferenceType(base->IgnoreImplicit())) { PushConversionKind push(*this, ConversionKind::FullRefCount); ufcs_receiver_ = diff --git a/cpp2rust/converter/models/converter_refcount.h b/cpp2rust/converter/models/converter_refcount.h index f588f6d1..0dce5d24 100644 --- a/cpp2rust/converter/models/converter_refcount.h +++ b/cpp2rust/converter/models/converter_refcount.h @@ -123,6 +123,7 @@ class ConverterRefCount final : public Converter { void EmitStmtExprTail(clang::Expr *tail) override; bool VisitInitListExpr(clang::InitListExpr *expr) override; + bool VisitArrayInitLoopExpr(clang::ArrayInitLoopExpr *expr) override; bool VisitArraySubscriptExpr(clang::ArraySubscriptExpr *expr) override; @@ -243,8 +244,8 @@ class ConverterRefCount final : public Converter { void emplace_back_plugin_construct_arg(clang::QualType elem_type, clang::CXXConstructExpr *ctor) override; - void emplace_back_emit_push_open(clang::CXXMemberCallExpr *call) override; - void emplace_back_emit_push_close(clang::CXXMemberCallExpr *call) override; + void emplace_back_emit_push(clang::CXXMemberCallExpr *call, + std::string_view arg) override; const char *GetPointerDerefSuffix(clang::QualType pointee_type); const char *GetPointerDerefPrefix(clang::QualType pointee_type) override; diff --git a/cpp2rust/converter/plugins/emplace_back.cpp b/cpp2rust/converter/plugins/emplace_back.cpp index c7e6e1e8..f766ea95 100644 --- a/cpp2rust/converter/plugins/emplace_back.cpp +++ b/cpp2rust/converter/plugins/emplace_back.cpp @@ -3,6 +3,8 @@ #include +#include + #include "converter/converter_lib.h" #include "converter/mapper.h" #include "converter/models/converter_refcount.h" @@ -134,18 +136,16 @@ clang::CXXConstructExpr *buildConstructExpr(clang::CXXMemberCallExpr *call, } // namespace -void Converter::emplace_back_emit_push_open(clang::CXXMemberCallExpr *call) { +void Converter::emplace_back_emit_push(clang::CXXMemberCallExpr *call, + std::string_view arg) { { PushExprKind push(*this, ExprKind::LValue); auto callee = ToString(call->getCallee()); ReplaceAll(callee, "emplace_back", "push"); StrCat(callee); } - StrCat('('); -} - -void Converter::emplace_back_emit_push_close(clang::CXXMemberCallExpr *call) { - StrCat(')'); + PushParen paren(*this); + StrCat(arg); } bool Converter::emplace_back_plugin_convert(clang::CallExpr *call) { @@ -155,41 +155,41 @@ bool Converter::emplace_back_plugin_convert(clang::CallExpr *call) { auto [elem_ty, ctor] = analyzeEmplaceCall(member_call, GetSema()); assert(!elem_ty.isNull() && "Could not analyze emplace_back type"); - emplace_back_emit_push_open(member_call); - - if (ctor) { - auto is_argument_moved = false; - if (call->getNumArgs() > 0) { - if (auto arg_call = clang::dyn_cast(call->getArg(0))) { - is_argument_moved = arg_call->isCallToStdMove(); + std::string arg; + { + Buffer buf(*this); + if (ctor) { + emplace_back_plugin_construct_arg( + elem_ty, buildConstructExpr(member_call, GetSema())); + } else if (elem_ty.isPODType(ctx_)) { + if (call->getNumArgs() == 0) { + StrCat(GetDefaultAsString(elem_ty)); + } else { + assert(call->getNumArgs() == 1 && + "multiple arguments passed for building POD type"); + Convert(call->getArg(0)); + StrCat("as"); + StrCat(GetUnsafeTypeAsString(elem_ty)); } - } - - if (is_argument_moved) { - StrCat("std::mem::take(&mut"); - } - emplace_back_plugin_construct_arg( - elem_ty, buildConstructExpr(member_call, GetSema())); - if (is_argument_moved) { - StrCat(')'); - } - } else if (elem_ty.isPODType(ctx_)) { - if (call->getNumArgs() == 0) { - StrCat(GetDefaultAsString(elem_ty)); } else { - assert(call->getNumArgs() == 1 && - "multiple arguments passed for building POD type"); - Convert(call->getArg(0)); - StrCat("as"); - StrCat(GetUnsafeTypeAsString(elem_ty)); + call->dump(); + assert(0 && "no ctor and no pod type"); + return false; } - } else { - call->dump(); - assert(0 && "no ctor and no pod type"); - return false; + arg = std::move(buf).str(); } - emplace_back_emit_push_close(member_call); + auto *obj = GetCallObject(member_call); + bool hoist = + std::any_of(call->arg_begin(), call->arg_end(), [obj](auto *call_arg) { + return MayCauseBorrowMutError(obj, call_arg); + }); + PushBrace brace(*this, hoist); + if (hoist) { + StrCat("let __arg = ", arg, ";"); + arg = "__arg"; + } + emplace_back_emit_push(member_call, arg); return true; } diff --git a/rules/vector/src.cpp b/rules/vector/src.cpp index 73cb285f..43e3385c 100644 --- a/rules/vector/src.cpp +++ b/rules/vector/src.cpp @@ -545,3 +545,9 @@ template > std::vector f110(const std::vector &o) { return std::vector(o); } + +template +std::vector> &f111(std::vector> &dst, + std::vector> &&src) { + return dst.operator=(std::move(src)); +} diff --git a/rules/vector/tgt_refcount.rs b/rules/vector/tgt_refcount.rs index 59165d22..f3b8caa1 100644 --- a/rules/vector/tgt_refcount.rs +++ b/rules/vector/tgt_refcount.rs @@ -361,3 +361,7 @@ fn f104(a0: Ptr) -> Ptr { fn f105(a0: Ptr>, a1: Vec) { a0.write(a1) } + +fn f111(a0: Ptr>>>, a1: &mut Vec>>) { + a0.write(std::mem::take(&mut *a1)) +} diff --git a/rules/vector/tgt_unsafe.rs b/rules/vector/tgt_unsafe.rs index c4277a7d..953a16c1 100644 --- a/rules/vector/tgt_unsafe.rs +++ b/rules/vector/tgt_unsafe.rs @@ -489,3 +489,7 @@ unsafe fn f109(a0: Vec) -> Vec { unsafe fn f110(a0: Vec) -> Vec { a0.clone() } + +unsafe fn f111(a0: &mut Vec>, a1: &mut Vec>) { + *a0 = std::mem::take(&mut *a1) +} diff --git a/tests/multi-file/defaulted_move_cross_tu/CMakeLists.txt b/tests/multi-file/defaulted_move_cross_tu/CMakeLists.txt new file mode 100644 index 00000000..504c2af0 --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/CMakeLists.txt @@ -0,0 +1,3 @@ +cmake_minimum_required(VERSION 3.16) +project(defaulted_move_cross_tu LANGUAGES CXX) +add_executable(app a.cpp b.cpp) diff --git a/tests/multi-file/defaulted_move_cross_tu/a.cpp b/tests/multi-file/defaulted_move_cross_tu/a.cpp new file mode 100644 index 00000000..3ef5d1a8 --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/a.cpp @@ -0,0 +1,12 @@ +#include + +#include "s.h" + +int sum(const S &s) { return static_cast(s.v.size()) + s.n[0] + s.n[1]; } + +int main() { + S s(2); + assert(sum(s) == 7); + assert(shuffle(3) == 10); + return 0; +} diff --git a/tests/multi-file/defaulted_move_cross_tu/b.cpp b/tests/multi-file/defaulted_move_cross_tu/b.cpp new file mode 100644 index 00000000..193cd0f0 --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/b.cpp @@ -0,0 +1,14 @@ +#include +#include + +#include "s.h" + +int shuffle(int x) { + S a(x); + S b(std::move(a)); + assert(a.v.empty()); + S c(1); + c = std::move(b); + assert(b.v.empty()); + return sum(c); +} diff --git a/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs b/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs new file mode 100644 index 00000000..6c54b789 --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/out/refcount/defaulted_move_cross_tu.rs @@ -0,0 +1,112 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive()] +pub struct S { + pub v: Value>, + pub n: Value>, +} +impl S { + pub fn S(x: i32) -> Self { + let x: Value = Rc::new(RefCell::new(x)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(vec![ + (*x.borrow()); + ((*x.borrow()) as usize) as usize + ])), + n: Rc::new(RefCell::new(Box::new([(*x.borrow()), ((*x.borrow()) + 1)]))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn S_pmutS(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(std::mem::take( + &mut (*(*_a0.upgrade().deref()).v.borrow_mut()), + ))), + n: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 2, _>( + |__i: usize| (*(*_a0.upgrade().deref()).n.borrow())[(__i) as usize], + )))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for S { + fn default() -> Self { + S { + v: Rc::new(RefCell::new(Default::default())), + n: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for S { + fn byte_size() -> usize { + 32 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..24]); + (*self.n.borrow()).to_bytes(&mut buf[24..32]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + n: Rc::new(RefCell::new(>::from_bytes(&buf[24..32]))), + } + } +} +pub fn sum_0(s: Ptr) -> i32 { + return { + let _lhs = { + let _lhs = ((*(*s.upgrade().deref()).v.borrow()).len() as i32); + _lhs + (*(*s.upgrade().deref()).n.borrow())[(0) as usize] + }; + _lhs + (*(*s.upgrade().deref()).n.borrow())[(1) as usize] + }; +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let s: Value = Rc::new(RefCell::new(S::S({ 2 }))); + assert!((({ sum_0(s.as_pointer(),) }) == 7)); + assert!((({ shuffle_1(3,) }) == 10)); + return 0; +} +pub fn shuffle_1(x: i32) -> i32 { + let x: Value = Rc::new(RefCell::new(x)); + let a: Value = Rc::new(RefCell::new(S::S({ (*x.borrow()) }))); + let b: Value = Rc::new(RefCell::new(S::S_pmutS({ a.as_pointer() }))); + assert!((*(*a.borrow()).v.borrow()).is_empty()); + let c: Value = Rc::new(RefCell::new(S::S({ 1 }))); + ({ SImpl::operator_assign_pmutS(&c.as_pointer(), b.as_pointer()) }); + assert!((*(*b.borrow()).v.borrow()).is_empty()); + return ({ sum_0(c.as_pointer()) }); +} +pub trait SImpl { + fn operator_assign_pmutS(&self, _a0: Ptr) -> Ptr; +} +impl SImpl for Ptr { + fn operator_assign_pmutS(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).v.as_pointer() as Ptr>).write(std::mem::take( + &mut (*(*_a0.upgrade().deref()).v.borrow_mut()), + )); + { + (((*(*self).upgrade().deref()).n.as_pointer()) as Ptr) + .to_any() + .memcpy( + &(((*_a0.upgrade().deref()).n.as_pointer()) as Ptr).to_any(), + 8_usize as usize, + ); + (((*(*self).upgrade().deref()).n.as_pointer()) as Ptr).to_any() + }; + return (*self).clone(); + } +} diff --git a/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs b/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs new file mode 100644 index 00000000..726421dc --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/out/unsafe/defaulted_move_cross_tu.rs @@ -0,0 +1,75 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive()] +pub struct S { + pub v: Vec, + pub n: [i32; 2], +} +impl S { + pub unsafe fn S(mut x: i32) -> Self { + let mut this = Self { + v: vec![x; (x as usize) as usize], + n: [x, ((x) + (1))], + }; + this + } + pub unsafe fn S_pmutS(_a0: *mut S) -> Self { + let mut this = Self { + v: std::mem::take(&mut (*_a0).v), + n: std::array::from_fn::<_, 2, _>(|__i: usize| (*_a0).n[(__i)]), + }; + this + } + pub unsafe fn operator_assign_pmutS(&mut self, _a0: *mut S) -> *mut S { + self.v = std::mem::take(&mut (*_a0).v); + { + if 8_usize != 0 { + ::std::ptr::copy_nonoverlapping( + ((&mut (*_a0).n as *mut [i32; 2]) as *const [i32; 2] as *const ::libc::c_void), + ((&mut self.n as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void), + 8_usize as usize, + ) + } + ((&mut self.n as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void) + }; + return &mut (*(self as *mut S)); + } +} +impl Default for S { + fn default() -> Self { + S { + v: Default::default(), + n: [0_i32; 2], + } + } +} +pub unsafe fn sum_0(s: *const S) -> i32 { + return ((((*s).v.len() as i32) + ((*s).n[(0) as usize])) + ((*s).n[(1) as usize])); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut s: S = S::S({ 2 }); + assert!(((unsafe { sum_0(&s,) }) == (7))); + assert!(((unsafe { shuffle_1(3,) }) == (10))); + return 0; +} +pub unsafe fn shuffle_1(mut x: i32) -> i32 { + let mut a: S = S::S({ x }); + let mut b: S = S::S_pmutS({ &mut a }); + assert!(a.v.is_empty()); + let mut c: S = S::S({ 1 }); + (unsafe { S::operator_assign_pmutS(&mut c, &mut b) }); + assert!(b.v.is_empty()); + return (unsafe { sum_0(&c) }); +} diff --git a/tests/multi-file/defaulted_move_cross_tu/s.h b/tests/multi-file/defaulted_move_cross_tu/s.h new file mode 100644 index 00000000..99c1e417 --- /dev/null +++ b/tests/multi-file/defaulted_move_cross_tu/s.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +struct S { + std::vector v; + int n[2]; + + S(int x) : v(x, x), n{x, x + 1} {} + S(const S &) = delete; + S(S &&) = default; + S &operator=(const S &) = delete; + S &operator=(S &&) = default; +}; + +int sum(const S &s); +int shuffle(int x); diff --git a/tests/unit/copy_move_defaulted.cpp b/tests/unit/copy_move_defaulted.cpp index 8452357c..45e0acac 100644 --- a/tests/unit/copy_move_defaulted.cpp +++ b/tests/unit/copy_move_defaulted.cpp @@ -1,5 +1,5 @@ -// translation-fail #include +#include #include #include @@ -50,6 +50,32 @@ struct UserCopyDefaultMove { UserCopyDefaultMove &operator=(UserCopyDefaultMove &&) = default; }; +struct Buffer { + std::vector data; + std::vector> rows; + int n; + int arr[2]; + Buffer(int n) : data(n, n), n(n), arr{n, n + 1} { rows.push_back(data); } + Buffer(const Buffer &) = delete; + Buffer(Buffer &&) = default; + Buffer &operator=(const Buffer &) = delete; + Buffer &operator=(Buffer &&) = default; +}; + +struct Owner { + std::vector data; + int n; + int arr[2]; + std::unique_ptr p; +}; + +struct Holder { + Inner inner; + Explicit e; + std::unique_ptr p; + Holder(int v) : inner{v}, e(v) {} +}; + static bool same(const Explicit &a, const Explicit &b) { return a.v == b.v && a.inner.x == b.inner.x && a.arr[0] == b.arr[0] && a.arr[1] == b.arr[1]; @@ -101,5 +127,40 @@ int main() { u3 = u2; u4 = std::move(u2); assert(u3.v == 108 && u4.v == 8); + + Buffer p(3); + Buffer q = std::move(p); + assert(q.n == 3 && q.data.size() == 3 && q.data[2] == 3 && p.data.empty()); + Buffer r(1); + r = std::move(q); + assert(r.n == 3 && r.data.size() == 3 && r.arr[1] == 4 && q.data.empty()); + assert(r.rows.size() == 1 && r.rows[0].size() == 3 && q.rows.empty()); + std::vector bufs; + bufs.push_back(std::move(r)); + bufs.emplace_back(std::move(bufs[0])); + assert(bufs[1].n == 3 && bufs[1].data.size() == 3 && bufs[0].data.empty()); + + Owner o1; + o1.data.push_back(5); + o1.n = 5; + o1.arr[0] = 5; + o1.arr[1] = 6; + o1.p.reset(new int(7)); + Owner o2 = std::move(o1); + assert(o2.n == 5 && o2.data.size() == 1 && o2.arr[1] == 6 && *o2.p == 7); + assert(o1.data.empty() && o1.p.get() == nullptr); + Owner o3; + o3 = std::move(o2); + assert(o3.n == 5 && o3.data[0] == 5 && o3.arr[0] == 5 && *o3.p == 7); + assert(o2.data.empty() && o2.p.get() == nullptr); + + Holder h1(4); + h1.p.reset(new int(9)); + Holder h2 = std::move(h1); + assert(h2.inner.x == 4 && h2.e.v == 4 && *h2.p == 9 && h1.p.get() == nullptr); + Holder h3(1); + h3 = std::move(h2); + assert(h3.inner.x == 4 && h3.e.arr[1] == 5 && *h3.p == 9 && + h2.p.get() == nullptr); return 0; } diff --git a/tests/unit/copy_move_deleted.cpp b/tests/unit/copy_move_deleted.cpp index c635eb03..4f7eabed 100644 --- a/tests/unit/copy_move_deleted.cpp +++ b/tests/unit/copy_move_deleted.cpp @@ -1,4 +1,3 @@ -// translation-fail #include #include diff --git a/tests/unit/out/refcount/clone_vs_move.rs b/tests/unit/out/refcount/clone_vs_move.rs index c3819e4e..7b51f17b 100644 --- a/tests/unit/out/refcount/clone_vs_move.rs +++ b/tests/unit/out/refcount/clone_vs_move.rs @@ -46,7 +46,9 @@ impl Clone for Foo { x: Rc::new(RefCell::new((*self.x.borrow()))), y: (self.y).clone(), z: Rc::new(RefCell::new((*self.z.borrow()).clone())), - a: Rc::new(RefCell::new((*self.a.borrow()).clone())), + a: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 3, _>( + |__i: usize| (*self.a.borrow())[(__i) as usize], + )))), bar: Rc::new(RefCell::new((*self.bar.borrow()).clone())), })); let this: Ptr = __this.as_pointer(); diff --git a/tests/unit/out/refcount/copy_assign.rs b/tests/unit/out/refcount/copy_assign.rs index 1eec39b5..5708fcb5 100644 --- a/tests/unit/out/refcount/copy_assign.rs +++ b/tests/unit/out/refcount/copy_assign.rs @@ -149,7 +149,13 @@ impl Clone for Holder { p: Rc::new(RefCell::new(Partial::Partial_pconstPartial({ self.p.as_pointer() }))), - arr: Rc::new(RefCell::new((*self.arr.borrow()).clone())), + arr: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 2, _>( + |__i: usize| { + Partial::Partial_pconstPartial({ + (self.arr.as_pointer() as Ptr).offset(__i) + }) + }, + )))), })); let this: Ptr = __this.as_pointer(); Rc::try_unwrap(__this).ok().unwrap().into_inner() diff --git a/tests/unit/out/refcount/copy_ctor.rs b/tests/unit/out/refcount/copy_ctor.rs index bab142e2..afd3641b 100644 --- a/tests/unit/out/refcount/copy_ctor.rs +++ b/tests/unit/out/refcount/copy_ctor.rs @@ -114,7 +114,13 @@ impl Clone for Holder { c: Rc::new(RefCell::new(Counted::Counted_pconstCounted({ self.c.as_pointer() }))), - arr: Rc::new(RefCell::new((*self.arr.borrow()).clone())), + arr: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 2, _>( + |__i: usize| { + Counted::Counted_pconstCounted({ + (self.arr.as_pointer() as Ptr).offset(__i) + }) + }, + )))), })); let this: Ptr = __this.as_pointer(); Rc::try_unwrap(__this).ok().unwrap().into_inner() diff --git a/tests/unit/out/refcount/copy_move_defaulted.rs b/tests/unit/out/refcount/copy_move_defaulted.rs new file mode 100644 index 00000000..8bdafca3 --- /dev/null +++ b/tests/unit/out/refcount/copy_move_defaulted.rs @@ -0,0 +1,827 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Default)] +pub struct Inner { + pub x: Value, +} +impl Clone for Inner { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + x: Rc::new(RefCell::new((*self.x.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for Inner { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.x.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + x: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive()] +pub struct Explicit { + pub v: Value, + pub inner: Value, + pub arr: Value>, +} +impl Explicit { + pub fn Explicit(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*v.borrow()))), + inner: Rc::new(RefCell::new(Inner { + x: Rc::new(RefCell::new(((*v.borrow()) * 10))), + })), + arr: Rc::new(RefCell::new(Box::new([(*v.borrow()), ((*v.borrow()) + 1)]))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Clone for Explicit { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*self.v.borrow()))), + inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())), + arr: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 2, _>( + |__i: usize| (*self.arr.borrow())[(__i) as usize], + )))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Explicit { + fn default() -> Self { + Explicit { + v: >::default(), + inner: >::default(), + arr: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for Explicit { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + (*self.inner.borrow()).to_bytes(&mut buf[4..8]); + (*self.arr.borrow()).to_bytes(&mut buf[8..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + inner: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + arr: Rc::new(RefCell::new(>::from_bytes(&buf[8..16]))), + } + } +} +#[derive()] +pub struct Implicit { + pub v: Value, + pub inner: Value, + pub arr: Value>, +} +impl Clone for Implicit { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*self.v.borrow()))), + inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())), + arr: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 2, _>( + |__i: usize| (*self.arr.borrow())[(__i) as usize], + )))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Implicit { + fn default() -> Self { + Implicit { + v: >::default(), + inner: >::default(), + arr: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for Implicit { + fn byte_size() -> usize { + 16 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + (*self.inner.borrow()).to_bytes(&mut buf[4..8]); + (*self.arr.borrow()).to_bytes(&mut buf[8..16]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + inner: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + arr: Rc::new(RefCell::new(>::from_bytes(&buf[8..16]))), + } + } +} +#[derive(Default)] +pub struct DefaultCopyUserMove { + pub v: Value, +} +impl DefaultCopyUserMove { + pub fn DefaultCopyUserMove(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn DefaultCopyUserMove_pmutDefaultCopyUserMove(o: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*o.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Clone for DefaultCopyUserMove { + fn clone(&self) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*self.v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for DefaultCopyUserMove { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive(Default)] +pub struct UserCopyDefaultMove { + pub v: Value, +} +impl UserCopyDefaultMove { + pub fn UserCopyDefaultMove(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn UserCopyDefaultMove_pconstUserCopyDefaultMove(o: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(((*(*o.upgrade().deref()).v.borrow()) + 100))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn UserCopyDefaultMove_pmutUserCopyDefaultMove(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Clone for UserCopyDefaultMove { + fn clone(&self) -> Self { + let __src: Value = + Rc::new(RefCell::new(UserCopyDefaultMove { v: self.v.clone() })); + UserCopyDefaultMove::UserCopyDefaultMove_pconstUserCopyDefaultMove(__src.as_pointer()) + } +} +impl ByteRepr for UserCopyDefaultMove { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive()] +pub struct Buffer { + pub data: Value>, + pub rows: Value>>>, + pub n: Value, + pub arr: Value>, +} +impl Buffer { + pub fn Buffer(n: i32) -> Self { + let n: Value = Rc::new(RefCell::new(n)); + let __this: Value = Rc::new(RefCell::new(Self { + data: Rc::new(RefCell::new(vec![ + (*n.borrow()); + ((*n.borrow()) as usize) as usize + ])), + rows: Rc::new(RefCell::new(Vec::new())), + n: Rc::new(RefCell::new((*n.borrow()))), + arr: Rc::new(RefCell::new(Box::new([(*n.borrow()), ((*n.borrow()) + 1)]))), + })); + let this: Ptr = __this.as_pointer(); + ((*this.upgrade().deref()).rows.as_pointer() as Ptr>>>).with_mut( + |__v: &mut Vec>>| { + __v.push(Rc::new(RefCell::new( + (*(*this.upgrade().deref()).data.borrow()).clone(), + ))) + }, + ); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn Buffer_pmutBuffer(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + data: Rc::new(RefCell::new(std::mem::take( + &mut (*(*_a0.upgrade().deref()).data.borrow_mut()), + ))), + rows: Rc::new(RefCell::new(std::mem::take( + &mut (*(*_a0.upgrade().deref()).rows.borrow_mut()), + ))), + n: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).n.borrow()))), + arr: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 2, _>( + |__i: usize| (*(*_a0.upgrade().deref()).arr.borrow())[(__i) as usize], + )))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Buffer { + fn default() -> Self { + Buffer { + data: Rc::new(RefCell::new(Default::default())), + rows: Rc::new(RefCell::new(Vec::new())), + n: >::default(), + arr: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + } + } +} +impl ByteRepr for Buffer { + fn byte_size() -> usize { + 64 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.data.borrow()).to_bytes(&mut buf[0..24]); + (*self.rows.borrow()).to_bytes(&mut buf[24..48]); + (*self.n.borrow()).to_bytes(&mut buf[48..52]); + (*self.arr.borrow()).to_bytes(&mut buf[52..60]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + data: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + rows: Rc::new(RefCell::new(>>>::from_bytes( + &buf[24..48], + ))), + n: Rc::new(RefCell::new(::from_bytes(&buf[48..52]))), + arr: Rc::new(RefCell::new(>::from_bytes(&buf[52..60]))), + } + } +} +#[derive()] +pub struct Owner { + pub data: Value>, + pub n: Value, + pub arr: Value>, + pub p: Value>>, +} +impl Owner { + pub fn Owner_pmutOwner(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + data: Rc::new(RefCell::new(std::mem::take( + &mut (*(*_a0.upgrade().deref()).data.borrow_mut()), + ))), + n: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).n.borrow()))), + arr: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 2, _>( + |__i: usize| (*(*_a0.upgrade().deref()).arr.borrow())[(__i) as usize], + )))), + p: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).p.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Owner { + fn default() -> Self { + Owner { + data: Rc::new(RefCell::new(Default::default())), + n: >::default(), + arr: Rc::new(RefCell::new( + (0..2).map(|_| ::default()).collect::>(), + )), + p: Rc::new(RefCell::new(None)), + } + } +} +impl ByteRepr for Owner { + fn byte_size() -> usize { + 48 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.data.borrow()).to_bytes(&mut buf[0..24]); + (*self.n.borrow()).to_bytes(&mut buf[24..28]); + (*self.arr.borrow()).to_bytes(&mut buf[28..36]); + (*self.p.borrow()).to_bytes(&mut buf[40..48]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + data: Rc::new(RefCell::new(>::from_bytes(&buf[0..24]))), + n: Rc::new(RefCell::new(::from_bytes(&buf[24..28]))), + arr: Rc::new(RefCell::new(>::from_bytes(&buf[28..36]))), + p: Rc::new(RefCell::new(>>::from_bytes(&buf[40..48]))), + } + } +} +#[derive(Default)] +pub struct Holder { + pub inner: Value, + pub e: Value, + pub p: Value>>, +} +impl Holder { + pub fn Holder(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + inner: Rc::new(RefCell::new(Inner { + x: Rc::new(RefCell::new((*v.borrow()))), + })), + e: Rc::new(RefCell::new(Explicit::Explicit({ (*v.borrow()) }))), + p: Rc::new(RefCell::new(None)), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn Holder_pmutHolder(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + inner: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).inner.borrow()).clone(), + )), + e: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).e.borrow()).clone())), + p: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).p.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for Holder { + fn byte_size() -> usize { + 32 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.inner.borrow()).to_bytes(&mut buf[0..4]); + (*self.e.borrow()).to_bytes(&mut buf[4..20]); + (*self.p.borrow()).to_bytes(&mut buf[24..32]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + inner: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + e: Rc::new(RefCell::new(::from_bytes(&buf[4..20]))), + p: Rc::new(RefCell::new(>>::from_bytes(&buf[24..32]))), + } + } +} +pub fn same_0(a: Ptr, b: Ptr) -> bool { + return ((({ + let _lhs = (*(*a.upgrade().deref()).v.borrow()); + _lhs == (*(*b.upgrade().deref()).v.borrow()) + }) && ({ + let _lhs = (*(*(*a.upgrade().deref()).inner.borrow()).x.borrow()); + _lhs == (*(*(*b.upgrade().deref()).inner.borrow()).x.borrow()) + })) && ({ + let _lhs = (*(*a.upgrade().deref()).arr.borrow())[(0) as usize]; + _lhs == (*(*b.upgrade().deref()).arr.borrow())[(0) as usize] + })) && ({ + let _lhs = (*(*a.upgrade().deref()).arr.borrow())[(1) as usize]; + _lhs == (*(*b.upgrade().deref()).arr.borrow())[(1) as usize] + }); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value = Rc::new(RefCell::new(Explicit::Explicit({ 1 }))); + let _dtor_a = ScopedDestructor::new(&a, |__p| __p.destructor()); + let b: Value = Rc::new(RefCell::new((*a.borrow()).clone())); + let _dtor_b = ScopedDestructor::new(&b, |__p| __p.destructor()); + let c: Value = Rc::new(RefCell::new((*a.borrow()).clone())); + let _dtor_c = ScopedDestructor::new(&c, |__p| __p.destructor()); + let d: Value = Rc::new(RefCell::new((*a.borrow()).clone())); + let _dtor_d = ScopedDestructor::new(&d, |__p| __p.destructor()); + assert!( + (({ same_0(b.as_pointer(), a.as_pointer(),) }) + && ({ same_0(c.as_pointer(), a.as_pointer(),) })) + && ({ same_0(d.as_pointer(), a.as_pointer(),) }) + ); + let e: Value = Rc::new(RefCell::new(Explicit::Explicit({ 2 }))); + let _dtor_e = ScopedDestructor::new(&e, |__p| __p.destructor()); + let f: Value = Rc::new(RefCell::new(Explicit::Explicit({ 3 }))); + let _dtor_f = ScopedDestructor::new(&f, |__p| __p.destructor()); + (*e.borrow_mut()) = (*b.borrow()).clone(); + (*f.borrow_mut()) = (*c.borrow()).clone(); + assert!( + ({ same_0(e.as_pointer(), b.as_pointer(),) }) + && ({ same_0(f.as_pointer(), c.as_pointer(),) }) + ); + let g: Value = Rc::new(RefCell::new(Explicit::Explicit({ 4 }))); + let _dtor_g = ScopedDestructor::new(&g, |__p| __p.destructor()); + (*g.borrow_mut()) = { + (*e.borrow_mut()) = (*f.borrow()).clone(); + (*e.borrow()).clone() + }; + assert!( + ({ same_0(g.as_pointer(), f.as_pointer(),) }) + && ({ same_0(e.as_pointer(), f.as_pointer(),) }) + ); + let i: Value = Rc::new(RefCell::new(Implicit { + v: Rc::new(RefCell::new(5)), + inner: Rc::new(RefCell::new(Inner { + x: Rc::new(RefCell::new(50)), + })), + arr: Rc::new(RefCell::new(Box::new([5, 6]))), + })); + let j: Value = Rc::new(RefCell::new((*i.borrow()).clone())); + let k: Value = Rc::new(RefCell::new((*i.borrow()).clone())); + assert!( + (((*(*j.borrow()).v.borrow()) == 5) + && ((*(*(*j.borrow()).inner.borrow()).x.borrow()) == 50)) + && ((*(*j.borrow()).arr.borrow())[(1) as usize] == 6) + ); + assert!(((*(*i.borrow()).v.borrow()) == 5) && ((*(*k.borrow()).v.borrow()) == 5)); + let l: Value = Rc::new(RefCell::new(Implicit { + v: Rc::new(RefCell::new(0)), + inner: Rc::new(RefCell::new(Inner { + x: Rc::new(RefCell::new(0)), + })), + arr: Rc::new(RefCell::new(Box::new([0, 0]))), + })); + (*l.borrow_mut()) = (*j.borrow()).clone(); + assert!( + (((*(*l.borrow()).v.borrow()) == 5) + && ((*(*(*l.borrow()).inner.borrow()).x.borrow()) == 50)) + && ((*(*l.borrow()).arr.borrow())[(0) as usize] == 5) + ); + let vec_: Value> = Rc::new(RefCell::new(Vec::new())); + { + let a0_clone = (*b.borrow()).clone(); + (*vec_.borrow_mut()).push(a0_clone) + }; + (*vec_.borrow_mut()).push(Explicit::Explicit({ 9 })); + assert!( + ((*(*(vec_.as_pointer() as Ptr) + .offset(0_usize) + .upgrade() + .deref()) + .v + .borrow()) + == 1) + && ((*(*(vec_.as_pointer() as Ptr) + .offset(1_usize) + .upgrade() + .deref()) + .v + .borrow()) + == 9) + ); + let m: Value = + Rc::new(RefCell::new(DefaultCopyUserMove::DefaultCopyUserMove({ + 7 + }))); + let m1: Value = Rc::new(RefCell::new((*m.borrow()).clone())); + let m2: Value = Rc::new(RefCell::new( + DefaultCopyUserMove::DefaultCopyUserMove_pmutDefaultCopyUserMove({ m.as_pointer() }), + )); + assert!( + (((*(*m1.borrow()).v.borrow()) == 7) && ((*(*m2.borrow()).v.borrow()) == 7)) + && ((*(*m.borrow()).v.borrow()) == 0) + ); + let m3: Value = + Rc::new(RefCell::new(DefaultCopyUserMove::DefaultCopyUserMove({ + 1 + }))); + let m4: Value = + Rc::new(RefCell::new(DefaultCopyUserMove::DefaultCopyUserMove({ + 1 + }))); + (*m3.borrow_mut()) = (*m1.borrow()).clone(); + ({ + DefaultCopyUserMoveImpl::operator_assign_pmutDefaultCopyUserMove( + &m4.as_pointer(), + m1.as_pointer(), + ) + }); + assert!( + (((*(*m3.borrow()).v.borrow()) == 7) && ((*(*m4.borrow()).v.borrow()) == 7)) + && ((*(*m1.borrow()).v.borrow()) == 0) + ); + let u: Value = + Rc::new(RefCell::new(UserCopyDefaultMove::UserCopyDefaultMove({ + 8 + }))); + let u1: Value = Rc::new(RefCell::new( + UserCopyDefaultMove::UserCopyDefaultMove_pconstUserCopyDefaultMove({ u.as_pointer() }), + )); + let u2: Value = Rc::new(RefCell::new( + UserCopyDefaultMove::UserCopyDefaultMove_pmutUserCopyDefaultMove({ u.as_pointer() }), + )); + assert!( + (((*(*u1.borrow()).v.borrow()) == 108) && ((*(*u2.borrow()).v.borrow()) == 8)) + && ((*(*u.borrow()).v.borrow()) == 8) + ); + let u3: Value = + Rc::new(RefCell::new(UserCopyDefaultMove::UserCopyDefaultMove({ + 1 + }))); + let u4: Value = + Rc::new(RefCell::new(UserCopyDefaultMove::UserCopyDefaultMove({ + 1 + }))); + ({ + UserCopyDefaultMoveImpl::operator_assign_pconstUserCopyDefaultMove( + &u3.as_pointer(), + u2.as_pointer(), + ) + }); + ({ + UserCopyDefaultMoveImpl::operator_assign_pmutUserCopyDefaultMove( + &u4.as_pointer(), + u2.as_pointer(), + ) + }); + assert!(((*(*u3.borrow()).v.borrow()) == 108) && ((*(*u4.borrow()).v.borrow()) == 8)); + let p: Value = Rc::new(RefCell::new(Buffer::Buffer({ 3 }))); + let q: Value = Rc::new(RefCell::new(Buffer::Buffer_pmutBuffer({ p.as_pointer() }))); + assert!( + ((((*(*q.borrow()).n.borrow()) == 3) && ((*(*q.borrow()).data.borrow()).len() == 3_usize)) + && ((((*q.borrow()).data.as_pointer() as Ptr) + .offset(2_usize) + .read()) + == 3)) + && ((*(*p.borrow()).data.borrow()).is_empty()) + ); + let r: Value = Rc::new(RefCell::new(Buffer::Buffer({ 1 }))); + ({ BufferImpl::operator_assign_pmutBuffer(&r.as_pointer(), q.as_pointer()) }); + assert!( + ((((*(*r.borrow()).n.borrow()) == 3) && ((*(*r.borrow()).data.borrow()).len() == 3_usize)) + && ((*(*r.borrow()).arr.borrow())[(1) as usize] == 4)) + && ((*(*q.borrow()).data.borrow()).is_empty()) + ); + assert!( + (((*(*r.borrow()).rows.borrow()).len() == 1_usize) + && ((*(((*r.borrow()).rows.as_pointer() as Ptr>>) + .offset(0_usize) + .upgrade() + .deref() + .as_pointer() as Ptr>) + .upgrade() + .deref()) + .len() + == 3_usize)) + && ((*(*q.borrow()).rows.borrow()).is_empty()) + ); + let bufs: Value> = Rc::new(RefCell::new(Vec::new())); + (*bufs.borrow_mut()).push(Buffer::Buffer_pmutBuffer({ r.as_pointer() })); + { + let __arg = + Buffer::Buffer_pmutBuffer({ (bufs.as_pointer() as Ptr).offset(0_usize) }); + bufs.as_pointer() + .with_mut(|__v: &mut Vec| __v.push(__arg)) + }; + assert!( + (((*(*(bufs.as_pointer() as Ptr) + .offset(1_usize) + .upgrade() + .deref()) + .n + .borrow()) + == 3) + && ((*(*(bufs.as_pointer() as Ptr) + .offset(1_usize) + .upgrade() + .deref()) + .data + .borrow()) + .len() + == 3_usize)) + && ((*(*(bufs.as_pointer() as Ptr) + .offset(0_usize) + .upgrade() + .deref()) + .data + .borrow()) + .is_empty()) + ); + let o1: Value = Rc::new(RefCell::new(::default())); + (*(*o1.borrow()).data.borrow_mut()).push(5); + (*(*o1.borrow()).n.borrow_mut()) = 5; + (*(*o1.borrow()).arr.borrow_mut())[(0) as usize] = 5; + (*(*o1.borrow()).arr.borrow_mut())[(1) as usize] = 6; + { + let _p: Ptr<_> = Ptr::alloc(7); + (*(*o1.borrow()).p.borrow_mut()) = _p.to_owned_opt() + }; + let o2: Value = Rc::new(RefCell::new(Owner::Owner_pmutOwner({ o1.as_pointer() }))); + assert!( + ((((*(*o2.borrow()).n.borrow()) == 5) + && ((*(*o2.borrow()).data.borrow()).len() == 1_usize)) + && ((*(*o2.borrow()).arr.borrow())[(1) as usize] == 6)) + && ((*(*(*o2.borrow()).p.borrow()).as_ref().unwrap().borrow()) == 7) + ); + assert!( + ((*(*o1.borrow()).data.borrow()).is_empty()) + && (((*(*o1.borrow()).p.borrow()).as_pointer()).is_null()) + ); + let o3: Value = Rc::new(RefCell::new(::default())); + ({ OwnerImpl::operator_assign_pmutOwner(&o3.as_pointer(), o2.as_pointer()) }); + assert!( + ((((*(*o3.borrow()).n.borrow()) == 5) + && ((((*o3.borrow()).data.as_pointer() as Ptr) + .offset(0_usize) + .read()) + == 5)) + && ((*(*o3.borrow()).arr.borrow())[(0) as usize] == 5)) + && ((*(*(*o3.borrow()).p.borrow()).as_ref().unwrap().borrow()) == 7) + ); + assert!( + ((*(*o2.borrow()).data.borrow()).is_empty()) + && (((*(*o2.borrow()).p.borrow()).as_pointer()).is_null()) + ); + let h1: Value = Rc::new(RefCell::new(Holder::Holder({ 4 }))); + let _dtor_h1 = ScopedDestructor::new(&h1, |__p| __p.destructor()); + { + let _p: Ptr<_> = Ptr::alloc(9); + (*(*h1.borrow()).p.borrow_mut()) = _p.to_owned_opt() + }; + let h2: Value = Rc::new(RefCell::new(Holder::Holder_pmutHolder({ h1.as_pointer() }))); + let _dtor_h2 = ScopedDestructor::new(&h2, |__p| __p.destructor()); + assert!( + ((((*(*(*h2.borrow()).inner.borrow()).x.borrow()) == 4) + && ((*(*(*h2.borrow()).e.borrow()).v.borrow()) == 4)) + && ((*(*(*h2.borrow()).p.borrow()).as_ref().unwrap().borrow()) == 9)) + && (((*(*h1.borrow()).p.borrow()).as_pointer()).is_null()) + ); + let h3: Value = Rc::new(RefCell::new(Holder::Holder({ 1 }))); + let _dtor_h3 = ScopedDestructor::new(&h3, |__p| __p.destructor()); + ({ HolderImpl::operator_assign_pmutHolder(&h3.as_pointer(), h2.as_pointer()) }); + assert!( + ((((*(*(*h3.borrow()).inner.borrow()).x.borrow()) == 4) + && ((*(*(*h3.borrow()).e.borrow()).arr.borrow())[(1) as usize] == 5)) + && ((*(*(*h3.borrow()).p.borrow()).as_ref().unwrap().borrow()) == 9)) + && (((*(*h2.borrow()).p.borrow()).as_pointer()).is_null()) + ); + return 0; +} +pub trait BufferImpl { + fn operator_assign_pmutBuffer(&self, _a0: Ptr) -> Ptr; +} +impl BufferImpl for Ptr { + fn operator_assign_pmutBuffer(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).data.as_pointer() as Ptr>).write(std::mem::take( + &mut (*(*_a0.upgrade().deref()).data.borrow_mut()), + )); + ((*(*self).upgrade().deref()).rows.as_pointer() as Ptr>>>).write( + std::mem::take(&mut (*(*_a0.upgrade().deref()).rows.borrow_mut())), + ); + let __rhs = (*(*_a0.upgrade().deref()).n.borrow()); + (*(*(*self).upgrade().deref()).n.borrow_mut()) = __rhs; + { + (((*(*self).upgrade().deref()).arr.as_pointer()) as Ptr) + .to_any() + .memcpy( + &(((*_a0.upgrade().deref()).arr.as_pointer()) as Ptr).to_any(), + 8_usize as usize, + ); + (((*(*self).upgrade().deref()).arr.as_pointer()) as Ptr).to_any() + }; + return (*self).clone(); + } +} +pub trait DefaultCopyUserMoveImpl { + fn operator_assign_pmutDefaultCopyUserMove( + &self, + o: Ptr, + ) -> Ptr; +} +impl DefaultCopyUserMoveImpl for Ptr { + fn operator_assign_pmutDefaultCopyUserMove( + &self, + o: Ptr, + ) -> Ptr { + let __rhs = (*(*o.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + return (*self).clone(); + } +} +pub trait ExplicitImpl { + fn destructor(&self); +} +impl ExplicitImpl for Ptr { + fn destructor(&self) {} +} +pub trait HolderImpl { + fn operator_assign_pmutHolder(&self, _a0: Ptr) -> Ptr; + fn destructor(&self); +} +impl HolderImpl for Ptr { + fn operator_assign_pmutHolder(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).inner.borrow()).clone(); + (*(*(*self).upgrade().deref()).inner.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).e.borrow()).clone(); + (*(*(*self).upgrade().deref()).e.borrow_mut()) = __rhs; + ((*(*self).upgrade().deref()).p.as_pointer() as Ptr>>) + .write((*(*_a0.upgrade().deref()).p.borrow_mut()).take()); + return (*self).clone(); + } + fn destructor(&self) { + (*self.upgrade().deref()).e.as_pointer().destructor(); + } +} +pub trait OwnerImpl { + fn operator_assign_pmutOwner(&self, _a0: Ptr) -> Ptr; +} +impl OwnerImpl for Ptr { + fn operator_assign_pmutOwner(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).data.as_pointer() as Ptr>).write(std::mem::take( + &mut (*(*_a0.upgrade().deref()).data.borrow_mut()), + )); + let __rhs = (*(*_a0.upgrade().deref()).n.borrow()); + (*(*(*self).upgrade().deref()).n.borrow_mut()) = __rhs; + { + (((*(*self).upgrade().deref()).arr.as_pointer()) as Ptr) + .to_any() + .memcpy( + &(((*_a0.upgrade().deref()).arr.as_pointer()) as Ptr).to_any(), + 8_usize as usize, + ); + (((*(*self).upgrade().deref()).arr.as_pointer()) as Ptr).to_any() + }; + ((*(*self).upgrade().deref()).p.as_pointer() as Ptr>>) + .write((*(*_a0.upgrade().deref()).p.borrow_mut()).take()); + return (*self).clone(); + } +} +pub trait UserCopyDefaultMoveImpl { + fn operator_assign_pconstUserCopyDefaultMove( + &self, + o: Ptr, + ) -> Ptr; + fn operator_assign_pmutUserCopyDefaultMove( + &self, + _a0: Ptr, + ) -> Ptr; +} +impl UserCopyDefaultMoveImpl for Ptr { + fn operator_assign_pconstUserCopyDefaultMove( + &self, + o: Ptr, + ) -> Ptr { + let __rhs = ((*(*o.upgrade().deref()).v.borrow()) + 100); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + return (*self).clone(); + } + fn operator_assign_pmutUserCopyDefaultMove( + &self, + _a0: Ptr, + ) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/copy_move_deleted.rs b/tests/unit/out/refcount/copy_move_deleted.rs new file mode 100644 index 00000000..0cf4c031 --- /dev/null +++ b/tests/unit/out/refcount/copy_move_deleted.rs @@ -0,0 +1,229 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +#[derive(Default)] +pub struct NoCopy { + pub v: Value, +} +impl NoCopy { + pub fn NoCopy(v: i32) -> Self { + let v: Value = Rc::new(RefCell::new(v)); + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn NoCopy_pmutNoCopy(o: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*o.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for NoCopy { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive()] +pub struct PrivateCopy { + pub v: Value, +} +impl PrivateCopy { + pub fn PrivateCopy() -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(0)), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } + pub fn PrivateCopy_pmutPrivateCopy(o: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new((*(*o.upgrade().deref()).v.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for PrivateCopy { + fn default() -> Self { + { PrivateCopy::PrivateCopy() } + } +} +impl ByteRepr for PrivateCopy { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive()] +pub struct Immovable { + pub v: Value, +} +impl Immovable { + pub fn Immovable() -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + v: Rc::new(RefCell::new(0)), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl Default for Immovable { + fn default() -> Self { + { Immovable::Immovable() } + } +} +impl ByteRepr for Immovable { + fn byte_size() -> usize { + 4 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.v.borrow()).to_bytes(&mut buf[0..4]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + v: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + } + } +} +#[derive(Default)] +pub struct Container { + pub inner: Value, + pub tag: Value, +} +impl Container { + pub fn Container_pmutContainer(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + inner: Rc::new(RefCell::new(NoCopy::NoCopy_pmutNoCopy({ + (*_a0.upgrade().deref()).inner.as_pointer() + }))), + tag: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).tag.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} +impl ByteRepr for Container { + fn byte_size() -> usize { + 8 + } + fn to_bytes(&self, buf: &mut [u8]) { + (*self.inner.borrow()).to_bytes(&mut buf[0..4]); + (*self.tag.borrow()).to_bytes(&mut buf[4..8]); + } + fn from_bytes(buf: &[u8]) -> Self { + Self { + inner: Rc::new(RefCell::new(::from_bytes(&buf[0..4]))), + tag: Rc::new(RefCell::new(::from_bytes(&buf[4..8]))), + } + } +} +pub fn bump_0(p: Ptr) { + let p: Value> = Rc::new(RefCell::new(p)); + (*(*(*p.borrow()).upgrade().deref()).v.borrow_mut()).postfix_inc(); +} +pub fn bump_ref_1(r: Ptr) { + (*(*r.upgrade().deref()).v.borrow_mut()).postfix_inc(); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value = Rc::new(RefCell::new(NoCopy::NoCopy({ 1 }))); + let b: Value = Rc::new(RefCell::new(NoCopy::NoCopy_pmutNoCopy({ a.as_pointer() }))); + assert!(((*(*b.borrow()).v.borrow()) == 1) && ((*(*a.borrow()).v.borrow()) == 0)); + ({ NoCopyImpl::operator_assign_pmutNoCopy(&a.as_pointer(), b.as_pointer()) }); + assert!(((*(*a.borrow()).v.borrow()) == 1) && ((*(*b.borrow()).v.borrow()) == 0)); + ({ bump_0((a.as_pointer())) }); + assert!(((*(*a.borrow()).v.borrow()) == 2)); + let p: Value = Rc::new(RefCell::new(PrivateCopy::PrivateCopy())); + (*(*p.borrow()).v.borrow_mut()) = 3; + let q: Value = Rc::new(RefCell::new(PrivateCopy::PrivateCopy_pmutPrivateCopy({ + p.as_pointer() + }))); + assert!(((*(*q.borrow()).v.borrow()) == 3) && ((*(*p.borrow()).v.borrow()) == 0)); + ({ PrivateCopyImpl::operator_assign_pmutPrivateCopy(&p.as_pointer(), q.as_pointer()) }); + assert!(((*(*p.borrow()).v.borrow()) == 3) && ((*(*q.borrow()).v.borrow()) == 0)); + let im: Value = Rc::new(RefCell::new(Immovable::Immovable())); + (*(*im.borrow()).v.borrow_mut()) = 4; + ({ bump_ref_1(im.as_pointer()) }); + let pim: Value> = Rc::new(RefCell::new((im.as_pointer()))); + assert!(((*(*(*pim.borrow()).upgrade().deref()).v.borrow()) == 5)); + let c: Value = Rc::new(RefCell::new(Container { + inner: Rc::new(RefCell::new(NoCopy::NoCopy({ 6 }))), + tag: Rc::new(RefCell::new(7)), + })); + let d: Value = Rc::new(RefCell::new(Container::Container_pmutContainer({ + c.as_pointer() + }))); + assert!( + (((*(*(*d.borrow()).inner.borrow()).v.borrow()) == 6) + && ((*(*d.borrow()).tag.borrow()) == 7)) + && ((*(*(*c.borrow()).inner.borrow()).v.borrow()) == 0) + ); + return 0; +} +pub trait ContainerImpl { + fn operator_assign_pmutContainer(&self, _a0: Ptr) -> Ptr; +} +impl ContainerImpl for Ptr { + fn operator_assign_pmutContainer(&self, _a0: Ptr) -> Ptr { + ({ + let _o: Ptr = (*_a0.upgrade().deref()).inner.as_pointer(); + NoCopyImpl::operator_assign_pmutNoCopy( + &(*(*self).upgrade().deref()).inner.as_pointer(), + _o, + ) + }); + let __rhs = (*(*_a0.upgrade().deref()).tag.borrow()); + (*(*(*self).upgrade().deref()).tag.borrow_mut()) = __rhs; + return (*self).clone(); + } +} +pub trait NoCopyImpl { + fn operator_assign_pmutNoCopy(&self, o: Ptr) -> Ptr; +} +impl NoCopyImpl for Ptr { + fn operator_assign_pmutNoCopy(&self, o: Ptr) -> Ptr { + let __rhs = (*(*o.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + return (*self).clone(); + } +} +pub trait PrivateCopyImpl { + fn operator_assign_pmutPrivateCopy(&self, o: Ptr) -> Ptr; +} +impl PrivateCopyImpl for Ptr { + fn operator_assign_pmutPrivateCopy(&self, o: Ptr) -> Ptr { + let __rhs = (*(*o.upgrade().deref()).v.borrow()); + (*(*(*self).upgrade().deref()).v.borrow_mut()) = __rhs; + (*(*o.upgrade().deref()).v.borrow_mut()) = 0; + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/default.rs b/tests/unit/out/refcount/default.rs index 0ebec44f..7e265c68 100644 --- a/tests/unit/out/refcount/default.rs +++ b/tests/unit/out/refcount/default.rs @@ -19,8 +19,12 @@ impl Clone for Pointers { let __this: Value = Rc::new(RefCell::new(Self { x1: Rc::new(RefCell::new((*self.x1.borrow()).clone())), x2: Rc::new(RefCell::new((*self.x2.borrow()).clone())), - x3: Rc::new(RefCell::new((*self.x3.borrow()).clone())), - x4: Rc::new(RefCell::new((*self.x4.borrow()).clone())), + x3: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 5, _>( + |__i: usize| ((*self.x3.borrow())[(__i) as usize]).clone(), + )))), + x4: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 10, _>( + |__i: usize| ((*self.x4.borrow())[(__i) as usize]).clone(), + )))), x5: Rc::new(RefCell::new((*self.x5.borrow()))), })); let this: Ptr = __this.as_pointer(); diff --git a/tests/unit/out/refcount/default_in_statics.rs b/tests/unit/out/refcount/default_in_statics.rs index 0302d002..0bf04450 100644 --- a/tests/unit/out/refcount/default_in_statics.rs +++ b/tests/unit/out/refcount/default_in_statics.rs @@ -52,7 +52,9 @@ impl Clone for Outer { let __this: Value = Rc::new(RefCell::new(Self { p1: Rc::new(RefCell::new((*self.p1.borrow()).clone())), p2: Rc::new(RefCell::new((*self.p2.borrow()).clone())), - arr: Rc::new(RefCell::new((*self.arr.borrow()).clone())), + arr: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 3, _>( + |__i: usize| ((*self.arr.borrow())[(__i) as usize]).clone(), + )))), cp: Rc::new(RefCell::new((*self.cp.borrow()).clone())), pp: Rc::new(RefCell::new((*self.pp.borrow()).clone())), inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())), diff --git a/tests/unit/out/refcount/destructor.rs b/tests/unit/out/refcount/destructor.rs index 4e10438d..71dff440 100644 --- a/tests/unit/out/refcount/destructor.rs +++ b/tests/unit/out/refcount/destructor.rs @@ -112,7 +112,9 @@ pub struct ArrayMember { impl Clone for ArrayMember { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { - items: Rc::new(RefCell::new((*self.items.borrow()).clone())), + items: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 3, _>( + |__i: usize| ((*self.items.borrow())[(__i) as usize]).clone(), + )))), })); let this: Ptr = __this.as_pointer(); Rc::try_unwrap(__this).ok().unwrap().into_inner() diff --git a/tests/unit/out/refcount/huffman.rs b/tests/unit/out/refcount/huffman.rs index 0b622cb5..eef8af57 100644 --- a/tests/unit/out/refcount/huffman.rs +++ b/tests/unit/out/refcount/huffman.rs @@ -82,6 +82,23 @@ pub struct MinHeap { pub next: Value, pub alloc: Value>>>, } +impl MinHeap { + pub fn MinHeap_pmutMinHeap(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + size: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).size.borrow()))), + capacity: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).capacity.borrow()))), + arr: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).arr.borrow_mut()).take(), + )), + next: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).next.borrow()))), + alloc: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).alloc.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for MinHeap { fn byte_size() -> usize { 32 @@ -335,6 +352,7 @@ pub trait MinHeapImpl { freq: Ptr>>>, n: i32, ); + fn operator_assign_pmutMinHeap(&self, _a0: Ptr) -> Ptr; } impl MinHeapImpl for Ptr { fn Alloc(&self, data: u8, freq: i32) -> Ptr { @@ -506,6 +524,20 @@ impl MinHeapImpl for Ptr { (*i.borrow_mut()).prefix_dec(); } } + fn operator_assign_pmutMinHeap(&self, _a0: Ptr) -> Ptr { + let __rhs = (*(*_a0.upgrade().deref()).size.borrow()); + (*(*(*self).upgrade().deref()).size.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).capacity.borrow()); + (*(*(*self).upgrade().deref()).capacity.borrow_mut()) = __rhs; + ((*(*self).upgrade().deref()).arr.as_pointer() + as Ptr]>>>>) + .write((*(*_a0.upgrade().deref()).arr.borrow_mut()).take()); + let __rhs = (*(*_a0.upgrade().deref()).next.borrow()); + (*(*(*self).upgrade().deref()).next.borrow_mut()) = __rhs; + ((*(*self).upgrade().deref()).alloc.as_pointer() as Ptr>>>) + .write((*(*_a0.upgrade().deref()).alloc.borrow_mut()).take()); + return (*self).clone(); + } } pub trait MinHeapNodeImpl { fn IsLeaf(&self) -> bool; diff --git a/tests/unit/out/refcount/kruskal.rs b/tests/unit/out/refcount/kruskal.rs index de5b50f3..036e0fea 100644 --- a/tests/unit/out/refcount/kruskal.rs +++ b/tests/unit/out/refcount/kruskal.rs @@ -221,6 +221,21 @@ pub struct DisjointSet { pub parent: Value>>>, pub n: Value, } +impl DisjointSet { + pub fn DisjointSet_pmutDisjointSet(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + rank: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).rank.borrow_mut()).take(), + )), + parent: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).parent.borrow_mut()).take(), + )), + n: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).n.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for DisjointSet { fn byte_size() -> usize { 24 @@ -248,6 +263,19 @@ pub struct Graph { pub V: Value, pub E: Value, } +impl Graph { + pub fn Graph_pmutGraph(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + edges: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).edges.borrow_mut()).take(), + )), + V: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).V.borrow()))), + E: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).E.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for Graph { fn byte_size() -> usize { 16 @@ -390,6 +418,7 @@ pub trait DisjointSetImpl { fn makeSet(&self); fn find(&self, x: i32) -> i32; fn merge(&self, x: i32, y: i32); + fn operator_assign_pmutDisjointSet(&self, _a0: Ptr) -> Ptr; } impl DisjointSetImpl for Ptr { fn makeSet(&self) { @@ -486,4 +515,27 @@ impl DisjointSetImpl for Ptr { .borrow_mut()[((*xset.borrow()) as usize) as usize] = __rhs; } } + fn operator_assign_pmutDisjointSet(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).rank.as_pointer() as Ptr>>>) + .write((*(*_a0.upgrade().deref()).rank.borrow_mut()).take()); + ((*(*self).upgrade().deref()).parent.as_pointer() as Ptr>>>) + .write((*(*_a0.upgrade().deref()).parent.borrow_mut()).take()); + let __rhs = (*(*_a0.upgrade().deref()).n.borrow()); + (*(*(*self).upgrade().deref()).n.borrow_mut()) = __rhs; + return (*self).clone(); + } +} +pub trait GraphImpl { + fn operator_assign_pmutGraph(&self, _a0: Ptr) -> Ptr; +} +impl GraphImpl for Ptr { + fn operator_assign_pmutGraph(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).edges.as_pointer() as Ptr>>>) + .write((*(*_a0.upgrade().deref()).edges.borrow_mut()).take()); + let __rhs = (*(*_a0.upgrade().deref()).V.borrow()); + (*(*(*self).upgrade().deref()).V.borrow_mut()) = __rhs; + let __rhs = (*(*_a0.upgrade().deref()).E.borrow()); + (*(*(*self).upgrade().deref()).E.borrow_mut()) = __rhs; + return (*self).clone(); + } } diff --git a/tests/unit/out/refcount/move_ctor.rs b/tests/unit/out/refcount/move_ctor.rs index 7a8cbadb..564326b3 100644 --- a/tests/unit/out/refcount/move_ctor.rs +++ b/tests/unit/out/refcount/move_ctor.rs @@ -123,7 +123,7 @@ fn main_0() -> i32 { let vec_: Value> = Rc::new(RefCell::new(Vec::new())); (*vec_.borrow_mut()).push(MoveOnly::MoveOnly({ 7 })); let f: Value = Rc::new(RefCell::new(MoveOnly::MoveOnly({ 8 }))); - (*vec_.borrow_mut()).push(std::mem::take(&mut (*f.borrow_mut()))); + (*vec_.borrow_mut()).push(MoveOnly::MoveOnly_pmutMoveOnly({ f.as_pointer() })); assert!( ((*(*(vec_.as_pointer() as Ptr) .offset(0_usize) diff --git a/tests/unit/out/refcount/offsetof.rs b/tests/unit/out/refcount/offsetof.rs index 7d9e0f58..da61178f 100644 --- a/tests/unit/out/refcount/offsetof.rs +++ b/tests/unit/out/refcount/offsetof.rs @@ -49,7 +49,9 @@ impl Clone for Frame { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { tag: Rc::new(RefCell::new((*self.tag.borrow()))), - body: Rc::new(RefCell::new((*self.body.borrow()).clone())), + body: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 64, _>( + |__i: usize| (*self.body.borrow())[(__i) as usize], + )))), })); let this: Ptr = __this.as_pointer(); Rc::try_unwrap(__this).ok().unwrap().into_inner() diff --git a/tests/unit/out/refcount/operator_comparison_noncopyable.rs b/tests/unit/out/refcount/operator_comparison_noncopyable.rs index fd5f23ca..71d91067 100644 --- a/tests/unit/out/refcount/operator_comparison_noncopyable.rs +++ b/tests/unit/out/refcount/operator_comparison_noncopyable.rs @@ -31,6 +31,13 @@ impl S { let this: Ptr = __this.as_pointer(); Rc::try_unwrap(__this).ok().unwrap().into_inner() } + pub fn S_pmutS(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + data_: Rc::new(RefCell::new((*(*_a0.upgrade().deref()).data_.borrow()))), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } } impl std::cmp::Ord for S { fn cmp(&self, other: &Self) -> std::cmp::Ordering { diff --git a/tests/unit/out/refcount/operator_member_pointer_free.rs b/tests/unit/out/refcount/operator_member_pointer_free.rs index 0fb3dad5..2fd79df3 100644 --- a/tests/unit/out/refcount/operator_member_pointer_free.rs +++ b/tests/unit/out/refcount/operator_member_pointer_free.rs @@ -40,7 +40,9 @@ pub struct S { impl Clone for S { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { - data: Rc::new(RefCell::new((*self.data.borrow()).clone())), + data: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 3, _>( + |__i: usize| (*self.data.borrow())[(__i) as usize], + )))), inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())), })); let this: Ptr = __this.as_pointer(); diff --git a/tests/unit/out/refcount/operator_member_pointer_member.rs b/tests/unit/out/refcount/operator_member_pointer_member.rs index 8d852312..c736517e 100644 --- a/tests/unit/out/refcount/operator_member_pointer_member.rs +++ b/tests/unit/out/refcount/operator_member_pointer_member.rs @@ -68,7 +68,9 @@ pub struct S { impl Clone for S { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { - data: Rc::new(RefCell::new((*self.data.borrow()).clone())), + data: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 3, _>( + |__i: usize| (*self.data.borrow())[(__i) as usize], + )))), inner: Rc::new(RefCell::new((*self.inner.borrow()).clone())), })); let this: Ptr = __this.as_pointer(); diff --git a/tests/unit/out/refcount/pointer_array.rs b/tests/unit/out/refcount/pointer_array.rs index 2fd7520f..e3832661 100644 --- a/tests/unit/out/refcount/pointer_array.rs +++ b/tests/unit/out/refcount/pointer_array.rs @@ -13,7 +13,9 @@ pub struct StackArray { impl Clone for StackArray { fn clone(&self) -> Self { let __this: Value = Rc::new(RefCell::new(Self { - arr: Rc::new(RefCell::new((*self.arr.borrow()).clone())), + arr: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 3, _>( + |__i: usize| ((*self.arr.borrow())[(__i) as usize]).clone(), + )))), })); let this: Ptr = __this.as_pointer(); Rc::try_unwrap(__this).ok().unwrap().into_inner() diff --git a/tests/unit/out/refcount/push_emplace_back.rs b/tests/unit/out/refcount/push_emplace_back.rs index 2fc46195..983b3dc4 100644 --- a/tests/unit/out/refcount/push_emplace_back.rs +++ b/tests/unit/out/refcount/push_emplace_back.rs @@ -141,9 +141,7 @@ pub fn shrink_through_ptr_2(comps: Ptr>) { pub fn nested_push_move_3(bw: Ptr) { let bw: Value> = Rc::new(RefCell::new(bw)); (*(*(*bw.borrow()).upgrade().deref()).output.borrow()).with_mut(|__v: &mut Vec| { - __v.push(std::mem::take( - &mut (*(*(*bw.borrow()).upgrade().deref()).chunk.borrow_mut()), - )) + __v.push((*(*(*bw.borrow()).upgrade().deref()).chunk.borrow()).clone()) }); } pub fn emplace_local_from_field_4(jpg: Ptr, cond: bool) { @@ -174,14 +172,13 @@ pub fn emplace_local_from_field_4(jpg: Ptr, cond: bool) { } pub fn nested_emplace_move_5(bw: Ptr) { let bw: Value> = Rc::new(RefCell::new(bw)); - (*(*(*bw.borrow()).upgrade().deref()).output.borrow()) - .to_strong() - .as_pointer() - .with_mut(|__v: &mut Vec| { - __v.push(std::mem::take( - &mut (*(*(*bw.borrow()).upgrade().deref()).chunk.borrow()).clone(), - )) - }); + { + let __arg = (*(*(*bw.borrow()).upgrade().deref()).chunk.borrow()).clone(); + (*(*(*bw.borrow()).upgrade().deref()).output.borrow()) + .to_strong() + .as_pointer() + .with_mut(|__v: &mut Vec| __v.push(__arg)) + }; } pub fn self_ref_push_6(comps: Ptr>) { let comps: Value>> = Rc::new(RefCell::new(comps)); diff --git a/tests/unit/out/refcount/random.rs b/tests/unit/out/refcount/random.rs index 3e857cbc..ceb93973 100644 --- a/tests/unit/out/refcount/random.rs +++ b/tests/unit/out/refcount/random.rs @@ -21,11 +21,15 @@ impl Clone for Pair { let __this: Value = Rc::new(RefCell::new(Self { x: Rc::new(RefCell::new((*self.x.borrow()))), y: Rc::new(RefCell::new((*self.y.borrow()))), - a: Rc::new(RefCell::new((*self.a.borrow()).clone())), + a: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 5, _>( + |__i: usize| (*self.a.borrow())[(__i) as usize], + )))), r: (self.r).clone(), p: Rc::new(RefCell::new((*self.p.borrow()).clone())), pair: Rc::new(RefCell::new((*self.pair.borrow()).clone())), - ap: Rc::new(RefCell::new((*self.ap.borrow()).clone())), + ap: Rc::new(RefCell::new(Box::new(std::array::from_fn::<_, 2, _>( + |__i: usize| ((*self.ap.borrow())[(__i) as usize]).clone(), + )))), })); let this: Ptr = __this.as_pointer(); Rc::try_unwrap(__this).ok().unwrap().into_inner() diff --git a/tests/unit/out/refcount/unique_ptr.rs b/tests/unit/out/refcount/unique_ptr.rs index 057d2497..b491bf44 100644 --- a/tests/unit/out/refcount/unique_ptr.rs +++ b/tests/unit/out/refcount/unique_ptr.rs @@ -10,6 +10,17 @@ use std::rc::{Rc, Weak}; pub struct SafePointer { pub ptr: Value>>, } +impl SafePointer { + pub fn SafePointer_pmutSafePointer(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + ptr: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).ptr.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for SafePointer { fn byte_size() -> usize { 8 @@ -305,6 +316,7 @@ impl PairImpl for Ptr { } pub trait SafePointerImpl { fn inc(&self); + fn operator_assign_pmutSafePointer(&self, _a0: Ptr) -> Ptr; } impl SafePointerImpl for Ptr { fn inc(&self) { @@ -314,4 +326,9 @@ impl SafePointerImpl for Ptr { .borrow_mut()) .prefix_inc(); } + fn operator_assign_pmutSafePointer(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).ptr.as_pointer() as Ptr>>) + .write((*(*_a0.upgrade().deref()).ptr.borrow_mut()).take()); + return (*self).clone(); + } } diff --git a/tests/unit/out/refcount/unique_ptr_const_deref.rs b/tests/unit/out/refcount/unique_ptr_const_deref.rs index 299f6780..7aa75e9e 100644 --- a/tests/unit/out/refcount/unique_ptr_const_deref.rs +++ b/tests/unit/out/refcount/unique_ptr_const_deref.rs @@ -10,6 +10,17 @@ use std::rc::{Rc, Weak}; pub struct Holder { pub val: Value>>, } +impl Holder { + pub fn Holder_pmutHolder(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + val: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).val.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for Holder { fn byte_size() -> usize { 8 @@ -49,3 +60,13 @@ fn main_0() -> i32 { assert!((({ read_val_0((h.as_pointer()),) }) == 42)); return 0; } +pub trait HolderImpl { + fn operator_assign_pmutHolder(&self, _a0: Ptr) -> Ptr; +} +impl HolderImpl for Ptr { + fn operator_assign_pmutHolder(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).val.as_pointer() as Ptr>>) + .write((*(*_a0.upgrade().deref()).val.borrow_mut()).take()); + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/unique_ptr_nested.rs b/tests/unit/out/refcount/unique_ptr_nested.rs index 7f5be219..729267fa 100644 --- a/tests/unit/out/refcount/unique_ptr_nested.rs +++ b/tests/unit/out/refcount/unique_ptr_nested.rs @@ -40,6 +40,17 @@ impl ByteRepr for Inner { pub struct Outer { pub inner: Value>>, } +impl Outer { + pub fn Outer_pmutOuter(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + inner: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).inner.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for Outer { fn byte_size() -> usize { 8 @@ -91,3 +102,13 @@ fn main_0() -> i32 { assert!((((*sum.borrow()) + (*(*b.borrow()).as_ref().unwrap().borrow())) == 135)); return 0; } +pub trait OuterImpl { + fn operator_assign_pmutOuter(&self, _a0: Ptr) -> Ptr; +} +impl OuterImpl for Ptr { + fn operator_assign_pmutOuter(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).inner.as_pointer() as Ptr>>) + .write((*(*_a0.upgrade().deref()).inner.borrow_mut()).take()); + return (*self).clone(); + } +} diff --git a/tests/unit/out/refcount/void_cast.rs b/tests/unit/out/refcount/void_cast.rs index 2c50822b..6778ff76 100644 --- a/tests/unit/out/refcount/void_cast.rs +++ b/tests/unit/out/refcount/void_cast.rs @@ -80,6 +80,17 @@ impl ByteRepr for Holder { pub struct NonCopyable { pub value: Value>>, } +impl NonCopyable { + pub fn NonCopyable_pmutNonCopyable(_a0: Ptr) -> Self { + let __this: Value = Rc::new(RefCell::new(Self { + value: Rc::new(RefCell::new( + (*(*_a0.upgrade().deref()).value.borrow_mut()).take(), + )), + })); + let this: Ptr = __this.as_pointer(); + Rc::try_unwrap(__this).ok().unwrap().into_inner() + } +} impl ByteRepr for NonCopyable { fn byte_size() -> usize { 8 @@ -168,3 +179,13 @@ fn main_0() -> i32 { assert!(((*(*(*g.borrow()).value.borrow()).as_ref().unwrap().borrow()) == 9)); return 0; } +pub trait NonCopyableImpl { + fn operator_assign_pmutNonCopyable(&self, _a0: Ptr) -> Ptr; +} +impl NonCopyableImpl for Ptr { + fn operator_assign_pmutNonCopyable(&self, _a0: Ptr) -> Ptr { + ((*(*self).upgrade().deref()).value.as_pointer() as Ptr>>) + .write((*(*_a0.upgrade().deref()).value.borrow_mut()).take()); + return (*self).clone(); + } +} diff --git a/tests/unit/out/unsafe/copy_ctor.rs b/tests/unit/out/unsafe/copy_ctor.rs index 56bd4a35..e098c68f 100644 --- a/tests/unit/out/unsafe/copy_ctor.rs +++ b/tests/unit/out/unsafe/copy_ctor.rs @@ -80,7 +80,7 @@ pub unsafe fn by_value_1(mut c: Counted) -> i32 { } pub unsafe fn make_2(mut v: i32) -> Counted { let mut c: Counted = Counted::Counted({ v }); - return Counted::Counted_pconstCounted({ &mut c }); + return Counted::Counted_pconstCounted({ &c }); } pub fn main() { unsafe { diff --git a/tests/unit/out/unsafe/copy_move_defaulted.rs b/tests/unit/out/unsafe/copy_move_defaulted.rs new file mode 100644 index 00000000..8e738688 --- /dev/null +++ b/tests/unit/out/unsafe/copy_move_defaulted.rs @@ -0,0 +1,447 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Inner { + pub x: i32, +} +#[repr(C)] +#[derive(Clone)] +pub struct Explicit { + pub v: i32, + pub inner: Inner, + pub arr: [i32; 2], +} +impl Explicit { + pub unsafe fn Explicit(mut v: i32) -> Self { + let mut this = Self { + v: v, + inner: Inner { x: ((v) * (10)) }, + arr: [v, ((v) + (1))], + }; + this + } + pub unsafe fn destructor(&mut self) {} +} +impl Default for Explicit { + fn default() -> Self { + Explicit { + v: 0_i32, + inner: ::default(), + arr: [0_i32; 2], + } + } +} +#[repr(C)] +#[derive(Copy, Clone)] +pub struct Implicit { + pub v: i32, + pub inner: Inner, + pub arr: [i32; 2], +} +impl Default for Implicit { + fn default() -> Self { + Implicit { + v: 0_i32, + inner: ::default(), + arr: [0_i32; 2], + } + } +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct DefaultCopyUserMove { + pub v: i32, +} +impl DefaultCopyUserMove { + pub unsafe fn DefaultCopyUserMove(mut v: i32) -> Self { + let mut this = Self { v: v }; + this + } + pub unsafe fn DefaultCopyUserMove_pmutDefaultCopyUserMove(o: *mut DefaultCopyUserMove) -> Self { + let mut this = Self { v: (*o).v }; + (*o).v = 0; + this + } + pub unsafe fn operator_assign_pmutDefaultCopyUserMove( + &mut self, + o: *mut DefaultCopyUserMove, + ) -> *mut DefaultCopyUserMove { + self.v = (*o).v; + (*o).v = 0; + return &mut (*(self as *mut DefaultCopyUserMove)); + } +} +#[repr(C)] +#[derive(Default)] +pub struct UserCopyDefaultMove { + pub v: i32, +} +impl UserCopyDefaultMove { + pub unsafe fn UserCopyDefaultMove(mut v: i32) -> Self { + let mut this = Self { v: v }; + this + } + pub unsafe fn UserCopyDefaultMove_pconstUserCopyDefaultMove( + o: *const UserCopyDefaultMove, + ) -> Self { + let mut this = Self { + v: (((*o).v) + (100)), + }; + this + } + pub unsafe fn UserCopyDefaultMove_pmutUserCopyDefaultMove( + _a0: *mut UserCopyDefaultMove, + ) -> Self { + let mut this = Self { v: (*_a0).v }; + this + } + pub unsafe fn operator_assign_pconstUserCopyDefaultMove( + &mut self, + o: *const UserCopyDefaultMove, + ) -> *mut UserCopyDefaultMove { + self.v = (((*o).v) + (100)); + return &mut (*(self as *mut UserCopyDefaultMove)); + } + pub unsafe fn operator_assign_pmutUserCopyDefaultMove( + &mut self, + _a0: *mut UserCopyDefaultMove, + ) -> *mut UserCopyDefaultMove { + self.v = (*_a0).v; + return &mut (*(self as *mut UserCopyDefaultMove)); + } +} +impl Clone for UserCopyDefaultMove { + fn clone(&self) -> Self { + unsafe { + UserCopyDefaultMove::UserCopyDefaultMove_pconstUserCopyDefaultMove( + self as *const UserCopyDefaultMove, + ) + } + } +} +#[repr(C)] +#[derive()] +pub struct Buffer { + pub data: Vec, + pub rows: Vec>, + pub n: i32, + pub arr: [i32; 2], +} +impl Buffer { + pub unsafe fn Buffer(mut n: i32) -> Self { + let mut this = Self { + data: vec![n; (n as usize) as usize], + rows: Vec::new(), + n: n, + arr: [n, ((n) + (1))], + }; + this.rows.push(this.data.clone()); + this + } + pub unsafe fn Buffer_pmutBuffer(_a0: *mut Buffer) -> Self { + let mut this = Self { + data: std::mem::take(&mut (*_a0).data), + rows: std::mem::take(&mut (*_a0).rows), + n: (*_a0).n, + arr: std::array::from_fn::<_, 2, _>(|__i: usize| (*_a0).arr[(__i)]), + }; + this + } + pub unsafe fn operator_assign_pmutBuffer(&mut self, _a0: *mut Buffer) -> *mut Buffer { + self.data = std::mem::take(&mut (*_a0).data); + self.rows = std::mem::take(&mut (*_a0).rows); + self.n = (*_a0).n; + { + if 8_usize != 0 { + ::std::ptr::copy_nonoverlapping( + ((&mut (*_a0).arr as *mut [i32; 2]) as *const [i32; 2] + as *const ::libc::c_void), + ((&mut self.arr as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void), + 8_usize as usize, + ) + } + ((&mut self.arr as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void) + }; + return &mut (*(self as *mut Buffer)); + } +} +impl Default for Buffer { + fn default() -> Self { + Buffer { + data: Default::default(), + rows: Vec::new(), + n: 0_i32, + arr: [0_i32; 2], + } + } +} +#[repr(C)] +#[derive()] +pub struct Owner { + pub data: Vec, + pub n: i32, + pub arr: [i32; 2], + pub p: Option>, +} +impl Owner { + pub unsafe fn Owner_pmutOwner(_a0: *mut Owner) -> Self { + let mut this = Self { + data: std::mem::take(&mut (*_a0).data), + n: (*_a0).n, + arr: std::array::from_fn::<_, 2, _>(|__i: usize| (*_a0).arr[(__i)]), + p: (*_a0).p.take(), + }; + this + } + pub unsafe fn operator_assign_pmutOwner(&mut self, _a0: *mut Owner) -> *mut Owner { + self.data = std::mem::take(&mut (*_a0).data); + self.n = (*_a0).n; + { + if 8_usize != 0 { + ::std::ptr::copy_nonoverlapping( + ((&mut (*_a0).arr as *mut [i32; 2]) as *const [i32; 2] + as *const ::libc::c_void), + ((&mut self.arr as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void), + 8_usize as usize, + ) + } + ((&mut self.arr as *mut [i32; 2]) as *mut [i32; 2] as *mut ::libc::c_void) + }; + self.p = (*_a0).p.take(); + return &mut (*(self as *mut Owner)); + } +} +impl Default for Owner { + fn default() -> Self { + Owner { + data: Default::default(), + n: 0_i32, + arr: [0_i32; 2], + p: None, + } + } +} +#[repr(C)] +#[derive(Default)] +pub struct Holder { + pub inner: Inner, + pub e: Explicit, + pub p: Option>, +} +impl Holder { + pub unsafe fn Holder(mut v: i32) -> Self { + let mut this = Self { + inner: Inner { x: v }, + e: Explicit::Explicit({ v }), + p: None, + }; + this + } + pub unsafe fn Holder_pmutHolder(_a0: *mut Holder) -> Self { + let mut this = Self { + inner: (*_a0).inner, + e: (*_a0).e.clone(), + p: (*_a0).p.take(), + }; + this + } + pub unsafe fn operator_assign_pmutHolder(&mut self, _a0: *mut Holder) -> *mut Holder { + self.inner = (*_a0).inner; + self.e = ((*_a0).e).clone(); + self.p = (*_a0).p.take(); + return &mut (*(self as *mut Holder)); + } +} +impl Holder { + pub unsafe fn destructor(&mut self) { + Explicit::destructor(&mut self.e); + } +} +pub unsafe fn same_0(a: *const Explicit, b: *const Explicit) -> bool { + return (((((*a).v) == ((*b).v)) && (((*a).inner.x) == ((*b).inner.x))) + && (((*a).arr[(0) as usize]) == ((*b).arr[(0) as usize]))) + && (((*a).arr[(1) as usize]) == ((*b).arr[(1) as usize])); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: Explicit = Explicit::Explicit({ 1 }); + let _dtor_a = ScopedDestructorUnsafe::new(&raw mut a, Explicit::destructor); + let mut b: Explicit = a.clone(); + let _dtor_b = ScopedDestructorUnsafe::new(&raw mut b, Explicit::destructor); + let mut c: Explicit = a.clone(); + let _dtor_c = ScopedDestructorUnsafe::new(&raw mut c, Explicit::destructor); + let mut d: Explicit = a.clone(); + let _dtor_d = ScopedDestructorUnsafe::new(&raw mut d, Explicit::destructor); + assert!( + ((unsafe { same_0(&b, &a,) }) && (unsafe { same_0(&c, &a,) })) + && (unsafe { same_0(&d, &a,) }) + ); + let mut e: Explicit = Explicit::Explicit({ 2 }); + let _dtor_e = ScopedDestructorUnsafe::new(&raw mut e, Explicit::destructor); + let mut f: Explicit = Explicit::Explicit({ 3 }); + let _dtor_f = ScopedDestructorUnsafe::new(&raw mut f, Explicit::destructor); + e = (b).clone(); + f = (c).clone(); + assert!((unsafe { same_0(&e, &b,) }) && (unsafe { same_0(&f, &c,) })); + let mut g: Explicit = Explicit::Explicit({ 4 }); + let _dtor_g = ScopedDestructorUnsafe::new(&raw mut g, Explicit::destructor); + g = { + e = (f).clone(); + (e).clone() + }; + assert!((unsafe { same_0(&g, &f,) }) && (unsafe { same_0(&e, &f,) })); + let mut i: Implicit = Implicit { + v: 5, + inner: Inner { x: 50 }, + arr: [5, 6], + }; + let mut j: Implicit = i; + let mut k: Implicit = i; + assert!((((j.v) == (5)) && ((j.inner.x) == (50))) && ((j.arr[(1) as usize]) == (6))); + assert!(((i.v) == (5)) && ((k.v) == (5))); + let mut l: Implicit = Implicit { + v: 0, + inner: Inner { x: 0 }, + arr: [0, 0], + }; + l = j; + assert!((((l.v) == (5)) && ((l.inner.x) == (50))) && ((l.arr[(0) as usize]) == (5))); + let mut vec_: Vec = Vec::new(); + { + let a0_clone = b.clone(); + vec_.push(a0_clone) + }; + vec_.push(Explicit::Explicit({ 9 })); + assert!(((vec_[(0_usize)].v) == (1)) && ((vec_[(1_usize)].v) == (9))); + let mut m: DefaultCopyUserMove = DefaultCopyUserMove::DefaultCopyUserMove({ 7 }); + let mut m1: DefaultCopyUserMove = m; + let mut m2: DefaultCopyUserMove = + DefaultCopyUserMove::DefaultCopyUserMove_pmutDefaultCopyUserMove({ &mut m }); + assert!((((m1.v) == (7)) && ((m2.v) == (7))) && ((m.v) == (0))); + let mut m3: DefaultCopyUserMove = DefaultCopyUserMove::DefaultCopyUserMove({ 1 }); + let mut m4: DefaultCopyUserMove = DefaultCopyUserMove::DefaultCopyUserMove({ 1 }); + m3 = m1; + (unsafe { DefaultCopyUserMove::operator_assign_pmutDefaultCopyUserMove(&mut m4, &mut m1) }); + assert!((((m3.v) == (7)) && ((m4.v) == (7))) && ((m1.v) == (0))); + let mut u: UserCopyDefaultMove = UserCopyDefaultMove::UserCopyDefaultMove({ 8 }); + let mut u1: UserCopyDefaultMove = + UserCopyDefaultMove::UserCopyDefaultMove_pconstUserCopyDefaultMove({ &u }); + let mut u2: UserCopyDefaultMove = + UserCopyDefaultMove::UserCopyDefaultMove_pmutUserCopyDefaultMove({ &mut u }); + assert!((((u1.v) == (108)) && ((u2.v) == (8))) && ((u.v) == (8))); + let mut u3: UserCopyDefaultMove = UserCopyDefaultMove::UserCopyDefaultMove({ 1 }); + let mut u4: UserCopyDefaultMove = UserCopyDefaultMove::UserCopyDefaultMove({ 1 }); + (unsafe { UserCopyDefaultMove::operator_assign_pconstUserCopyDefaultMove(&mut u3, &u2) }); + (unsafe { UserCopyDefaultMove::operator_assign_pmutUserCopyDefaultMove(&mut u4, &mut u2) }); + assert!(((u3.v) == (108)) && ((u4.v) == (8))); + let mut p: Buffer = Buffer::Buffer({ 3 }); + let mut q: Buffer = Buffer::Buffer_pmutBuffer({ &mut p }); + assert!( + ((((q.n) == (3)) && ((q.data.len()) == (3_usize))) && ((q.data[(2_usize)]) == (3))) + && (p.data.is_empty()) + ); + let mut r: Buffer = Buffer::Buffer({ 1 }); + (unsafe { Buffer::operator_assign_pmutBuffer(&mut r, &mut q) }); + assert!( + ((((r.n) == (3)) && ((r.data.len()) == (3_usize))) && ((r.arr[(1) as usize]) == (4))) + && (q.data.is_empty()) + ); + assert!( + (((r.rows.len()) == (1_usize)) && ((r.rows[(0_usize)].len()) == (3_usize))) + && (q.rows.is_empty()) + ); + let mut bufs: Vec = Vec::new(); + bufs.push(Buffer::Buffer_pmutBuffer({ &mut r })); + { + let __arg = Buffer::Buffer_pmutBuffer({ &mut bufs[(0_usize)] }); + bufs.push(__arg) + }; + assert!( + (((bufs[(1_usize)].n) == (3)) && ((bufs[(1_usize)].data.len()) == (3_usize))) + && (bufs[(0_usize)].data.is_empty()) + ); + let mut o1: Owner = ::default(); + o1.data.push(5); + o1.n = 5; + o1.arr[(0) as usize] = 5; + o1.arr[(1) as usize] = 6; + { + let _a0: *mut i32 = (Box::leak(Box::new(7)) as *mut i32); + o1.p = if _a0.is_null() { + None + } else { + Some(Box::from_raw(_a0)) + } + }; + let mut o2: Owner = Owner::Owner_pmutOwner({ &mut o1 }); + assert!( + ((((o2.n) == (5)) && ((o2.data.len()) == (1_usize))) && ((o2.arr[(1) as usize]) == (6))) + && ((*o2.p.as_deref_mut().unwrap()) == (7)) + ); + assert!( + (o1.data.is_empty()) + && ((o1 + .p + .as_deref_mut() + .map_or(::std::ptr::null_mut(), |v| v as *mut i32)) + .is_null()) + ); + let mut o3: Owner = ::default(); + (unsafe { Owner::operator_assign_pmutOwner(&mut o3, &mut o2) }); + assert!( + ((((o3.n) == (5)) && ((o3.data[(0_usize)]) == (5))) && ((o3.arr[(0) as usize]) == (5))) + && ((*o3.p.as_deref_mut().unwrap()) == (7)) + ); + assert!( + (o2.data.is_empty()) + && ((o2 + .p + .as_deref_mut() + .map_or(::std::ptr::null_mut(), |v| v as *mut i32)) + .is_null()) + ); + let mut h1: Holder = Holder::Holder({ 4 }); + let _dtor_h1 = ScopedDestructorUnsafe::new(&raw mut h1, Holder::destructor); + { + let _a0: *mut i32 = (Box::leak(Box::new(9)) as *mut i32); + h1.p = if _a0.is_null() { + None + } else { + Some(Box::from_raw(_a0)) + } + }; + let mut h2: Holder = Holder::Holder_pmutHolder({ &mut h1 }); + let _dtor_h2 = ScopedDestructorUnsafe::new(&raw mut h2, Holder::destructor); + assert!( + ((((h2.inner.x) == (4)) && ((h2.e.v) == (4))) && ((*h2.p.as_deref_mut().unwrap()) == (9))) + && ((h1 + .p + .as_deref_mut() + .map_or(::std::ptr::null_mut(), |v| v as *mut i32)) + .is_null()) + ); + let mut h3: Holder = Holder::Holder({ 1 }); + let _dtor_h3 = ScopedDestructorUnsafe::new(&raw mut h3, Holder::destructor); + (unsafe { Holder::operator_assign_pmutHolder(&mut h3, &mut h2) }); + assert!( + ((((h3.inner.x) == (4)) && ((h3.e.arr[(1) as usize]) == (5))) + && ((*h3.p.as_deref_mut().unwrap()) == (9))) + && ((h2 + .p + .as_deref_mut() + .map_or(::std::ptr::null_mut(), |v| v as *mut i32)) + .is_null()) + ); + return 0; +} diff --git a/tests/unit/out/unsafe/copy_move_deleted.rs b/tests/unit/out/unsafe/copy_move_deleted.rs new file mode 100644 index 00000000..ac5257ac --- /dev/null +++ b/tests/unit/out/unsafe/copy_move_deleted.rs @@ -0,0 +1,135 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[repr(C)] +#[derive(Default)] +pub struct NoCopy { + pub v: i32, +} +impl NoCopy { + pub unsafe fn NoCopy(mut v: i32) -> Self { + let mut this = Self { v: v }; + this + } + pub unsafe fn NoCopy_pmutNoCopy(o: *mut NoCopy) -> Self { + let mut this = Self { v: (*o).v }; + (*o).v = 0; + this + } + pub unsafe fn operator_assign_pmutNoCopy(&mut self, o: *mut NoCopy) -> *mut NoCopy { + self.v = (*o).v; + (*o).v = 0; + return &mut (*(self as *mut NoCopy)); + } +} +#[repr(C)] +#[derive()] +pub struct PrivateCopy { + pub v: i32, +} +impl PrivateCopy { + pub unsafe fn PrivateCopy() -> Self { + let mut this = Self { v: 0 }; + this + } + pub unsafe fn PrivateCopy_pmutPrivateCopy(o: *mut PrivateCopy) -> Self { + let mut this = Self { v: (*o).v }; + (*o).v = 0; + this + } + pub unsafe fn operator_assign_pmutPrivateCopy( + &mut self, + o: *mut PrivateCopy, + ) -> *mut PrivateCopy { + self.v = (*o).v; + (*o).v = 0; + return &mut (*(self as *mut PrivateCopy)); + } +} +impl Default for PrivateCopy { + fn default() -> Self { + unsafe { PrivateCopy::PrivateCopy() } + } +} +#[repr(C)] +#[derive()] +pub struct Immovable { + pub v: i32, +} +impl Immovable { + pub unsafe fn Immovable() -> Self { + let mut this = Self { v: 0 }; + this + } +} +impl Default for Immovable { + fn default() -> Self { + unsafe { Immovable::Immovable() } + } +} +#[repr(C)] +#[derive(Default)] +pub struct Container { + pub inner: NoCopy, + pub tag: i32, +} +impl Container { + pub unsafe fn Container_pmutContainer(_a0: *mut Container) -> Self { + let mut this = Self { + inner: NoCopy::NoCopy_pmutNoCopy({ &mut (*_a0).inner }), + tag: (*_a0).tag, + }; + this + } + pub unsafe fn operator_assign_pmutContainer(&mut self, _a0: *mut Container) -> *mut Container { + (unsafe { + let _o: *mut NoCopy = &mut (*_a0).inner; + NoCopy::operator_assign_pmutNoCopy(&mut self.inner, _o) + }); + self.tag = (*_a0).tag; + return &mut (*(self as *mut Container)); + } +} +pub unsafe fn bump_0(mut p: *mut NoCopy) { + (*p).v.postfix_inc(); +} +pub unsafe fn bump_ref_1(r: *mut Immovable) { + (*r).v.postfix_inc(); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: NoCopy = NoCopy::NoCopy({ 1 }); + let mut b: NoCopy = NoCopy::NoCopy_pmutNoCopy({ &mut a }); + assert!(((b.v) == (1)) && ((a.v) == (0))); + (unsafe { NoCopy::operator_assign_pmutNoCopy(&mut a, &mut b) }); + assert!(((a.v) == (1)) && ((b.v) == (0))); + (unsafe { bump_0((&mut a as *mut NoCopy)) }); + assert!(((a.v) == (2))); + let mut p: PrivateCopy = PrivateCopy::PrivateCopy(); + p.v = 3; + let mut q: PrivateCopy = PrivateCopy::PrivateCopy_pmutPrivateCopy({ &mut p }); + assert!(((q.v) == (3)) && ((p.v) == (0))); + (unsafe { PrivateCopy::operator_assign_pmutPrivateCopy(&mut p, &mut q) }); + assert!(((p.v) == (3)) && ((q.v) == (0))); + let mut im: Immovable = Immovable::Immovable(); + im.v = 4; + (unsafe { bump_ref_1(&mut im) }); + let mut pim: *mut Immovable = (&mut im as *mut Immovable); + assert!((((*pim).v) == (5))); + let mut c: Container = Container { + inner: NoCopy::NoCopy({ 6 }), + tag: 7, + }; + let mut d: Container = Container::Container_pmutContainer({ &mut c }); + assert!((((d.inner.v) == (6)) && ((d.tag) == (7))) && ((c.inner.v) == (0))); + return 0; +} diff --git a/tests/unit/out/unsafe/huffman.rs b/tests/unit/out/unsafe/huffman.rs index ce0a4293..ba9e4a2e 100644 --- a/tests/unit/out/unsafe/huffman.rs +++ b/tests/unit/out/unsafe/huffman.rs @@ -125,6 +125,24 @@ impl MinHeap { i.prefix_dec(); } } + pub unsafe fn MinHeap_pmutMinHeap(_a0: *mut MinHeap) -> Self { + let mut this = Self { + size: (*_a0).size, + capacity: (*_a0).capacity, + arr: (*_a0).arr.take(), + next: (*_a0).next, + alloc: (*_a0).alloc.take(), + }; + this + } + pub unsafe fn operator_assign_pmutMinHeap(&mut self, _a0: *mut MinHeap) -> *mut MinHeap { + self.size = (*_a0).size; + self.capacity = (*_a0).capacity; + self.arr = (*_a0).arr.take(); + self.next = (*_a0).next; + self.alloc = (*_a0).alloc.take(); + return &mut (*(self as *mut MinHeap)); + } } pub unsafe fn AllocMinHeap_1(mut capacity: i32) -> Option> { let mut minHeap: Option> = Some(Box::new(MinHeap { diff --git a/tests/unit/out/unsafe/kruskal.rs b/tests/unit/out/unsafe/kruskal.rs index cb48b4dc..5fa31aae 100644 --- a/tests/unit/out/unsafe/kruskal.rs +++ b/tests/unit/out/unsafe/kruskal.rs @@ -138,6 +138,23 @@ impl DisjointSet { ((self.rank.as_mut().unwrap()[(xset as usize)]) + (1)); } } + pub unsafe fn DisjointSet_pmutDisjointSet(_a0: *mut DisjointSet) -> Self { + let mut this = Self { + rank: (*_a0).rank.take(), + parent: (*_a0).parent.take(), + n: (*_a0).n, + }; + this + } + pub unsafe fn operator_assign_pmutDisjointSet( + &mut self, + _a0: *mut DisjointSet, + ) -> *mut DisjointSet { + self.rank = (*_a0).rank.take(); + self.parent = (*_a0).parent.take(); + self.n = (*_a0).n; + return &mut (*(self as *mut DisjointSet)); + } } #[repr(C)] #[derive(Default)] @@ -146,6 +163,22 @@ pub struct Graph { pub V: i32, pub E: i32, } +impl Graph { + pub unsafe fn Graph_pmutGraph(_a0: *mut Graph) -> Self { + let mut this = Self { + edges: (*_a0).edges.take(), + V: (*_a0).V, + E: (*_a0).E, + }; + this + } + pub unsafe fn operator_assign_pmutGraph(&mut self, _a0: *mut Graph) -> *mut Graph { + self.edges = (*_a0).edges.take(); + self.V = (*_a0).V; + self.E = (*_a0).E; + return &mut (*(self as *mut Graph)); + } +} pub unsafe fn MSTKruskal_2(graph: *mut Graph) -> f64 { (unsafe { let _arr: *mut Option> = &mut (*graph).edges; diff --git a/tests/unit/out/unsafe/move_assign.rs b/tests/unit/out/unsafe/move_assign.rs index 5c9f54c9..da0855c8 100644 --- a/tests/unit/out/unsafe/move_assign.rs +++ b/tests/unit/out/unsafe/move_assign.rs @@ -83,7 +83,7 @@ unsafe fn main_0() -> i32 { (unsafe { MoveOnly::operator_assign_pmutMoveOnly( &mut c, - (unsafe { MoveOnly::operator_assign_pmutMoveOnly(&mut a, &mut b) }), + &mut (*(unsafe { MoveOnly::operator_assign_pmutMoveOnly(&mut a, &mut b) })), ) }); assert!((((b.v) == (0)) && ((a.v) == (0))) && ((c.v) == (3))); diff --git a/tests/unit/out/unsafe/move_ctor.rs b/tests/unit/out/unsafe/move_ctor.rs index a7614be6..e6e83f28 100644 --- a/tests/unit/out/unsafe/move_ctor.rs +++ b/tests/unit/out/unsafe/move_ctor.rs @@ -81,7 +81,7 @@ unsafe fn main_0() -> i32 { let mut vec_: Vec = Vec::new(); vec_.push(MoveOnly::MoveOnly({ 7 })); let mut f: MoveOnly = MoveOnly::MoveOnly({ 8 }); - vec_.push(std::mem::take(&mut f)); + vec_.push(MoveOnly::MoveOnly_pmutMoveOnly({ &mut f })); assert!(((vec_[(0_usize)].v) == (7)) && ((vec_[(1_usize)].v) == (8))); assert!(((f.v) == (0))); let mut m: ConstMove = ConstMove::ConstMove(); diff --git a/tests/unit/out/unsafe/move_this.rs b/tests/unit/out/unsafe/move_this.rs index 75b912f1..d4d939fd 100644 --- a/tests/unit/out/unsafe/move_this.rs +++ b/tests/unit/out/unsafe/move_this.rs @@ -35,16 +35,16 @@ impl Chain { } pub unsafe fn add_i32_rref(&mut self, mut n: i32) -> *mut Chain { self.v += n; - return (self as *mut Chain); + return &mut (*(self as *mut Chain)); } pub unsafe fn take(&mut self) -> Chain { - return Chain::Chain_pmutChain({ (self as *mut Chain) }); + return Chain::Chain_pmutChain({ &mut (*(self as *mut Chain)) }); } pub unsafe fn copy(&self) -> Chain { return Chain::Chain_pconstChain({ &(*(self as *const Chain)) }); } pub unsafe fn self_(&mut self) -> *mut Chain { - return (self as *mut Chain); + return &mut (*(self as *mut Chain)); } } impl Clone for Chain { diff --git a/tests/unit/out/unsafe/operator_comparison_noncopyable.rs b/tests/unit/out/unsafe/operator_comparison_noncopyable.rs index a4f9676d..1593443c 100644 --- a/tests/unit/out/unsafe/operator_comparison_noncopyable.rs +++ b/tests/unit/out/unsafe/operator_comparison_noncopyable.rs @@ -22,6 +22,12 @@ impl S { let mut this = Self { data_: data }; this } + pub unsafe fn S_pmutS(_a0: *mut S) -> Self { + let mut this = Self { + data_: (*_a0).data_, + }; + this + } } impl std::cmp::Ord for S { fn cmp(&self, other: &Self) -> std::cmp::Ordering { diff --git a/tests/unit/out/unsafe/push_emplace_back.rs b/tests/unit/out/unsafe/push_emplace_back.rs index 9c295cd6..14ef3b9c 100644 --- a/tests/unit/out/unsafe/push_emplace_back.rs +++ b/tests/unit/out/unsafe/push_emplace_back.rs @@ -48,7 +48,7 @@ pub unsafe fn shrink_through_ptr_2(mut comps: *mut Vec) { (*comps).shrink_to_fit(); } pub unsafe fn nested_push_move_3(mut bw: *mut Writer) { - (*(*bw).output).push(std::mem::take(&mut (*bw).chunk)); + (*(*bw).output).push((*bw).chunk); } pub unsafe fn emplace_local_from_field_4(mut jpg: *mut JPEGData, mut cond: bool) { let mut head: [u8; 3] = [1_u8, 2_u8, 3_u8]; @@ -69,7 +69,10 @@ pub unsafe fn emplace_local_from_field_4(mut jpg: *mut JPEGData, mut cond: bool) ); } pub unsafe fn nested_emplace_move_5(mut bw: *mut Writer) { - (*(*bw).output).push(std::mem::take(&mut (*bw).chunk)); + { + let __arg = (*bw).chunk; + (*(*bw).output).push(__arg) + }; } pub unsafe fn self_ref_push_6(mut comps: *mut Vec) { { diff --git a/tests/unit/out/unsafe/rule_of_three.rs b/tests/unit/out/unsafe/rule_of_three.rs index f358e026..b08a1eed 100644 --- a/tests/unit/out/unsafe/rule_of_three.rs +++ b/tests/unit/out/unsafe/rule_of_three.rs @@ -107,11 +107,11 @@ unsafe fn main_0() -> i32 { assert!(((copies_1) == (2))); assert!(((unsafe { sum_2(&a,) }) == (6))); assert!(((unsafe { sum_2(&b,) }) == (106))); - let mut d: Buffer = Buffer::Buffer_pconstBuffer({ &mut a }); + let mut d: Buffer = Buffer::Buffer_pconstBuffer({ &a }); let _dtor_d = ScopedDestructorUnsafe::new(&raw mut d, Buffer::destructor); assert!(((alive_0) == (4)) && ((copies_1) == (3))); assert!(((a.size) == (4)) && ((a.data[(3) as usize]) == (3))); - (unsafe { Buffer::operator_assign(&mut d, &mut b) }); + (unsafe { Buffer::operator_assign(&mut d, &b) }); assert!(((copies_1) == (4))); assert!(((b.data[(0) as usize]) == (100)) && ((d.data[(0) as usize]) == (100))); } diff --git a/tests/unit/out/unsafe/unique_ptr.rs b/tests/unit/out/unsafe/unique_ptr.rs index 5b700600..3dc2ecc4 100644 --- a/tests/unit/out/unsafe/unique_ptr.rs +++ b/tests/unit/out/unsafe/unique_ptr.rs @@ -15,6 +15,19 @@ impl SafePointer { pub unsafe fn inc(&mut self) { (*self.ptr.as_deref_mut().unwrap()).prefix_inc(); } + pub unsafe fn SafePointer_pmutSafePointer(_a0: *mut SafePointer) -> Self { + let mut this = Self { + ptr: (*_a0).ptr.take(), + }; + this + } + pub unsafe fn operator_assign_pmutSafePointer( + &mut self, + _a0: *mut SafePointer, + ) -> *mut SafePointer { + self.ptr = (*_a0).ptr.take(); + return &mut (*(self as *mut SafePointer)); + } } #[repr(C)] #[derive(Copy, Clone, Default)] diff --git a/tests/unit/out/unsafe/unique_ptr_const_deref.rs b/tests/unit/out/unsafe/unique_ptr_const_deref.rs index 2de99893..0da6adde 100644 --- a/tests/unit/out/unsafe/unique_ptr_const_deref.rs +++ b/tests/unit/out/unsafe/unique_ptr_const_deref.rs @@ -11,6 +11,18 @@ use std::rc::Rc; pub struct Holder { pub val: Option>, } +impl Holder { + pub unsafe fn Holder_pmutHolder(_a0: *mut Holder) -> Self { + let mut this = Self { + val: (*_a0).val.take(), + }; + this + } + pub unsafe fn operator_assign_pmutHolder(&mut self, _a0: *mut Holder) -> *mut Holder { + self.val = (*_a0).val.take(); + return &mut (*(self as *mut Holder)); + } +} pub unsafe fn read_val_0(mut h: *const Holder) -> i32 { return (*(*(std::ptr::addr_of!((*h).val).cast_mut())) .as_deref_mut() diff --git a/tests/unit/out/unsafe/unique_ptr_nested.rs b/tests/unit/out/unsafe/unique_ptr_nested.rs index 02c01c14..f13ecaa3 100644 --- a/tests/unit/out/unsafe/unique_ptr_nested.rs +++ b/tests/unit/out/unsafe/unique_ptr_nested.rs @@ -17,6 +17,18 @@ pub struct Inner { pub struct Outer { pub inner: Option>, } +impl Outer { + pub unsafe fn Outer_pmutOuter(_a0: *mut Outer) -> Self { + let mut this = Self { + inner: (*_a0).inner.take(), + }; + this + } + pub unsafe fn operator_assign_pmutOuter(&mut self, _a0: *mut Outer) -> *mut Outer { + self.inner = (*_a0).inner.take(); + return &mut (*(self as *mut Outer)); + } +} pub fn main() { unsafe { std::process::exit(main_0() as i32); diff --git a/tests/unit/out/unsafe/void_cast.rs b/tests/unit/out/unsafe/void_cast.rs index aea1827d..71f34c2f 100644 --- a/tests/unit/out/unsafe/void_cast.rs +++ b/tests/unit/out/unsafe/void_cast.rs @@ -35,6 +35,21 @@ pub struct Holder { pub struct NonCopyable { pub value: Option>, } +impl NonCopyable { + pub unsafe fn NonCopyable_pmutNonCopyable(_a0: *mut NonCopyable) -> Self { + let mut this = Self { + value: (*_a0).value.take(), + }; + this + } + pub unsafe fn operator_assign_pmutNonCopyable( + &mut self, + _a0: *mut NonCopyable, + ) -> *mut NonCopyable { + self.value = (*_a0).value.take(); + return &mut (*(self as *mut NonCopyable)); + } +} pub unsafe fn unused_noncopyable_param_5(x: *const NonCopyable) { &(*x); }