diff --git a/src/Expr.cc b/src/Expr.cc index bcd9ac96ae..3183743043 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -4726,7 +4726,7 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) for ( const auto& c : *captures ) { - auto cid = c.id.get(); + auto cid = c.Id().get(); if ( ! cid ) // This happens for undefined/inappropriate @@ -4768,7 +4768,7 @@ bool LambdaExpr::CheckCaptures(StmtPtr when_parent) for ( const auto& c : *captures ) { - auto cid = c.id.get(); + auto cid = c.Id().get(); if ( cid && capture_is_matched.count(cid) == 0 ) { auto msg = util::fmt("%s is captured but not used inside %s", cid->Name(), desc); diff --git a/src/Stmt.cc b/src/Stmt.cc index 5cfb7bb914..0f6bd043f0 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -2018,7 +2018,7 @@ WhenInfo::WhenInfo(ExprPtr arg_cond, FuncType::CaptureList* arg_cl, bool arg_is_ bool is_present = false; for ( auto& c : *cl ) - if ( c.id == wl ) + if ( c.Id() == wl ) { is_present = true; break; diff --git a/src/Type.cc b/src/Type.cc index 469a7ba6fd..2bb7279c10 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -699,6 +699,12 @@ TypePtr SetType::ShallowClone() SetType::~SetType() = default; +FuncType::Capture::Capture(detail::IDPtr _id, bool _deep_copy) + : id(std::move(_id)), deep_copy(_deep_copy) + { + is_managed = id ? ZVal::IsManagedType(id->GetType()) : false; + } + FuncType::FuncType(RecordTypePtr arg_args, TypePtr arg_yield, FunctionFlavor arg_flavor) : Type(TYPE_FUNC), args(std::move(arg_args)), arg_types(make_intrusive()), yield(std::move(arg_yield)) diff --git a/src/Type.h b/src/Type.h index 020ab6e358..38a08a5c7f 100644 --- a/src/Type.h +++ b/src/Type.h @@ -511,10 +511,22 @@ public: /** * A single lambda "capture" (outer variable used in a lambda's body). */ - struct Capture + class Capture { + public: + Capture(detail::IDPtr _id, bool _deep_copy); + + auto& Id() const { return id; } + bool IsDeepCopy() const { return deep_copy; } + bool IsManaged() const { return is_managed; } + + // For script optimization: + void SetID(detail::IDPtr new_id) { id = std::move(new_id); } + + private: detail::IDPtr id; bool deep_copy; + bool is_managed; }; using CaptureList = std::vector; diff --git a/src/parse.y b/src/parse.y index d16fc5042c..2a44660d56 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1640,9 +1640,7 @@ capture: delete [] $2; - $$ = new FuncType::Capture; - $$->id = id; - $$->deep_copy = $1; + $$ = new FuncType::Capture(id, $1); } ; diff --git a/src/script_opt/CPP/Exprs.cc b/src/script_opt/CPP/Exprs.cc index c9cde5ab0c..90e7b0bd8d 100644 --- a/src/script_opt/CPP/Exprs.cc +++ b/src/script_opt/CPP/Exprs.cc @@ -1301,7 +1301,7 @@ string CPPCompile::GenLambdaClone(const LambdaExpr* l, bool all_deep) if ( captures && ! IsNativeType(id_t) ) { for ( const auto& c : *captures ) - if ( id == c.id && (c.deep_copy || all_deep) ) + if ( id == c.Id() && (c.IsDeepCopy() || all_deep) ) arg = string("cast_intrusive<") + TypeName(id_t) + ">(" + arg + "->Clone())"; }