Closed
Description
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};
}