feat: support function types
Resolves #525. Resolves #502. Resolves #343. Resolves #711. Resolves #718. Partially addresses #387 (parameter-declaration-list).
Testing summary:
100% tests passed, 0 tests failed out of 776
Total Test time (real) = 39.42 sec
Acknowledgements:
- Tested thanks to https://github.com/modern-cmake/cppfront.
- The commit message uses Conventional Commits 1.0.0.
Title: Observable difference in template function's type.
Description:
This is due to the fact that
a template function's function parameter
with the type of a template parameter
doesn't use cpp2::in.
Minimal reproducer:
f: <T> (x: T) = { g: * (_: T) throws = f; }
main: () = { _ = f(:i32 = 0); }
Commands:
cppfront main.cpp2
clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -I . main.cpp
Expected result:
I'm not sure.
Attempting to extent the exception in the description can only get you so far.
If you did it for literal * (_: T) throws,
the same wouldn't apply for h<T> which itself aliases * (_: T) throws.
If you did it for all other uses of T,
we lose out on the optimization opportunities brought by cpp2::in.
Actual result and error:
Cpp2 lowered to Cpp1:
#define CPP2_USE_MODULES Yes
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
//=== Cpp2 type definitions and function declarations ===========================
#line 1 "pure2-function-type-id.cpp2"
template<typename T> auto f(T const& x) -> void;
auto main() -> int;
//=== Cpp2 function definitions =================================================
#line 1 "pure2-function-type-id.cpp2"
template<typename T> auto f(T const& x) -> void{cpp2::fn_t<void(cpp2::in<T>)>* g {f}; }
auto main() -> int{(void) f(cpp2::i32{0});}
regression-tests/pure2-function-type-id/pure2-function-type-id.cpp2:1:83: error: address of overloaded function 'f' does not match required type 'void (int)'
1 | template<typename T> auto f(T const& x) -> void{cpp2::fn_t<void(cpp2::in<T>)>* g {f}; }
| ^
regression-tests/pure2-function-type-id/pure2-function-type-id.cpp2:2:27: note: in instantiation of function template specialization 'f<int>' requested here
2 | auto main() -> int{(void) f(cpp2::i32{0});}
| ^
regression-tests/pure2-function-type-id/pure2-function-type-id.cpp2:1:27: note: candidate template ignored: could not match 'const T &' against 'int'
1 | template<typename T> auto f(T const& x) -> void{cpp2::fn_t<void(cpp2::in<T>)>* g {f}; }
| ^
1 error generated.
LGTM.
In your current commits, there are always some white-space fixes. These clutter the commit a little bit. Maybe we can have a pull request, that fixes all the white-spaces once and for all.
Yeah.
I wanted to reduce having to manually adjust whitespace, even if just a little.
So I set my related IDE settings back on when working on Cppfront.
I suggest you set this when reviewing:
Thanks for the hint, I did not know that this can be enabled in the github view.
Thanks again for this good PR, and deep apologies for the delay as I haven't kept up with PRs.
Because main has moved along since this PR, I took a pass at hand-merging this PR to rebase it to the current main and integrate it with some other features added since then. The result is #1177 ...
Although I was not able to get a manually-rebased version of this working in #1177, I did try my own implementation in #1183 and was able to get that working, so I'll commit that in favor of #526 and #1177. But I still appreciate this, thanks again!