Skip to content

Commit 1a764db

Browse files
committed
feat: accept function-type after type-id
1 parent 5a57f5e commit 1a764db

14 files changed

+439
-103
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
main: () = {
2+
f: * (x: i32) throws = :(_) = {};
3+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
main: () = {
2+
f: * () [[pre: true]] = :() = {};
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
main: () = { f: * () -> (_: i32); }
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
main: () = {
2+
postfix_operators();
3+
4+
// Variables with type of a mix of `*`/`const` to `() throws -> void`.
5+
f0: * () throws = :() = {};
6+
f1: const * () throws = f0;
7+
f2: * const () throws = f0;
8+
f3: const * const () throws = f0;
9+
10+
i: i32 = 0;
11+
i0: * i32 = i&;
12+
i1: const * i32 = i0;
13+
i2: * const i32 = i0;
14+
i3: const * const i32 = i0;
15+
16+
// Assert consistent '*'/'const' with non-function type variables.
17+
static_assert((std::is_const_v<decltype(f1)>) == std::is_const_v<decltype(i1)>);
18+
static_assert((std::is_const_v<decltype(f2)>) == std::is_const_v<decltype(i2)>);
19+
static_assert((std::is_const_v<decltype(f3)>) == std::is_const_v<decltype(i3)>);
20+
21+
// Variables with various kinds of parameter.
22+
f4: * (_: i32) throws = :(x: i32) = {};
23+
f5: * (_: std::any) throws = :(x: std::any) = {};
24+
f6: * (move _: i32) throws = :(move x: i32) = {};
25+
f7: * (out _: i32) throws = :(copy x) = {};
26+
27+
// As local function parameter.
28+
_ = :(f: * () throws) = {};
29+
_ = :(f: * () throws -> * () throws) = {};
30+
_ = :(f: * () throws -> * () throws -> * () throws) = {};
31+
32+
// Without `throws`.
33+
_ = :* (copy _: std::string_view, copy _: CPP2_MESSAGE_PARAM) = cpp2::report_and_terminate;
34+
35+
// As template argument.
36+
_ = :std::type_identity_t<* () throws> = f0;
37+
}
38+
39+
// As non-local function parameter.
40+
g: (f: * () throws) = { }
41+
g: (f: * () throws -> * () throws) = { }
42+
// As template parameter.
43+
g: <V: * () throws> () = { }
44+
g: <V: * () throws -> * () throws> () = { }
45+
46+
// Adapted from <https://github.com/hsutter/cppfront/wiki/Design-note%3A-Postfix-operators>.
47+
// clang-format off
48+
f: (x: i32) -> * (_: i32) throws -> std::string = +:(x: i32) -> std::string = "";
49+
postfix_operators: () = {
50+
[[assert: f is (_: i32) throws -> * (_: i32) throws -> std::string]]
51+
// / | |
52+
// / | |
53+
[[assert: f(42) is * (_: i32) throws -> std::string]]
54+
// ________________/ |
55+
// / |
56+
[[assert: f(42)* is (_: i32) throws -> std::string]]
57+
// _______________/
58+
// /
59+
[[assert: (f(42)*)(1) is std::string]]
60+
} // clang-format on

regression-tests/test-results/gcc-13/pure2-function-type-id.cpp.execution

Whitespace-only changes.

regression-tests/test-results/gcc-13/pure2-function-type-id.cpp.output

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pure2-function-type-id-2-error.cpp2...
2+
pure2-function-type-id-2-error.cpp2(2,9): error: the parameter of a function type must be named '_'
3+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pure2-function-type-id-3-error.cpp2...
2+
pure2-function-type-id-3-error.cpp2(2,11): error: a function type can't have contracts
3+
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pure2-function-type-id-4-error.cpp2...
2+
pure2-function-type-id-4-error.cpp2(1,25): error: a function type can't have an anonymous return type
3+
pure2-function-type-id-4-error.cpp2(1,14): error: f - variable must be initialized on every branch path
4+
==> program violates initialization safety guarantee - see previous errors
5+
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
2+
#define CPP2_USE_MODULES Yes
3+
4+
//=== Cpp2 type declarations ====================================================
5+
6+
7+
#include "cpp2util.h"
8+
9+
10+
11+
//=== Cpp2 type definitions and function declarations ===========================
12+
13+
#line 1 "pure2-function-type-id.cpp2"
14+
auto main() -> int;
15+
16+
17+
#line 39 "pure2-function-type-id.cpp2"
18+
// As non-local function parameter.
19+
auto g(auto (* f)() -> void) -> void;
20+
auto g(auto (* f)() -> auto (*)() -> void) -> void;
21+
// As template parameter.
22+
template<auto (* V)() -> void> auto g() -> void;
23+
template<auto (* V)() -> auto (*)() -> void> auto g() -> void;
24+
25+
// Adapted from <https://github.com/hsutter/cppfront/wiki/Design-note%3A-Postfix-operators>.
26+
// clang-format off
27+
[[nodiscard]] auto f(cpp2::in<cpp2::i32> x) -> auto (*)(cpp2::in<cpp2::i32>) -> std::string;
28+
auto postfix_operators() -> void;
29+
30+
31+
//=== Cpp2 function definitions =================================================
32+
33+
#line 1 "pure2-function-type-id.cpp2"
34+
auto main() -> int{
35+
postfix_operators();
36+
37+
// Variables with type of a mix of `*`/`const` to `() throws -> void`.
38+
std::type_identity_t<auto (*)() -> void> f0 {[]() -> void{}};
39+
std::type_identity_t<auto (*)() -> void> const f1 {f0};
40+
std::type_identity_t<auto (* const)() -> void> f2 {f0};
41+
std::type_identity_t<auto (* const)() -> void> const f3 {f0};
42+
43+
cpp2::i32 i {0};
44+
cpp2::i32* i0 {&i};
45+
cpp2::i32* const i1 {i0};
46+
cpp2::i32 const* i2 {i0};
47+
cpp2::i32 const* const i3 {i0};
48+
49+
// Assert consistent '*'/'const' with non-function type variables.
50+
static_assert((std::is_const_v<decltype(std::move(f1))>)==std::is_const_v<decltype(std::move(i1))>);
51+
static_assert((std::is_const_v<decltype(std::move(f2))>)==std::is_const_v<decltype(std::move(i2))>);
52+
static_assert((std::is_const_v<decltype(std::move(f3))>)==std::is_const_v<decltype(std::move(i3))>);
53+
54+
// Variables with various kinds of parameter.
55+
std::type_identity_t<auto (*)(cpp2::in<cpp2::i32>) -> void> f4 {[](cpp2::in<cpp2::i32> x) -> void{}};
56+
std::type_identity_t<auto (*)(cpp2::in<std::any>) -> void> f5 {[](cpp2::in<std::any> x) -> void{}};
57+
std::type_identity_t<auto (*)(cpp2::i32&&) -> void> f6 {[](cpp2::i32&& x) -> void{}};
58+
std::type_identity_t<auto (*)(cpp2::out<cpp2::i32>) -> void> f7 {[](auto x) -> void{}};
59+
60+
// As local function parameter.
61+
(void) [](auto (* f)() -> void) -> void{};
62+
(void) [](auto (* f)() -> auto (*)() -> void) -> void{};
63+
(void) [](auto (* f)() -> auto (*)() -> auto (*)() -> void) -> void{};
64+
65+
// Without `throws`.
66+
(void) std::type_identity_t<auto (*)(std::string_view, CPP2_MESSAGE_PARAM) noexcept -> void>{cpp2::report_and_terminate};
67+
68+
// As template argument.
69+
(void) std::type_identity_t<auto (*)() -> void>{std::move(f0)};
70+
}
71+
72+
#line 40 "pure2-function-type-id.cpp2"
73+
auto g(auto (* f)() -> void) -> void{}
74+
auto g(auto (* f)() -> auto (*)() -> void) -> void{}
75+
76+
template<auto (* V)() -> void> auto g() -> void{}
77+
template<auto (* V)() -> auto (*)() -> void> auto g() -> void{}
78+
79+
#line 48 "pure2-function-type-id.cpp2"
80+
[[nodiscard]] auto f(cpp2::in<cpp2::i32> x) -> auto (*)(cpp2::in<cpp2::i32>) -> std::string { return +[](cpp2::in<cpp2::i32> x) -> std::string { return ""; }; }
81+
auto postfix_operators() -> void{
82+
cpp2::Default.expects(cpp2::is<auto (cpp2::in<cpp2::i32>) -> auto (*)(cpp2::in<cpp2::i32>) -> std::string>(f), "");
83+
// / | |
84+
// / | |
85+
cpp2::Default.expects(cpp2::is<auto (*)(cpp2::in<cpp2::i32>) -> std::string>(f(42)), "");
86+
// ________________/ |
87+
// / |
88+
cpp2::Default.expects(cpp2::is<auto (cpp2::in<cpp2::i32>) -> std::string>(*cpp2::assert_not_null(f(42))), "");
89+
// _______________/
90+
// /
91+
cpp2::Default.expects(cpp2::is<std::string>((*cpp2::assert_not_null(f(42)))(1)), "");
92+
} // clang-format on
93+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pure2-function-type-id.cpp2... ok (all Cpp2, passes safety checks)
2+

0 commit comments

Comments
 (0)