Requirement that deserialized types be MoveConstructible is too strong

Issue #198 resolved
Amir Kamil created an issue

The spec states the following at the end of section 6.1:

Implementations of serialization may require moving deserialized objects after constructing them. It is an error to serialize an object of type T if its deserialized counterpart deserialized_type_t<T> (§6.2.6) is not MoveConstructible.

However, non-MoveConstructible types can be correctly handled by deserializing_iterator<T>::deserialize_into() and [Reader]::read_into<T>(), as well as views over TriviallySerializable types.

As far as I can tell, the only place where the implementation requires MoveConstructibility is for deserializing the arguments to rpc() and as_rpc(). We should remove the blanket requirement and instead state the requirement explicitly for rpc() and as_rpc().

Comments (4)

  1. Dan Bonachea

    I believe we have consensus that this relaxation is a good idea.

    I believe we also need the MoveConstructible requirement along the RPC return value path (ie MoveConstructible deserialized_type_t<T> for RPC callback returning T or future<T>). One could argue this is already covered by 7.1-18, which dictates Copy/Move requirements for completion event values -- but that's definitely non-obvious and is probably worth at least a cross-reference from the section where we discuss the RPC return value. Note we already require MoveConstructible for a non-reference or rvalue-reference return type T, so this is an additional/related constraint.

    I think it's also worth clarifying in future <deserialized_type_t <T>> dist_object <T>::fetch() that both T AND deserialized_type_t <T> must be MoveConstructible.

    Please proceed with PRs for the change, ideally as independent/targeted PRs.

  2. Dan Bonachea

    As noted in this comment on Impl PR 443, I suspect that our deserialization implementation for std::pair<T,U> and std::tuple<T,U> require that deserialized_type_t<T> and deserialized_type_t<U> must be MoveConstructible, regardless of the context where that deserialization is invoked. This might also be true of other containers..

  3. Amir Kamil reporter

    All standard-library containers require their constituents to be MoveConstructible. The only exception in the implementation is deserializing a std::array into raw memory. However, since deserializing into an optional does require MoveConstructibility and the implementation of deserializing into raw memory relies heavily on UB, I don’t think we should guarantee that it works.

  4. Log in to comment