Skip to content

Commit 4bd0c04

Browse files
committed
Emit anonymous functions as mutable lambdas
This example now works: main: () = { v: std::vector = ( 1, 2, 3, 4, 5 ); // Definite last use of v => move-capture v into f's closure f := :() -> forward _ = v$; // Now we can access the vector captured inside f()... f().push_back(6); for f() do(e) std::cout << e; // prints 123456 }
1 parent 0b333f3 commit 4bd0c04

17 files changed

+40
-34
lines changed

include/cpp2util.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ auto is( X const& x ) -> bool {
10791079

10801080
// Values
10811081
//
1082-
inline constexpr auto is( auto const& x, auto const& value ) -> bool
1082+
inline constexpr auto is( auto const& x, auto&& value ) -> bool
10831083
{
10841084
// Value with customized operator_is case
10851085
if constexpr (requires{ x.op_is(value); }) {
@@ -1313,7 +1313,7 @@ auto is( std::variant<Ts...> const& x );
13131313
// is Value
13141314
//
13151315
template<typename... Ts>
1316-
constexpr auto is( std::variant<Ts...> const& x, auto const& value ) -> bool
1316+
constexpr auto is( std::variant<Ts...> const& x, auto&& value ) -> bool
13171317
{
13181318
// Predicate case
13191319
if constexpr (requires{ bool{ value(operator_as< 0>(x)) }; }) { if (x.index() == 0) return value(operator_as< 0>(x)); }
@@ -1494,7 +1494,7 @@ constexpr auto is( X const& x ) -> bool
14941494

14951495
// is Value
14961496
//
1497-
inline constexpr auto is( std::any const& x, auto const& value ) -> bool
1497+
inline constexpr auto is( std::any const& x, auto&& value ) -> bool
14981498
{
14991499
// Predicate case
15001500
if constexpr (requires{ bool{ value(x) }; }) {
@@ -1542,7 +1542,7 @@ constexpr auto is( std::optional<U> const& x ) -> bool
15421542
// is Value
15431543
//
15441544
template<typename T>
1545-
constexpr auto is( std::optional<T> const& x, auto const& value ) -> bool
1545+
constexpr auto is( std::optional<T> const& x, auto&& value ) -> bool
15461546
{
15471547
// Predicate case
15481548
if constexpr (requires{ bool{ value(x) }; }) {
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
pure2-bugfix-for-non-local-function-expression.cpp2:5:34: error: lambda expression in an unevaluated operand
2-
template<typename T> concept v = []() -> bool { return true; }();
2+
template<typename T> concept v = []() mutable -> bool { return true; }();
33
^
44
pure2-bugfix-for-non-local-function-expression.cpp2:7:41: error: lambda expression in an unevaluated operand
5-
using u = std::type_identity_t<decltype([]() -> void{})>;
5+
using u = std::type_identity_t<decltype([]() mutable -> void{})>;
66
^
77
pure2-bugfix-for-non-local-function-expression.cpp2:9:47: error: lambda expression in an unevaluated operand
8-
class t: public std::type_identity_t<decltype([]() -> void{})> {
8+
class t: public std::type_identity_t<decltype([]() mutable -> void{})> {
99
^
1010
3 errors generated.

regression-tests/test-results/mixed-captures-in-expressions-and-postconditions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ auto insert_at(cpp2::in<int> where, cpp2::in<int> val) -> void;
3333
"hello", "2022"};
3434

3535
std::string y {"\n"};
36-
auto callback {[_0 = (&y)](auto const& x) -> void { std::cout << x << *cpp2::assert_not_null(_0); }};
36+
auto callback {[_0 = (&y)](auto const& x) mutable -> void { std::cout << x << *cpp2::assert_not_null(_0); }};
3737

3838
std::ranges::for_each(vec, callback);
3939
y = "-ish\n";

regression-tests/test-results/mixed-function-expression-and-std-for-each.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@
3232
// Passing a function expression
3333
std::ranges::for_each(
3434
vec,
35-
[](auto& x) -> void { x += "-ish"; }
35+
[](auto& x) mutable -> void { x += "-ish"; }
3636
);
3737

3838
// Initializing from a function expression
39-
auto callback {[](auto& x) -> void { x += " maybe"; }};
39+
auto callback {[](auto& x) mutable -> void { x += " maybe"; }};
4040
std::ranges::for_each(
4141
vec,
4242
std::move(callback)

regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each-with-capture.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232

3333
auto y {"\n"};
3434
std::ranges::for_each
35-
(vec, [_0 = std::move(y)](auto const& x) -> void { std::cout << x << _0; });
35+
(vec, [_0 = std::move(y)](auto const& x) mutable -> void { std::cout << x << _0; });
3636

37-
auto callback {[](auto& x) -> void { x += "-ish"; }};
37+
auto callback {[](auto& x) mutable -> void { x += "-ish"; }};
3838
std::ranges::for_each(vec, std::move(callback));
3939

4040
for ( auto const& str : vec )

regression-tests/test-results/mixed-function-expression-and-std-ranges-for-each.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@
3131
"hello", "2022"};
3232

3333
std::ranges::for_each
34-
(vec, [](auto const& x) -> void { std::cout << x << "\n"; });
34+
(vec, [](auto const& x) mutable -> void { std::cout << x << "\n"; });
3535

36-
auto callback {[](auto& x) -> void { x += "-ish"; }};
36+
auto callback {[](auto& x) mutable -> void { x += "-ish"; }};
3737
std::ranges::for_each(vec, std::move(callback));
3838

3939
for ( auto const& str : vec )

regression-tests/test-results/mixed-function-expression-with-pointer-capture.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131
"hello", "2023"};
3232

3333
std::string y {"\n"};
34-
std::ranges::for_each(vec, [_0 = (&y)](auto const& x) -> void {
34+
std::ranges::for_each(vec, [_0 = (&y)](auto const& x) mutable -> void {
3535
std::cout << CPP2_UFCS_0(c_str, (*cpp2::assert_not_null(_0))) << x << *cpp2::assert_not_null(_0); }
3636
);
3737

38-
auto callback {[](auto& x) -> void { x += "-ish"; }};
38+
auto callback {[](auto& x) mutable -> void { x += "-ish"; }};
3939
std::ranges::for_each(vec, std::move(callback));
4040

4141
for ( auto const& str : vec )

regression-tests/test-results/mixed-function-expression-with-repeated-capture.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232

3333
auto y {"\n"};
3434
std::ranges::for_each
35-
(vec, [_0 = std::move(y)](auto const& x) -> void { std::cout << _0 << x << _0; });
35+
(vec, [_0 = std::move(y)](auto const& x) mutable -> void { std::cout << _0 << x << _0; });
3636

37-
auto callback {[](auto& x) -> void { x += "-ish"; }};
37+
auto callback {[](auto& x) mutable -> void { x += "-ish"; }};
3838
std::ranges::for_each(vec, std::move(callback));
3939

4040
for ( auto const& str : vec )

regression-tests/test-results/pure2-bugfix-for-non-local-function-expression.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ class t;
2020
// Standalone Cpp1 repro: https://godbolt.org/z/dznnYTvc6
2121

2222
#line 5 "pure2-bugfix-for-non-local-function-expression.cpp2"
23-
template<typename T> concept v = []() -> bool { return true; }();
23+
template<typename T> concept v = []() mutable -> bool { return true; }();
2424

25-
using u = std::type_identity_t<decltype([]() -> void{})>;
25+
using u = std::type_identity_t<decltype([]() mutable -> void{})>;
2626

27-
class t: public std::type_identity_t<decltype([]() -> void{})> {
27+
class t: public std::type_identity_t<decltype([]() mutable -> void{})> {
2828

2929
};
3030

regression-tests/test-results/pure2-look-up-parameter-across-unnamed-function.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ using g_ret = int;
3333
[[nodiscard]] auto f() -> f_ret{
3434
int ri {0};
3535
#line 3 "pure2-look-up-parameter-across-unnamed-function.cpp2"
36-
auto pred {[](auto const& e) -> auto { return e == 1; }};
36+
auto pred {[](auto const& e) mutable -> auto { return e == 1; }};
3737
ri = 42;
3838
std::move(pred)(ri);
3939
return std::move(ri); // "return;" is implicit"
@@ -43,7 +43,7 @@ using g_ret = int;
4343
cpp2::deferred_init<int> ri;
4444
#line 10 "pure2-look-up-parameter-across-unnamed-function.cpp2"
4545
ri.construct(0);
46-
auto pred {[](auto const& e) -> auto { return e == 1; }};
46+
auto pred {[](auto const& e) mutable -> auto { return e == 1; }};
4747
ri.value() = 42;
4848
std::move(pred)(ri.value());
4949
return std::move(ri.value());

0 commit comments

Comments
 (0)