RFC 0533: no-array-elem-moves

lang (typesystem | expressions | array | drop)

Summary

In order to prepare for an expected future implementation of non-zeroing dynamic drop, remove support for:

Motivation

If we want to continue supporting dynamic drop while also removing automatic memory zeroing and drop-flags, then we need to either (1.) adopt potential complex code generation strategies to support arrays with only some elements initialized (as discussed in the unresolved questions for RFC PR 320, or we need to (2.) remove support for constructing such arrays in safe code.

This RFC is proposing the second tack.

The expectation is that relatively few libraries need to support moving out of fixed-sized arrays (and even fewer take advantage of being able to initialize individual elements of an uninitialized array, as supporting this was almost certainly not intentional in the language design). Therefore removing the feature from the language will present relatively little burden.

Detailed design

If an expression e has type [T; n] and T does not implement Copy, then it will be illegal to use e[i] in an r-value position.

If an expression e has type [T; n] expression e[i] = <expr> will be made illegal at points in the control flow where e has not yet been initialized.

Note that it remains legal to overwrite an element in an initialized array: e[i] = <expr>, as today. This will continue to drop the overwritten element before moving the result of <expr> into place.

Note also that the proposed change has no effect on the semantics of destructuring bind; i.e. fn([a, b, c]: [Elem; 3]) { ... } will continue to work as much as it does today.

A prototype implementation has been posted at Rust PR 21930.

Drawbacks

Also, as noted in the comment thread from RFC PR 320

Alternatives

We can just leave things as they are; there are hypothetical code-generation strategies for supporting non-zeroing drop even with this feature, as discussed in the comment thread from RFC PR 320.

Unresolved questions

None