Requirement that deserialized types be MoveConstructible is too strong
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 counterpartdeserialized_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)
-
-
As noted in this comment on Impl PR 443, I suspect that our deserialization implementation for
std::pair<T,U>
andstd::tuple<T,U>
require thatdeserialized_type_t<T>
anddeserialized_type_t<U>
must be MoveConstructible, regardless of the context where that deserialization is invoked. This might also be true of other containers.. -
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. -
- changed status to resolved
Resolved in spec PR 91, merged at 547fee6
- Log in to comment
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 returningT
orfuture<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 typeT
, 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 bothT
ANDdeserialized_type_t <T>
must be MoveConstructible.Please proceed with PRs for the change, ideally as independent/targeted PRs.