@@ -178,3 +178,42 @@ statement, and only later see the `if` and realize it's a conditional return.
178
178
179
179
Such a change would also have non-obvious evaluation order (evaluating the
180
180
condition before the return expression).
181
+
182
+ ## Size != Stride
183
+
184
+ Rust assumes that the size of an object is equivalent to the stride of an object -
185
+ this means that the size of ` [T; N] ` is ` N * std::mem::size_of::<T> ` . Allowing
186
+ size to not equal stride may allow objects that take up less space in arrays due
187
+ to the reuse of tail padding, and allow interop with other languages with this behavior.
188
+
189
+ One downside of this assumption is that types with alignment greater than their size can
190
+ waste large amounts of space due to padding. An overaligned struct such as the following:
191
+ ```
192
+ #[repr(C, align(512))]
193
+ struct Overaligned(u8);
194
+ ```
195
+ will store only 1 byte of data, but will have 511 bytes of tail padding for a total size of
196
+ 512 bytes. This tail padding will not be reusable, and adding ` Overaligned ` as a struct field
197
+ may exacerbate this waste as additional trailing padding be included after any other members.
198
+
199
+ Rust makes several guarantees that make supporting size != stride difficult in the general case.
200
+ The combination of ` std::array::from_ref ` and array indexing is a stable guarantee that a pointer
201
+ (or reference) to a type is convertible to a pointer to a 1-array of that type, and vice versa.
202
+
203
+ Such a change could also pose problems for existing unsafe code, which may assume that pointers
204
+ can be manually offset by the size of the type to access the next array element. Unsafe
205
+ code may also assume that overwriting trailing padding is allowed, which would conflict with
206
+ the repurposing of such padding for data storage.
207
+
208
+ While changing the fundamental layout guarantees seems unlikely, it may be reasonable to add additional
209
+ inspection APIs for code that wishes to opt into the possibility of copying smaller parts of an object
210
+ -- an API to find out that copying only bytes ` 0..1 ` of ` Overaligned ` is sufficient might still be
211
+ reasonable, or something ` size_of_val ` -like that could be variant-aware to say which bytes are sufficient
212
+ for copying a particular instance. Similarly, move-only fields may allow users to mitigate the effects
213
+ of tail or internal padding, as they can be reused due to the lack of a possible reference or pointer.
214
+
215
+ Cross-referencing to other discussions:
216
+
217
+ * https://github.com/rust-lang/rfcs/issues/1397
218
+ * https://github.com/rust-lang/rust/issues/17027
219
+ * https://github.com/rust-lang/unsafe-code-guidelines/issues/176
0 commit comments