hsutter / cppfront

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

[BUG] Move from last-use incompatible with `constexpr` function #1105

Closed bluetarpmedia closed 2 weeks ago

bluetarpmedia commented 2 weeks ago

Describe the bug A move from last-use in a constexpr Cpp2 function causes a C++ compiler error because cpp2::move is not constexpr.

To Reproduce Run cppfront on this code:

trim_start: (str: std::string_view) -> std::string_view == {
    it:= std::ranges::find_if_not(str, :(ch: char) ch == ' ');
    return (it, str.cend());
}

main: () = {
    using namespace std::literals::string_view_literals;

    static_assert("test"sv    == trim_start(" test"));
    static_assert("another"sv == trim_start("     another"));
}

The it variable is automatically moved in its last use in the lowered C++:

[[nodiscard]] constexpr auto trim_start(cpp2::impl::in<std::string_view> str) -> std::string_view{
    auto it {std::ranges::find_if_not(str, [](cpp2::impl::in<char> ch) mutable -> auto { return ch == ' ';  })}; 
    return { cpp2::move(it), CPP2_UFCS(cend)(str) }; 
}

and this causes a C++ compiler error because cpp2::move is not constexpr.

Repro on Godbolt

Workaround

Discarding the it variable prevents the move:

trim_start: (str: std::string_view) -> std::string_view == {
    it:= std::ranges::find_if_not(str, :(ch: char) ch == ' ');
    return (it, str.cend());
    _ = it;
}

But I don't think that's ideal to have to spell out (and reads awkwardly after the return) so marking cpp2::move as constexpr would be better.

Additional context I was translating the ranges::mismatch example from cppreference:

[[nodiscard]]
constexpr [std::string_view](http://en.cppreference.com/w/cpp/string/basic_string_view) mirror_ends(const [std::string_view](http://en.cppreference.com/w/cpp/string/basic_string_view) in)
{
    const auto end = std::ranges::mismatch(in, in | std::[views::reverse](http://en.cppreference.com/w/cpp/ranges/reverse_view)).in1;
    return {in.cbegin(), end};
}
hsutter commented 2 weeks ago

Thanks! Yes, cpp2::move should be inline constexpr, that would solve this problem.

hsutter commented 2 weeks ago

Ah, and there's the PR. Thanks!

hsutter commented 2 weeks ago

Closed by #1106