Skip to content

[BUG] UFCS fails during constant evaluation only #788

Open
@JohelEGP

Description

@JohelEGP

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions