Open
Description
Title: UFCS fails during constant evaluation only.
Description:
Given a parameter named after the function being called,
UFCS will fail during constant evaluation only
in the case UFCS would call a member function.
Minimal reproducer (https://cpp2.godbolt.org/z/jKWG4boaq, https://compiler-explorer.com/z/zeqW6MEPK):
t: @struct type = {
f: (this) -> int == 0;
}
g: (f) = {
[[assert: t().f() == 0]] // OK.
static_assert(t().f() == 0); // Error: Argument `f` isn't "`constexpr`".
}
main: () = {
g(0);
// g(std::identity()); // Might be OK since P2280R4 (unimplemented).
}
Commands:
cppfront main.cpp2
clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cpp
Expected result: A well-formed program that calls the member function.
Actual result and error:
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
class t;
//=== Cpp2 type definitions and function declarations ===========================
class t {
public: [[nodiscard]] constexpr auto f() const& -> int;
};
auto g(auto const& f) -> void;
auto main() -> int;
//=== Cpp2 function definitions =================================================
[[nodiscard]] constexpr auto t::f() const& -> int { return 0; }
auto g(auto const& f) -> void{
cpp2::Default.expects(CPP2_UFCS_0(f, t()) == 0, "");// OK.
static_assert(CPP2_UFCS_0(f, t()) == 0);// Error: Argument `f` isn't "`constexpr`".
}
auto main() -> int{
g(0);
// g(std::identity()); // Might be OK since P2280R4 (unimplemented).
}
Output:
main.cpp2:7:17: error: static assertion expression is not an integral constant expression
7 | static_assert(CPP2_UFCS_0(f, t()) == 0);// Error: Argument `f` isn't "`constexpr`".
| ^~~~~~~~~~~~~~~~~~~~~~~~
raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:790:38: note: expanded from macro 'CPP2_UFCS_0'
790 | #define CPP2_UFCS_0(FUNCNAME,PARAM1) \
| ^
main.cpp2:11:3: note: in instantiation of function template specialization 'g<int>' requested here
11 | g(0);
| ^
main.cpp2:7:17: note: function parameter 'f' with unknown value cannot be used in a constant expression
7 | static_assert(CPP2_UFCS_0(f, t()) == 0);// Error: Argument `f` isn't "`constexpr`".
| ^
raw.githubusercontent.com/hsutter/cppfront/main/include/cpp2util.h:791:2: note: expanded from macro 'CPP2_UFCS_0'
791 | [&] CPP2_LAMBDA_NO_DISCARD (auto&& obj) CPP2_FORCE_INLINE_LAMBDA -> decltype(auto) { \
| ^
main.cpp2:5:20: note: declared here
5 | auto g(auto const& f) -> void{
| ^
1 error generated.