@@ -6,13 +6,12 @@ This discussion is meant to focus on the following things:
6
6
7
7
- What guarantees does Rust make regarding the layout of data structures?
8
8
- 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 ]
11
9
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.
16
15
17
16
### Layout of data structures
18
17
@@ -50,30 +49,13 @@ goal of the `#[repr(transparent)]` annotation introduced in [RFC
50
49
for us to specify how they are treated at the point of a function
51
50
call.
52
51
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
-
68
52
## Goals
69
53
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
77
59
future.
78
60
79
61
## Some interesting examples and questions
@@ -83,6 +65,7 @@ As an example, a value of `&T` type can never be null -- therefore,
83
65
- ` Option<&T> ` where ` T: Sized `
84
66
- This is ** guaranteed** to be a nullable pointer
85
67
- ` Option<extern "C" fn()> `
68
+ - Can this be assumed to be a non-null pointer?
86
69
- ` usize `
87
70
- Platform dependent size, but guaranteed to be able to store a pointer?
88
71
- Also an array length?
@@ -103,11 +86,9 @@ To start, we will create threads for each major categories of types
103
86
(with a few suggested focus points):
104
87
105
88
- Integers and floating points
106
- - What about uninitialized values?
107
89
- What about signaling NaN etc? ([ Seems like a
108
90
non-issue] ( https://github.com/rust-lang/rust/issues/40470#issuecomment-343803381 ) ,
109
91
but it'd be good to resummarize the details).
110
- - usize/isize
111
92
- 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 ) ?
112
93
what are edge cases here?
113
94
- 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
131
112
- For example, [ rkruppe
132
113
writes] ( https://github.com/rust-rfcs/unsafe-code-guidelines/pull/5#discussion_r212776247 )
133
114
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?"
137
118
- Tuples
138
119
- Are these effectively anonymous structs?
139
120
- Unions
@@ -147,10 +128,10 @@ To start, we will create threads for each major categories of types
147
128
distinction between ` void* ` and a function pointer, but are
148
129
there any modern and/or realisic platforms where it is an
149
130
issue?
131
+ - Is ` Option<extern "C" fn()> ` guaranteed to be a pointer (possibly null)?
150
132
- References ` &T ` and ` &mut T `
151
133
- 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
154
135
- When using the C ABI, these map to the C pointer types, presumably
155
136
- Raw pointers
156
137
- Effectively same as integers?
@@ -160,13 +141,6 @@ To start, we will create threads for each major categories of types
160
141
- Custom alignment ([ RFC 1358] )
161
142
- Packed ([ RFC 1240] talks about some safety issues)
162
143
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
-
170
144
[ #46156 ] : https://github.com/rust-lang/rust/pull/46156
171
145
[ #46176 ] : https://github.com/rust-lang/rust/pull/46176
172
146
[ RFC 2363 ] : https://github.com/rust-lang/rfcs/pull/2363
0 commit comments