beast icon indicating copy to clipboard operation
beast copied to clipboard

Misplaced static_assert in basic_field's move-assignment operator

Open Tradias opened this issue 3 years ago • 7 comments

Version of Beast: 1.80.0

Steps necessary to reproduce the problem

https://godbolt.org/z/vdfYrEE1e

Error:

/opt/compiler-explorer/libs/boost_1_80_0/boost/beast/http/impl/fields.hpp: In instantiation of 'boost::beast::http::basic_fields<Allocator>& boost::beast::http::basic_fields<Allocator>::operator=(boost::beast::http::basic_fields<Allocator>&&) [with Allocator = std::pmr::polymorphic_allocator<>]':
<source>:7:31:   required from here
/opt/compiler-explorer/libs/boost_1_80_0/boost/beast/http/impl/fields.hpp:440:58: error: static assertion failed: Allocator must be noexcept assignable.
  440 |     static_assert(is_nothrow_move_assignable<Allocator>::value,
      |                                                          ^~~~~
/opt/compiler-explorer/libs/boost_1_80_0/boost/beast/http/impl/fields.hpp:440:58: note: 'boost::integral_constant<bool, false>::value' evaluates to false
Compiler returned: 1

Proposed solution

Move the static_assertion from fields.hpp#L440 to the noexcept specifier:

template<class Allocator>
auto
basic_fields<Allocator>::
operator=(basic_fields&& other) noexcept(
    std::conjunction_v<alloc_traits::propagate_on_container_move_assignment, is_nothrow_move_assignable<Allocator>>)
      -> basic_fields&
{

And actually move assign the allocator instead of copy assigning it in fields.hpp#L1132.

Tradias avatar Sep 08 '22 14:09 Tradias

The same is true for std::vector. https://godbolt.org/z/3rxj9sKs7

@vinniefalco What (if any) is the intention here?

madmongo1 avatar Sep 08 '22 17:09 madmongo1

@madmongo1 your example is malformed, here is the corrected one that compiles successfully: https://godbolt.org/z/aaKjbaoEc

Tradias avatar Sep 08 '22 17:09 Tradias

@vinniefalco What (if any) is the intention here?

I have no idea to be honest. Allocators are cancer.

vinniefalco avatar Sep 08 '22 23:09 vinniefalco

I ran into this as well and found related background in p0337 - Delete operator= for polymorphic_allocator

Given that a polymorphic_allocator is not propagated on assignment, one may question the usefulness of the assignment operators. Indeed, it seems that most uses of assignment for polymorphic_allocator are likely to be errors.

xbreak avatar Sep 23 '22 09:09 xbreak

The static assert doesn't seem to be misplaced, move-assignments work fine: https://godbolt.org/z/7Pnn99KzW

What is needed is support for propagate_on_container_move_assignment.

klemens-morgenstern avatar Sep 24 '22 04:09 klemens-morgenstern

@klemens-morgenstern ? Your example doesn't perform move-assignment at all: https://godbolt.org/z/vdfYrEE1e

Tradias avatar Sep 24 '22 07:09 Tradias

Or maybe a more simplified example showing it is unrelated to propagate_on_container_move_assignment: https://godbolt.org/z/Kb8d66fb5

Tradias avatar Sep 24 '22 07:09 Tradias