File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -592,6 +592,14 @@ void Converter::EmitScopedDestructor(const clang::VarDecl *decl) {
592592 return ;
593593 }
594594 auto type = decl->getType ();
595+ if (auto lambda = AsLambdaClass (type);
596+ lambda && LambdaNeedsDestruction (lambda)) {
597+ StrCat (token::kSemiColon ,
598+ std::format (" let _dtor_{0} = ScopedDestructorUnsafe::new(&raw mut "
599+ " {0}, |__f| __f.destroy())" ,
600+ GetNamedDeclAsString (decl)));
601+ return ;
602+ }
595603 if (type->isReferenceType () || type->isArrayType () ||
596604 !TypeNeedsDestruction (type)) {
597605 return ;
@@ -3865,6 +3873,11 @@ bool Converter::VisitLambdaExpr(clang::LambdaExpr *expr) {
38653873 StrCat (token::kComma );
38663874 ConvertLambdaClosure (decl);
38673875 ConvertLambdaCopyAndMove (decl);
3876+ if (LambdaNeedsDestruction (decl)) {
3877+ StrCat (token::kComma , " destroy" , token::kAssign );
3878+ PushBrace destroy (*this );
3879+ StrCat (DestroyMembers (decl));
3880+ }
38683881 computed_expr_type_ = ComputedExprType::FreshValue;
38693882 return false ;
38703883}
Original file line number Diff line number Diff line change @@ -1088,6 +1088,12 @@ bool IsLambdaCopyOrMoveConstructor(const clang::CXXConstructorDecl *ctor) {
10881088 !decl->captures ().empty ();
10891089}
10901090
1091+ bool LambdaNeedsDestruction (const clang::CXXRecordDecl *decl) {
1092+ return llvm::any_of (decl->fields (), [](const clang::FieldDecl *field) {
1093+ return TypeNeedsDestruction (field->getType ());
1094+ });
1095+ }
1096+
10911097clang::Expr *AsLambdaUncapturedConstant (const clang::FunctionDecl *fn,
10921098 clang::DeclRefExpr *expr) {
10931099 if (!AsLambdaOperatorCall (fn)) {
Original file line number Diff line number Diff line change @@ -206,6 +206,8 @@ const clang::LambdaCapture *AsLambdaCapture(const clang::FieldDecl *field);
206206
207207bool IsLambdaCopyOrMoveConstructor (const clang::CXXConstructorDecl *ctor);
208208
209+ bool LambdaNeedsDestruction (const clang::CXXRecordDecl *decl);
210+
209211clang::Expr *AsLambdaUncapturedConstant (const clang::FunctionDecl *fn,
210212 clang::DeclRefExpr *expr);
211213
Original file line number Diff line number Diff line change @@ -873,6 +873,14 @@ void ConverterRefCount::EmitScopedDestructor(const clang::VarDecl *decl) {
873873 return ;
874874 }
875875 auto type = decl->getType ();
876+ if (auto lambda = AsLambdaClass (type);
877+ lambda && LambdaNeedsDestruction (lambda)) {
878+ StrCat (token::kSemiColon ,
879+ std::format (" let _dtor_{0} = ScopedDestructor::new(&{0}, |__p| "
880+ " __p.with(|__f| __f.destroy()))" ,
881+ GetNamedDeclAsString (decl)));
882+ return ;
883+ }
876884 if (type->isReferenceType () || type->isArrayType () ||
877885 !TypeNeedsDestruction (type)) {
878886 return ;
@@ -3423,6 +3431,12 @@ ConverterRefCount::DestroyMembers(const clang::CXXRecordDecl *decl) {
34233431 std::string out;
34243432 for (auto *field : std::ranges::reverse_view (fields)) {
34253433 auto name = GetNamedDeclAsString (field);
3434+ if (decl->isLambda ()) {
3435+ assert (!field->getType ()->isArrayType ());
3436+ out +=
3437+ std::format (" self.{0}.as_pointer().{1}();\n " , name, kDestructorName );
3438+ continue ;
3439+ }
34263440 if (field->getType ()->isArrayType ()) {
34273441 auto *elem =
34283442 field->getType ()->getBaseElementTypeUnsafe ()->getAsCXXRecordDecl ();
You can’t perform that action at this time.
0 commit comments