Skip to content

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

Closed
@bluetarpmedia

Description

@bluetarpmedia

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions