diff --git a/regression-tests/pure2-for-loop-range-with-lambda.cpp2 b/regression-tests/pure2-for-loop-range-with-lambda.cpp2 new file mode 100644 index 0000000000..066771baa9 --- /dev/null +++ b/regression-tests/pure2-for-loop-range-with-lambda.cpp2 @@ -0,0 +1,30 @@ +first: (forward f, forward _...) -> forward _ = f; + +main: (args) = { + ints: const std::array = (1, 2, 3, 4, 5); + // OK + for ints.first() do (i) { + std::cout << i; + } + + // OK + for ints.first(1) do (i) { + std::cout << i; + } + + // Used to cause Error + for ints.first(:(x) x) do (i) { + std::cout << i; + } + + // OK + temp := ints.first(:(x) x); + for temp do (i) { + std::cout << i; + } + + for :() args$;() do (i) _ = i; + for :(x) x;(args) do (j) _ = j; + for :(x) x;(args) next _ = :() args$;() do (k) _ = k; + for :(x) x;(args) next _ = :(x) x;(args) do (l) _ = l; +} diff --git a/regression-tests/test-results/pure2-for-loop-range-with-lambda.cpp b/regression-tests/test-results/pure2-for-loop-range-with-lambda.cpp new file mode 100644 index 0000000000..3e2e505aed --- /dev/null +++ b/regression-tests/test-results/pure2-for-loop-range-with-lambda.cpp @@ -0,0 +1,56 @@ + +#define CPP2_IMPORT_STD Yes + +//=== Cpp2 type declarations ==================================================== + + +#include "cpp2util.h" + +#line 1 "pure2-for-loop-range-with-lambda.cpp2" + + +//=== Cpp2 type definitions and function declarations =========================== + +#line 1 "pure2-for-loop-range-with-lambda.cpp2" +[[nodiscard]] auto first(auto&& f, [[maybe_unused]] auto&& ...unnamed_param_2) -> auto&&; + +#line 3 "pure2-for-loop-range-with-lambda.cpp2" +auto main(int const argc_, char** argv_) -> int; + +//=== Cpp2 function definitions ================================================= + +#line 1 "pure2-for-loop-range-with-lambda.cpp2" +[[nodiscard]] auto first(auto&& f, [[maybe_unused]] auto&& ...unnamed_param_2) -> auto&& { return CPP2_FORWARD(f); } + +#line 3 "pure2-for-loop-range-with-lambda.cpp2" +auto main(int const argc_, char** argv_) -> int{ + auto const args = cpp2::make_args(argc_, argv_); +#line 4 "pure2-for-loop-range-with-lambda.cpp2" + std::array const ints {1, 2, 3, 4, 5}; + // OK + for ( auto const& i : CPP2_UFCS(first)(ints) ) { + std::cout << i; + } + + // OK + for ( auto const& i : CPP2_UFCS(first)(ints, 1) ) { + std::cout << i; + } + + // Used to cause Error + for ( auto const& i : CPP2_UFCS(first)(ints, [](auto const& x) mutable -> auto { return x; }) ) { + std::cout << i; + } + + // OK + auto temp {CPP2_UFCS(first)(std::move(ints), [](auto const& x) mutable -> auto { return x; })}; + for ( auto const& i : temp ) { + std::cout << i; + } + + for ( auto const& i : [_0 = args]() mutable -> auto { return _0; }() ) static_cast(i); + for ( auto const& j : [](auto const& x) mutable -> auto { return x; }(args) ) static_cast(j); + for ( auto const& k : [](auto const& x) mutable -> auto { return x; }(args) ) { do static_cast(k); while (false); static_cast([_0 = args]() mutable -> auto { return _0; }()); } + for ( auto const& l : [](auto const& x) mutable -> auto { return x; }(args) ) { do static_cast(l); while (false); static_cast([](auto const& x) mutable -> auto { return x; }(args)); } +} + diff --git a/regression-tests/test-results/pure2-for-loop-range-with-lambda.cpp2.output b/regression-tests/test-results/pure2-for-loop-range-with-lambda.cpp2.output new file mode 100644 index 0000000000..0a120379fb --- /dev/null +++ b/regression-tests/test-results/pure2-for-loop-range-with-lambda.cpp2.output @@ -0,0 +1,2 @@ +pure2-for-loop-range-with-lambda.cpp2... ok (all Cpp2, passes safety checks) + diff --git a/source/parse.h b/source/parse.h index b55a75269c..a2a5932ca1 100644 --- a/source/parse.h +++ b/source/parse.h @@ -4028,6 +4028,7 @@ auto primary_expression_node::visit(auto& v, int depth) struct next_expression_tag { }; +struct loop_body_tag { token const* identifier; }; auto iteration_statement_node::visit(auto& v, int depth) -> void @@ -4054,6 +4055,7 @@ auto iteration_statement_node::visit(auto& v, int depth) else { assert(range && parameter && body); range->visit(v, depth+1); + v.start(loop_body_tag{identifier}, depth); parameter->visit(v, depth+1); body->visit(v, depth+1); } diff --git a/source/sema.h b/source/sema.h index b582e8b0f0..1f7e48ad2c 100644 --- a/source/sema.h +++ b/source/sema.h @@ -1691,7 +1691,7 @@ class sema inside_returns_list = false; } - auto start(iteration_statement_node const& n, int) -> void + auto start(loop_body_tag const &n, int) -> void { if (*n.identifier == "for") { just_entered_for = true;