hsutter / cppfront

A personal experimental C++ Syntax 2 -> Syntax 1 compiler
Other
5.39k stars 232 forks source link

[BUG] Disable UFCS on deduced return type not yet deduced (`f: () x.f();`) #874

Open JohelEGP opened 8 months ago

JohelEGP commented 8 months ago

Title: Disable UFCS on deduced return type not yet deduced (f: () x.f();).

Minimal reproducer (https://cpp2.godbolt.org/z/x8GsWo7cT):

#include <ranges>
arity: @struct type = {
  range: type == std::ranges::iota_view<i16, i16>;
  value: range = ();
  begin: (this) -> _ = {
    return std::ranges::iterator_t<range>(); // Deduce.
    return value.begin(); // OK.
    return begin(); // Recurses.
  }
  // error: function 'end' with deduced return type cannot be used before it is defined
  end: (this) value.end();
}
main: () = { }

Commands: ```bash cppfront main.cpp2 clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -Werror=unused-value -Werror=unused-parameter -I . main.cpp ```

Expected result: For arity::end to be well-formed by not naming itself in its body.

Actual result and error:

Cpp2 lowered to Cpp1: ```C++ //=== Cpp2 type declarations ==================================================== #include "cpp2util.h" #line 1 "/app/example.cpp2" #line 2 "/app/example.cpp2" class arity; //=== Cpp2 type definitions and function declarations =========================== #line 1 "/app/example.cpp2" #include class arity { #line 3 "/app/example.cpp2" public: using range = std::ranges::iota_view; public: range value {}; public: [[nodiscard]] auto begin() const& -> auto; #line 10 "/app/example.cpp2" // error: function 'end' with deduced return type cannot be used before it is defined public: [[nodiscard]] auto end() const& -> auto; }; auto main() -> int; //=== Cpp2 function definitions ================================================= #line 1 "/app/example.cpp2" #line 5 "/app/example.cpp2" [[nodiscard]] auto arity::begin() const& -> auto{ return std::ranges::iterator_t(); // Deduce. return CPP2_UFCS(begin)(value); // OK. return begin(); // Recurses. } [[nodiscard]] auto arity::end() const& -> auto { return CPP2_UFCS(end)(value); } auto main() -> int{} ```

Output:

main.cpp2:11:69: error: function 'end' with deduced return type cannot be used before it is defined
   11 |   [[nodiscard]] auto arity::end() const& -> auto { return CPP2_UFCS(end)(value);  }
      |                                                                     ^
main.cpp2:11:29: note: 'end' declared here
   11 |   [[nodiscard]] auto arity::end() const& -> auto { return CPP2_UFCS(end)(value);  }
      |                             ^

See also: