@@ -6,13 +6,12 @@ This discussion is meant to focus on the following things:
66
77- What guarantees does Rust make regarding the layout of data structures?
88- What guarantees does Rust make regarding ABI compatibility?
9- - What invariants does the compiler require from the various Rust types?
10- - the "validity invariant", as defined in [ Ralf's blog post] [ bp ]
119
12- NB. The discussion is ** not** meant to discuss the "safety invariant"
13- from [ Ralf's blog post] [ bp ] , as that can be handled later.
14-
15- [ bp ] : https://www.ralfj.de/blog/2018/08/22/two-kinds-of-invariants.html
10+ NB. Oftentimes, choices of layout will only be possible if we can
11+ guarantee various invariants -- this is particularly true when
12+ optimizing the layout of ` Option ` or other enums. However, designing
13+ those invariants is left for a future discussion -- here, we should
14+ document/describe what we currently do and/or aim to support.
1615
1716### Layout of data structures
1817
@@ -50,30 +49,13 @@ goal of the `#[repr(transparent)]` annotation introduced in [RFC
5049for us to specify how they are treated at the point of a function
5150call.
5251
53- ### Validity invariant
54-
55- The "validity invariant" for each type defines what must hold whenever
56- a value of this type is considered to be initialized. The compiler expects
57- the validity invariant to hold ** at all times** and is thus allowed to use
58- these invariants to (e.g.) affect the layout of data structures or do other
59- optimizations.
60-
61- Therefore, the validity invariant must ** at minimum** justify all the
62- layout optimizations that the compiler does. We may want a stronger
63- invariant, however, so as to leave room for future optimization.
64-
65- As an example, a value of ` &T ` type can never be null -- therefore,
66- ` Option<&T> ` can use null to represent ` None ` .
67-
6852## Goals
6953
70- - Define what we guarantee about the layout of various types
71- and the effect of ` #[repr] ` annotations.
72- - Define the ** validity requirements** of various types. These are the
73- requirements that must hold at all times when the compiler considers
74- a value to be initialized.
75- - Also examine when/how we could dynamically check these requirements.
76- - Uncover the sorts of constraints that we may wish to satisfy in the
54+ - Document current behavior of compiler.
55+ - Indicate which behavior is "permitted" for compiler and which
56+ aspects are things that unsafe code can rely upon.
57+ - Include the effect of ` #[repr] ` annotations.
58+ - Uncover the sorts of layout optimizations we may wish to do in the
7759 future.
7860
7961## Some interesting examples and questions
@@ -83,6 +65,7 @@ As an example, a value of `&T` type can never be null -- therefore,
8365- ` Option<&T> ` where ` T: Sized `
8466 - This is ** guaranteed** to be a nullable pointer
8567- ` Option<extern "C" fn()> `
68+ - Can this be assumed to be a non-null pointer?
8669- ` usize `
8770 - Platform dependent size, but guaranteed to be able to store a pointer?
8871 - Also an array length?
@@ -103,11 +86,9 @@ To start, we will create threads for each major categories of types
10386(with a few suggested focus points):
10487
10588- Integers and floating points
106- - What about uninitialized values?
10789 - What about signaling NaN etc? ([ Seems like a
10890 non-issue] ( https://github.com/rust-lang/rust/issues/40470#issuecomment-343803381 ) ,
10991 but it'd be good to resummarize the details).
110- - usize/isize
11192 - is ` usize ` the native size of a pointer? [ the max of various other considerations] ( https://github.com/rust-rfcs/unsafe-code-guidelines/pull/5#discussion_r212702266 ) ?
11293 what are edge cases here?
11394 - Rust currently states that the maximum size of any single value must fit in with ` isize `
@@ -131,9 +112,9 @@ To start, we will create threads for each major categories of types
131112 - For example, [ rkruppe
132113 writes] ( https://github.com/rust-rfcs/unsafe-code-guidelines/pull/5#discussion_r212776247 )
133114 that we might "want to guarantee (some subset of) newtype
134- unpacking and relegate repr(transparent) to being the way to
135- guarantee to other crates that a type with private fields is and
136- will remain a newtype?"
115+ unpacking and relegate ` #[ repr(transparent)] ` to being the way
116+ to guarantee to other crates that a type with private fields is
117+ and will remain a newtype?"
137118- Tuples
138119 - Are these effectively anonymous structs?
139120- Unions
@@ -147,10 +128,10 @@ To start, we will create threads for each major categories of types
147128 distinction between ` void* ` and a function pointer, but are
148129 there any modern and/or realisic platforms where it is an
149130 issue?
131+ - Is ` Option<extern "C" fn()> ` guaranteed to be a pointer (possibly null)?
150132- References ` &T ` and ` &mut T `
151133 - Out of scope: aliasing rules
152- - We currently tell LLVM they are aligned and dereferenceable, have to justify that
153- - Safe code may use them also
134+ - Always aligned, non-null
154135 - When using the C ABI, these map to the C pointer types, presumably
155136- Raw pointers
156137 - Effectively same as integers?
@@ -160,13 +141,6 @@ To start, we will create threads for each major categories of types
160141 - Custom alignment ([ RFC 1358] )
161142 - Packed ([ RFC 1240] talks about some safety issues)
162143
163- We will also create categories for the following specific areas:
164-
165- - Niches: Optimizing ` Option ` -like enums
166- - Uninitialized memory: when/where are uninitializes values permitted, if ever?
167- - ... what else?
168-
169-
170144[ #46156 ] : https://github.com/rust-lang/rust/pull/46156
171145[ #46176 ] : https://github.com/rust-lang/rust/pull/46176
172146[ RFC 2363 ] : https://github.com/rust-lang/rfcs/pull/2363
0 commit comments