Skip to content

Bugfix #778: Flag for entry into for loop after range has been processed #795

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions regression-tests/pure2-for-loop-range-with-lambda.cpp2
Original file line number Diff line number Diff line change
@@ -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;
}
56 changes: 56 additions & 0 deletions regression-tests/test-results/pure2-for-loop-range-with-lambda.cpp
Original file line number Diff line number Diff line change
@@ -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<void>(i);
for ( auto const& j : [](auto const& x) mutable -> auto { return x; }(args) ) static_cast<void>(j);
for ( auto const& k : [](auto const& x) mutable -> auto { return x; }(args) ) { do static_cast<void>(k); while (false); static_cast<void>([_0 = args]() mutable -> auto { return _0; }()); }
for ( auto const& l : [](auto const& x) mutable -> auto { return x; }(args) ) { do static_cast<void>(l); while (false); static_cast<void>([](auto const& x) mutable -> auto { return x; }(args)); }
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pure2-for-loop-range-with-lambda.cpp2... ok (all Cpp2, passes safety checks)

2 changes: 2 additions & 0 deletions source/parse.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion source/sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down