Skip to content

Commit a9d98fe

Browse files
committed
Use ConvertFunctionPointerType for lambda operator()
1 parent 2925eaa commit a9d98fe

6 files changed

Lines changed: 53 additions & 16 deletions

File tree

cpp2rust/converter/converter.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,11 @@ bool Converter::VisitRecordType(clang::RecordType *type) {
131131
if (auto lambda = clang::dyn_cast<clang::CXXRecordDecl>(decl)) {
132132
if (lambda->isLambda()) {
133133
if (in_function_formals_) {
134-
auto call_op = lambda->getLambdaCallOperator();
135-
StrCat("impl Fn(");
136-
for (auto p : call_op->parameters()) {
137-
StrCat(std::format("{},", ToStringBase(p->getType())));
138-
}
139-
StrCat(")");
140-
if (!call_op->getReturnType()->isVoidType()) {
141-
StrCat("->");
142-
StrCat(ToStringBase(call_op->getReturnType()));
143-
}
134+
StrCat(
135+
ConvertFunctionPointerType(lambda->getLambdaCallOperator()
136+
->getType()
137+
->getAs<clang::FunctionProtoType>(),
138+
FnProtoType::LambdaCallOperator));
144139
} else {
145140
StrCat("_");
146141
}
@@ -226,8 +221,10 @@ bool Converter::VisitLValueReferenceType(clang::LValueReferenceType *type) {
226221
}
227222

228223
std::string
229-
Converter::ConvertFunctionPointerType(const clang::FunctionProtoType *proto) {
230-
std::string result = "fn(";
224+
Converter::ConvertFunctionPointerType(const clang::FunctionProtoType *proto,
225+
FnProtoType kind) {
226+
std::string result =
227+
(kind == FnProtoType::LambdaCallOperator ? "impl Fn(" : "fn(");
231228
for (auto p_ty : proto->param_types()) {
232229
result += ToString(p_ty) + ",";
233230
}

cpp2rust/converter/converter.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,11 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
6161

6262
virtual bool VisitPointerType(clang::PointerType *type);
6363

64+
enum class FnProtoType { LambdaCallOperator, FnPtr };
65+
6466
virtual std::string
65-
ConvertFunctionPointerType(const clang::FunctionProtoType *proto);
67+
ConvertFunctionPointerType(const clang::FunctionProtoType *proto,
68+
FnProtoType kind = FnProtoType::FnPtr);
6669

6770
virtual bool VisitDecayedType(clang::DecayedType *type);
6871

cpp2rust/converter/models/converter_refcount.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,9 @@ std::string ConverterRefCount::BuildFnAdapter(
221221
}
222222

223223
std::string ConverterRefCount::ConvertFunctionPointerType(
224-
const clang::FunctionProtoType *proto) {
224+
const clang::FunctionProtoType *proto, FnProtoType kind) {
225225
PushConversionKind push(*this, ConversionKind::Unboxed);
226-
return Converter::ConvertFunctionPointerType(proto);
226+
return Converter::ConvertFunctionPointerType(proto, kind);
227227
}
228228

229229
bool ConverterRefCount::VisitPointerType(clang::PointerType *type) {

cpp2rust/converter/models/converter_refcount.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class ConverterRefCount final : public Converter {
2323
bool VisitPointerType(clang::PointerType *type) override;
2424

2525
std::string
26-
ConvertFunctionPointerType(const clang::FunctionProtoType *proto) override;
26+
ConvertFunctionPointerType(const clang::FunctionProtoType *proto,
27+
FnProtoType kind = FnProtoType::FnPtr) override;
2728

2829
bool VisitCXXRecordDecl(clang::CXXRecordDecl *decl) override;
2930

tests/unit/lambda_capture_pass.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <assert.h>
2+
3+
template <typename F> int apply(F fn, int x) { return fn(x); }
4+
5+
int main() {
6+
int base = 10;
7+
8+
auto add_base = [&base](int x) { return x + base; };
9+
assert(apply(add_base, 5) == 15);
10+
11+
base = 100;
12+
assert(apply(add_base, 5) == 105);
13+
14+
int factor = 3;
15+
auto scale = [factor](int x) { return x * factor; };
16+
assert(apply(scale, 4) == 12);
17+
18+
return 0;
19+
}

tests/unit/lambda_nested.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <assert.h>
2+
3+
int main() {
4+
int x = 10;
5+
6+
auto outer = [&x](int y) {
7+
auto inner = [&x, y](int z) { return x + y + z; };
8+
return inner(1);
9+
};
10+
11+
assert(outer(20) == 31);
12+
13+
x = 100;
14+
assert(outer(20) == 121);
15+
16+
return 0;
17+
}

0 commit comments

Comments
 (0)