forked from hsutter/cppfront
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: accept function-type after type-id
Uses the same grammar for functions, _function-type_. Parameter identifiers must be named `_` and can't be omitted. It's generally needed to specify the `throws` qualifier so that it doesn't lower to a `noexcept` function type. Some examples: ```Cpp2 main: () = { f0: * () throws = :() = {}; f6: * (move _: i32) throws = :(move x: i32) = {}; [[assert: inspect f0 -> bool { is () = (std::terminate(), false); is * () throws = true; is _ = false; }]] } // Test case from hsutter#343. f2: () -> std::function<(_: std::string) throws -> std::string> = { return :(s: std::string) -> std::string = { return s + " World!"; }; } // Adapted from <https://github.com/hsutter/cppfront/wiki/Design-note%3A-Postfix-operators>. f: (x: i32) -> * (_: i32) throws -> std::string = +:(x: i32) -> std::string = ""; postfix_operators: () = { [[assert: f is (_: i32) throws -> * (_: i32) throws -> std::string]] // / | | // / | | [[assert: f(42) is * (_: i32) throws -> std::string]] // ________________/ | // / | [[assert: f(42)* is (_: i32) throws -> std::string]] // _______________/ // / [[assert: (f(42)*)(1) is std::string]] } ```
- Loading branch information
Showing
21 changed files
with
538 additions
and
92 deletions.
There are no files selected for viewing
1 change: 1 addition & 0 deletions
1
regression-tests/pure2-bugfix-for-multi-token-type-prvalue.cpp2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
main: (args) = { _ = :* int = args.argc&; } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
main: () = { | ||
f: * (x: i32) throws = :(_) = {}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
main: () = { | ||
f: * () [[pre: true]] = :() = {}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
main: () = { f: * () -> (x: i32); } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
main: () = { | ||
f: * (_) throws = :(_) = {}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
main: () = { | ||
postfix_operators(); | ||
|
||
// Variables with type of a mix of `*`/`const` to `() throws -> void`. | ||
f0: * () throws = :() = {}; | ||
f1: const * () throws = f0; | ||
f2: * const () throws = f0; | ||
f3: const * const () throws = f0; | ||
|
||
i: i32 = 0; | ||
i0: * i32 = i&; | ||
i1: const * i32 = i0; | ||
i2: * const i32 = i0; | ||
i3: const * const i32 = i0; | ||
|
||
// Assert consistent '*'/'const' with non-function type variables. | ||
static_assert((std::is_const_v<decltype(f1)>) == std::is_const_v<decltype(i1)>); | ||
static_assert((std::is_const_v<decltype(f2)>) == std::is_const_v<decltype(i2)>); | ||
static_assert((std::is_const_v<decltype(f3)>) == std::is_const_v<decltype(i3)>); | ||
|
||
// Variables with various kinds of parameter. | ||
f4: * (_: i32) throws = :(x: i32) = {}; | ||
f5: * (_: std::any) throws = :(x: std::any) = {}; | ||
f6: * (move _: i32) throws = :(move x: i32) = {}; | ||
f7: * (out _: i32) throws = :(copy x) = {}; | ||
|
||
// In alternative. | ||
[[assert: inspect f0 -> bool { | ||
is () = (std::terminate(), false); | ||
is () throws = (std::terminate(), false); | ||
is * () throws = true; | ||
is _ = false; | ||
}]] | ||
[[assert: inspect f0* -> bool { | ||
is () throws = true; | ||
is _ = false; | ||
}]] | ||
|
||
// As block variable. | ||
(f: * () throws = f0) { } | ||
|
||
// As local function parameter. | ||
_ = :(f: * () throws) = {}; | ||
_ = :(f: * () throws -> * () throws) = {}; | ||
_ = :(f: * () throws -> * () throws -> * () throws) = {}; | ||
|
||
// In local function return type. | ||
_ = :() -> * () throws = nullptr; | ||
_ = :() -> * () throws -> * () throws = nullptr; | ||
|
||
// Without `throws`. | ||
_ = :* (copy _: std::string_view, copy _: CPP2_MESSAGE_PARAM) = cpp2::report_and_terminate; | ||
|
||
// As template argument. | ||
_ = :std::type_identity_t<* () throws> = f0; | ||
} | ||
|
||
// As non-local function parameter. | ||
g: (f: * () throws) = { } | ||
g: (f: * () throws -> * () throws) = { } | ||
// As template parameter. | ||
g: <V: * () throws> () = { } | ||
g: <V: * () throws -> * () throws> () = { } | ||
|
||
// In non-local function return type. | ||
g1: () -> * () throws = nullptr; | ||
g2: () -> * () throws -> * () throws = nullptr; | ||
|
||
// clang-format off | ||
// Test case from #343. | ||
f2: () -> std::function<(_: std::string) throws -> std::string> = { | ||
return :(s: std::string) -> std::string = { return s + " World!"; }; | ||
} | ||
|
||
// Adapted from <https://github.com/hsutter/cppfront/wiki/Design-note%3A-Postfix-operators>. | ||
f: (x: i32) -> * (_: i32) throws -> std::string = +:(x: i32) -> std::string = ""; | ||
postfix_operators: () = { | ||
[[assert: f is (_: i32) throws -> * (_: i32) throws -> std::string]] | ||
// / | | | ||
// / | | | ||
[[assert: f(42) is * (_: i32) throws -> std::string]] | ||
// ________________/ | | ||
// / | | ||
[[assert: f(42)* is (_: i32) throws -> std::string]] | ||
// _______________/ | ||
// / | ||
[[assert: (f(42)*)(1) is std::string]] | ||
} // clang-format on |
Empty file.
Empty file.
Empty file.
Empty file.
24 changes: 24 additions & 0 deletions
24
regression-tests/test-results/pure2-bugfix-for-multi-token-type-prvalue.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
|
||
#define CPP2_USE_MODULES Yes | ||
|
||
//=== Cpp2 type declarations ==================================================== | ||
|
||
|
||
#include "cpp2util.h" | ||
|
||
|
||
|
||
//=== Cpp2 type definitions and function declarations =========================== | ||
|
||
#line 1 "pure2-bugfix-for-multi-token-type-prvalue.cpp2" | ||
auto main(int const argc_, char const* const* const argv_) -> int; | ||
|
||
|
||
//=== Cpp2 function definitions ================================================= | ||
|
||
#line 1 "pure2-bugfix-for-multi-token-type-prvalue.cpp2" | ||
auto main(int const argc_, char const* const* const argv_) -> int{ | ||
auto args = cpp2::make_args(argc_, argv_); | ||
#line 1 "pure2-bugfix-for-multi-token-type-prvalue.cpp2" | ||
(void) std::type_identity_t<int*>{&args.argc}; } | ||
|
2 changes: 2 additions & 0 deletions
2
regression-tests/test-results/pure2-bugfix-for-multi-token-type-prvalue.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pure2-bugfix-for-multi-token-type-prvalue.cpp2... ok (all Cpp2, passes safety checks) | ||
|
3 changes: 3 additions & 0 deletions
3
regression-tests/test-results/pure2-function-type-id-2-error.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pure2-function-type-id-2-error.cpp2... | ||
pure2-function-type-id-2-error.cpp2(2,9): error: the parameter of a function type must be named '_' | ||
|
3 changes: 3 additions & 0 deletions
3
regression-tests/test-results/pure2-function-type-id-3-error.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pure2-function-type-id-3-error.cpp2... | ||
pure2-function-type-id-3-error.cpp2(2,11): error: a function type can't have contracts | ||
|
5 changes: 5 additions & 0 deletions
5
regression-tests/test-results/pure2-function-type-id-4-error.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pure2-function-type-id-4-error.cpp2... | ||
pure2-function-type-id-4-error.cpp2(1,25): error: a function type can't have an anonymous return type | ||
pure2-function-type-id-4-error.cpp2(1,14): error: f - variable must be initialized on every branch path | ||
==> program violates initialization safety guarantee - see previous errors | ||
|
3 changes: 3 additions & 0 deletions
3
regression-tests/test-results/pure2-function-type-id-5-error.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pure2-function-type-id-5-error.cpp2... | ||
pure2-function-type-id-5-error.cpp2(2,9): error: function type parameter must have a type | ||
|
135 changes: 135 additions & 0 deletions
135
regression-tests/test-results/pure2-function-type-id.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
|
||
#define CPP2_USE_MODULES Yes | ||
|
||
//=== Cpp2 type declarations ==================================================== | ||
|
||
|
||
#include "cpp2util.h" | ||
|
||
|
||
|
||
//=== Cpp2 type definitions and function declarations =========================== | ||
|
||
#line 1 "pure2-function-type-id.cpp2" | ||
auto main() -> int; | ||
|
||
|
||
#line 58 "pure2-function-type-id.cpp2" | ||
// As non-local function parameter. | ||
auto g(auto (* f)() -> void) -> void; | ||
auto g(auto (* f)() -> auto (*)() -> void) -> void; | ||
// As template parameter. | ||
template<auto (* V)() -> void> auto g() -> void; | ||
template<auto (* V)() -> auto (*)() -> void> auto g() -> void; | ||
|
||
// In non-local function return type. | ||
[[nodiscard]] auto g1() -> auto (*)() -> void; | ||
[[nodiscard]] auto g2() -> auto (*)() -> auto (*)() -> void; | ||
|
||
// clang-format off | ||
// Test case from #343. | ||
[[nodiscard]] auto f2() -> std::function<auto (cpp2::in<std::string>) -> std::string>; | ||
|
||
|
||
#line 75 "pure2-function-type-id.cpp2" | ||
// Adapted from <https://github.com/hsutter/cppfront/wiki/Design-note%3A-Postfix-operators>. | ||
[[nodiscard]] auto f(cpp2::in<cpp2::i32> x) -> auto (*)(cpp2::in<cpp2::i32>) -> std::string; | ||
auto postfix_operators() -> void; | ||
|
||
|
||
//=== Cpp2 function definitions ================================================= | ||
|
||
#line 1 "pure2-function-type-id.cpp2" | ||
auto main() -> int{ | ||
postfix_operators(); | ||
|
||
// Variables with type of a mix of `*`/`const` to `() throws -> void`. | ||
std::type_identity_t<auto (*)() -> void> f0 {[]() -> void{}}; | ||
std::type_identity_t<auto (*)() -> void> const f1 {f0}; | ||
std::type_identity_t<auto (* const)() -> void> f2 {f0}; | ||
std::type_identity_t<auto (* const)() -> void> const f3 {f0}; | ||
|
||
cpp2::i32 i {0}; | ||
cpp2::i32* i0 {&i}; | ||
cpp2::i32* const i1 {i0}; | ||
cpp2::i32 const* i2 {i0}; | ||
cpp2::i32 const* const i3 {i0}; | ||
|
||
// Assert consistent '*'/'const' with non-function type variables. | ||
static_assert((std::is_const_v<decltype(std::move(f1))>)==std::is_const_v<decltype(std::move(i1))>); | ||
static_assert((std::is_const_v<decltype(std::move(f2))>)==std::is_const_v<decltype(std::move(i2))>); | ||
static_assert((std::is_const_v<decltype(std::move(f3))>)==std::is_const_v<decltype(std::move(i3))>); | ||
|
||
// Variables with various kinds of parameter. | ||
std::type_identity_t<auto (*)(cpp2::in<cpp2::i32>) -> void> f4 {[](cpp2::in<cpp2::i32> x) -> void{}}; | ||
std::type_identity_t<auto (*)(cpp2::in<std::any>) -> void> f5 {[](cpp2::in<std::any> x) -> void{}}; | ||
std::type_identity_t<auto (*)(cpp2::i32&&) -> void> f6 {[](cpp2::i32&& x) -> void{}}; | ||
std::type_identity_t<auto (*)(cpp2::out<cpp2::i32>) -> void> f7 {[](auto x) -> void{}}; | ||
|
||
// In alternative. | ||
cpp2::Default.expects([&] () -> bool { auto&& __expr = f0; | ||
if (cpp2::is<auto () noexcept -> void>(__expr)) { if constexpr( requires{std::terminate(), false;} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF((std::terminate(), false)),bool> ) return std::terminate(), false; else return bool{}; else return bool{}; } | ||
else if (cpp2::is<auto () -> void>(__expr)) { if constexpr( requires{std::terminate(), false;} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF((std::terminate(), false)),bool> ) return std::terminate(), false; else return bool{}; else return bool{}; } | ||
else if (cpp2::is<auto (*)() -> void>(__expr)) { if constexpr( requires{true;} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF((true)),bool> ) return true; else return bool{}; else return bool{}; } | ||
else return false; } | ||
(), ""); | ||
cpp2::Default.expects([&] () -> bool { auto&& __expr = *cpp2::assert_not_null(f0); | ||
if (cpp2::is<auto () -> void>(__expr)) { if constexpr( requires{true;} ) if constexpr( std::is_convertible_v<CPP2_TYPEOF((true)),bool> ) return true; else return bool{}; else return bool{}; } | ||
else return false; } | ||
(), ""); | ||
{ | ||
auto (* f)() -> void = f0; | ||
|
||
// As block variable. | ||
#line 40 "pure2-function-type-id.cpp2" | ||
{} | ||
} | ||
|
||
// As local function parameter. | ||
#line 43 "pure2-function-type-id.cpp2" | ||
(void) [](auto (* f)() -> void) -> void{}; | ||
(void) [](auto (* f)() -> auto (*)() -> void) -> void{}; | ||
(void) [](auto (* f)() -> auto (*)() -> auto (*)() -> void) -> void{}; | ||
|
||
// In local function return type. | ||
(void) []() -> auto (*)() -> void { return nullptr; }; | ||
(void) []() -> auto (*)() -> auto (*)() -> void { return nullptr; }; | ||
|
||
// Without `throws`. | ||
(void) std::type_identity_t<auto (*)(std::string_view, CPP2_MESSAGE_PARAM) noexcept -> void>{cpp2::report_and_terminate}; | ||
|
||
// As template argument. | ||
(void) std::type_identity_t<auto (*)() -> void>{std::move(f0)}; | ||
} | ||
|
||
#line 59 "pure2-function-type-id.cpp2" | ||
auto g(auto (* f)() -> void) -> void{} | ||
auto g(auto (* f)() -> auto (*)() -> void) -> void{} | ||
|
||
template<auto (* V)() -> void> auto g() -> void{} | ||
template<auto (* V)() -> auto (*)() -> void> auto g() -> void{} | ||
|
||
#line 66 "pure2-function-type-id.cpp2" | ||
[[nodiscard]] auto g1() -> auto (*)() -> void { return nullptr; } | ||
[[nodiscard]] auto g2() -> auto (*)() -> auto (*)() -> void { return nullptr; } | ||
|
||
#line 71 "pure2-function-type-id.cpp2" | ||
[[nodiscard]] auto f2() -> std::function<auto (cpp2::in<std::string>) -> std::string>{ | ||
return [](cpp2::in<std::string> s) -> std::string{return s + " World!"; }; | ||
} | ||
|
||
#line 76 "pure2-function-type-id.cpp2" | ||
[[nodiscard]] auto f(cpp2::in<cpp2::i32> x) -> auto (*)(cpp2::in<cpp2::i32>) -> std::string { return +[](cpp2::in<cpp2::i32> x) -> std::string { return ""; }; } | ||
auto postfix_operators() -> void{ | ||
cpp2::Default.expects(cpp2::is<auto (cpp2::in<cpp2::i32>) -> auto (*)(cpp2::in<cpp2::i32>) -> std::string>(f), ""); | ||
// / | | | ||
// / | | | ||
cpp2::Default.expects(cpp2::is<auto (*)(cpp2::in<cpp2::i32>) -> std::string>(f(42)), ""); | ||
// ________________/ | | ||
// / | | ||
cpp2::Default.expects(cpp2::is<auto (cpp2::in<cpp2::i32>) -> std::string>(*cpp2::assert_not_null(f(42))), ""); | ||
// _______________/ | ||
// / | ||
cpp2::Default.expects(cpp2::is<std::string>((*cpp2::assert_not_null(f(42)))(1)), ""); | ||
} // clang-format on | ||
|
2 changes: 2 additions & 0 deletions
2
regression-tests/test-results/pure2-function-type-id.cpp2.output
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pure2-function-type-id.cpp2... ok (all Cpp2, passes safety checks) | ||
|
Oops, something went wrong.