There are cases where borrowed references provide a view to a larger object in memory than the nominal sized type being referenced. When only immutable references are available on such types, it’s possible to prevent copying out the nominal sized value in safe code, but there is still potential for trouble with values under reference having a bogus size. A couple of examples:
-
CStr
as a proposed ‘thin’ dereference type forCString
. A token type to represent an undetermined number of bytes in a null-terminated string. As currently defined, the struct has size of 1. - A structure that is a public view into a larger contiguously allocated object (e.g. obtained via FFI). Rust methods are implemented on the public structure, but for them to work the whole object has to be present.
To prevent unintended use of such types as sized, could a further distinction be made under non-Sized
types, between DSTs and completely unsized types?
How I could see this done, is [T]
, str
, and types containing them would get a new intrinsically implemented trait DynamicSize
, and non-DSTs could opt out of Sized
(and out of Copy
) by including a marker:
struct CStr {
head: libc::c_char, // Contains at least one character...
rest: std::marker::NotSized // ...but there can be more
}
DynamicSize
will be determinant in deciding whether a reference to the type will be ‘fat’ and require the actual size of the data to be computed at runtime. Things like std::mem::size_of
, on the other hand, will continue being bound by Sized
, so a truly unsized type under reference cannot be misinterpreted as a value that can be copied or otherwise used in isolation from its current location in memory.
Thoughts? Feasible?