Skip to content

feat: support function types #526

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

Closed
wants to merge 5 commits into from
Closed
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
25 changes: 18 additions & 7 deletions include/cpp2util.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@
// in our -pure-cpp2 "import std;" simulation mode... if you need this,
// use mixed mode (not -pure-cpp2) and #include all the headers you need
// including this one
//
//
// #include <execution>
#endif

Expand Down Expand Up @@ -277,6 +277,17 @@ using __schar = signed char; // normally use i8 instead
using __uchar = unsigned char; // normally use u8 instead


//-----------------------------------------------------------------------
//
// fn_t<R(ArgTypes...)> For emitted Cpp2 function types
//
//-----------------------------------------------------------------------
//
template<typename T>
requires std::is_function_v<T>
using fn_t = T;


//-----------------------------------------------------------------------
//
// String: A helper workaround for passing a string literal as a
Expand Down Expand Up @@ -466,7 +477,7 @@ template<typename T>
auto Typeid() -> decltype(auto) {
#ifdef CPP2_NO_RTTI
Type.expects(
!"'any' dynamic casting is disabled with -fno-rtti", // more likely to appear on console
!"'any' dynamic casting is disabled with -fno-rtti", // more likely to appear on console
"'any' dynamic casting is disabled with -fno-rtti" // make message available to hooked handlers
);
#else
Expand Down Expand Up @@ -828,17 +839,17 @@ auto is( X const& ) -> bool {

template< typename C, typename X >
requires (
( std::is_base_of_v<X, C> ||
( std::is_polymorphic_v<C> && std::is_polymorphic_v<X>)
( std::is_base_of_v<X, C> ||
( std::is_polymorphic_v<C> && std::is_polymorphic_v<X>)
) && !std::is_same_v<C,X>)
auto is( X const& x ) -> bool {
return Dynamic_cast<C const*>(&x) != nullptr;
}

template< typename C, typename X >
requires (
( std::is_base_of_v<X, C> ||
( std::is_polymorphic_v<C> && std::is_polymorphic_v<X>)
( std::is_base_of_v<X, C> ||
( std::is_polymorphic_v<C> && std::is_polymorphic_v<X>)
) && !std::is_same_v<C,X>)
auto is( X const* x ) -> bool {
return Dynamic_cast<C const*>(x) != nullptr;
Expand Down Expand Up @@ -1426,7 +1437,7 @@ inline auto to_string(std::string const& s) -> std::string const&

template<typename T>
inline auto to_string(T const& sv) -> std::string
requires (std::is_convertible_v<T, std::string_view>
requires (std::is_convertible_v<T, std::string_view>
&& !std::is_convertible_v<T, const char*>)
{
return std::string{sv};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
main: (args) = { _ = :* int = args.argc&; }
3 changes: 3 additions & 0 deletions regression-tests/pure2-function-type-id-2-error.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
main: () = {
f: * (x: i32) = :(_) = {};
}
3 changes: 3 additions & 0 deletions regression-tests/pure2-function-type-id-3-error.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
main: () = {
f: * () [[pre: true]] = :() = {};
}
1 change: 1 addition & 0 deletions regression-tests/pure2-function-type-id-4-error.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
main: () = { f: * () -> (x: i32); }
3 changes: 3 additions & 0 deletions regression-tests/pure2-function-type-id-5-error.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
main: () = {
f: * (_) = :(_) = {};
}
112 changes: 112 additions & 0 deletions regression-tests/pure2-function-type-id.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
main: () = {
postfix_operators();

// Variables with type of a mix of `*`/`const` to `() -> void`.
f0: * () = :() = {};
f1: const * () = f0;
f2: * const () = f0;
f3: const * const () = f0;

// Uninitialized.
f4: * ();
f4 = f0;

f10: * * () = f0&;
f11: const * * () = f10;
f12: * const * () = f10;
f13: const * const * () = f10;

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(f10)>) == std::is_const_v<decltype(i0)>);
static_assert((std::is_const_v<decltype(f11)>) == std::is_const_v<decltype(i1)>);
static_assert((std::is_const_v<decltype(f12)>) == std::is_const_v<decltype(i2)>);
static_assert((std::is_const_v<decltype(f13)>) == std::is_const_v<decltype(i3)>);
_ = f10;
_ = f11;
_ = f12;
_ = f13;
_ = i0;
_ = i1;
_ = i2;
_ = i3;

// Variables with various kinds of parameter.
f5: * (_: i32) = :(x: i32) = {};
f6: * (_: std::any) = :(x: std::any) = {};
f7: * (move _: i32) = :(move x: i32) = {};
f8: * (out _: i32) = :(copy x) = {};

// In alternative.
[[assert: inspect f0 -> bool {
is () !throws = (std::terminate(), false);
is () = (std::terminate(), false);
is * () = true;
is _ = false;
}]]
[[assert: inspect f0* -> bool {
is () = true;
is _ = false;
}]]

// As block variable.
(f: * () = f0) { }
(f: () = f0*) { }

// As local function parameter.
_ = :(f: ()) = {};
_ = :(f: * ()) = {};
_ = :(f: * () -> * ()) = {};
_ = :(f: * () -> * () -> * ()) = {};

// In local function return type.
_ = :() -> forward() = f0$*;
_ = :() -> * () = nullptr;
_ = :() -> * () -> * () = nullptr;

// With `!throws`.
_ = :* (copy _: std::string_view, copy _: CPP2_MESSAGE_PARAM) !throws = cpp2::report_and_terminate;

// As template argument.
_ = :std::type_identity_t<* ()> = f0;
static_assert(std::is_function_v<()>);
}

// As non-local function parameter.
g: (f: ()) = { }
g: (f: * ()) = { }
g: (f: * () -> * ()) = { }
// As template parameter.
g: <V: * ()> () = { }
g: <V: * () -> * ()> () = { }

// In non-local function return type.
g1: () -> * () = nullptr;
g1: <V: bool> () -> * () requires V = { return nullptr; }
g2: () -> * () -> * () = nullptr;

// clang-format off
// Test case from #343.
f2: () -> std::function<(_: std::string) -> 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) -> std::string = :(x: i32) -> std::string = "";
postfix_operators: () = {
[[assert: f is (_: i32) -> * (_: i32) -> std::string]]
// / | |
// / | |
[[assert: f(42) is * (_: i32) -> std::string]]
// _________/ |
// / |
[[assert: f(42)* is (_: i32) -> std::string]]
// ________/
// /
[[assert: (f(42)*)(1) is std::string]]
} // clang-format on
Empty file.
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** argv_) -> int;


//=== Cpp2 function definitions =================================================

#line 1 "pure2-bugfix-for-multi-token-type-prvalue.cpp2"
auto main(int const argc_, char** argv_) -> int{
auto args = cpp2::make_args(argc_, argv_);
#line 1 "pure2-bugfix-for-multi-token-type-prvalue.cpp2"
static_cast<void>(std::type_identity_t<int*>{&args.argc}); }

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)

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 '_'

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

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

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

Loading