Skip to content

Commit 24daaff

Browse files
committed
More wordsmithing on the changes I just added.
1 parent 59a661a commit 24daaff

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

posts/2022-09-15-const-eval-safety-rule-revision.md

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,17 @@ to above is trying to reinterpret the memory address `&()` as an integer of type
7272
associated with at execution time, so it refuses to allow that reinterpretation.
7373

7474
When you write safe Rust, then the compiler is responsible for preventing
75-
undefined behavior. When you write any unsafe code (be it const or non-const), you are
76-
responsible for preventing UB. The Rust compiler will protect itself from being
77-
[adversely affected][const-ub-guide], but other than that there are few
78-
guarantees. Specifically: If you have UB at const-eval time, there is no
79-
guarantee that your code will be accepted from one compiler version to another.
75+
undefined behavior. When you write any unsafe code (be it const or non-const),
76+
you are responsible for preventing UB, and during const-eval, the rules about
77+
what unsafe code has defined behavior are even more strict than the analogous
78+
rules governing Rust's runtime semantics. (In other words, *more* code is
79+
classified as "UB" than you may have otherwise realized.)
80+
81+
If you hit undefined behavior during const-eval, the Rust compiler will protect
82+
itself from [adverse effects][const-ub-guide], but there are few guarantees
83+
other than that. For example, compile-time UB could lead to runtime UB.
84+
Furthermore, if you have UB at const-eval time, there is no guarantee that your
85+
code will be accepted from one compiler version to another.
8086

8187
[const-ub-guide]: https://github.com/rust-lang/rfcs/blob/master/text/3016-const-ub.md#guide-level-explanation
8288

@@ -173,21 +179,23 @@ pointing out that these tools can pinpoint the injection point more precisely.)
173179

174180
Why not have these extra const-ub checks on by default? Well, the checks
175181
introduce performance overhead upon Rust compilation time, and we do not know if
176-
that overhead can be made acceptable. However, [recent debate][perf argument]
182+
that overhead can be made acceptable. (However, [recent debate][perf argument]
177183
among Miri developers indicates that the inherent cost here might not be as bad
178-
as they had originally thought.
184+
as they had originally thought. Perhaps a future version of the compiler will
185+
have these extra checks on by default.)
179186

180187
[perf argument]: https://rust-lang.zulipchat.com/#narrow/stream/238009-t-compiler.2Fmeetings/topic/.5Bsteering.20meeting.5D.202022-09-02.20const-eval.20and.20future-compa.2E.2E.2E/near/296853344
181188

182189
## Change is hard
183190

184191
You might well be wondering at this point: "Wait, when *is* it okay to transmute
185-
a pointer to a `usize` during const evaluation?" And the answer is: "Never."
192+
a pointer to a `usize` during const evaluation?" And the answer is simple:
193+
"Never."
186194

187195
Transmuting a pointer to a usize during const-eval has always been undefined behavior,
188196
ever since const-eval added support for
189197
`transmute` and `union`. You can read more about this in the
190-
`const_fn_`{`transmute`,`union`} [stabilization report][cftu report],
198+
`const_fn_transmute` / `const_fn_union` [stabilization report][cftu report],
191199
specifically the subsection entitled "Pointer-integer-transmutes".
192200

193201
[cftu report]: https://github.com/rust-lang/rust/pull/85769#issuecomment-854363720
@@ -286,15 +294,18 @@ can say Hello in the [miri zulip][].
286294

287295
## Conclusion
288296

289-
When you write safe Rust, then the compiler is responsible for preventing
290-
undefined behavior. When you write any unsafe code, you are responsible for
291-
preventing undefined behavior. If you have undefined behavior at const-eval
292-
time, there is no guarantee that your code will be accepted from one compiler
293-
version to another.
297+
To sum it all up: When you write safe Rust, then the compiler is responsible for
298+
preventing undefined behavior. When you write any unsafe code, *you* are
299+
responsible for preventing undefined behavior. Rust's const-eval system has a
300+
stricter set of rules governing what unsafe code has defined behavior:
301+
specifically, reinterpreting (aka "transmuting") a pointer value as a `usize` is
302+
undefined behavior during const-eval. If you have undefined behavior at
303+
const-eval time, there is no guarantee that your code will be accepted from one
304+
compiler version to another.
294305

295306
The compiler team is hoping that issue [#99923][] is an exceptional fluke and
296307
that the 1.64 stable release will not encounter any other surprises related to
297-
this change to the const-eval machinery.
308+
the aforementioned change to the const-eval machinery.
298309

299310
But fluke or not, the issue provided excellent motivation to spend some time
300311
exploring facets of Rust's const-eval architecture, and the Miri interpreter

0 commit comments

Comments
 (0)