Skip to content

Commit e250f62

Browse files
committed
describe static vs dynamic const checks
1 parent a71d34f commit e250f62

File tree

3 files changed

+32
-1
lines changed

3 files changed

+32
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ which sort of is a virtual machine using `MIR` as "bytecode".
2121
## Table of Contents
2222

2323
* [Const Safety](const_safety.md)
24+
* [Static and dynamic checks](const_checks.md)
2425
* The three "kinds" of compile-time evaluated data:
2526
* [Statics](static.md) (`static`, `static mut`)
2627
* [Constants](const.md) (`const`, array sizes, non-`Copy` array initializers)

const_checks.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Static and dynamic checks
2+
3+
This repository describes a set of rules that various forms of compile-time evaluated code needs to satisfy.
4+
The compiler contains two kinds of checks that guard against violations of these rules: static checks and dynamic checks.
5+
6+
## Dynamic checks
7+
8+
Dynamic checks are conceptually very simple: when evaluating the compile-time code, we look at what it does, and if what it does violates the rules, we halt evaluation.
9+
Thus, a dynamic check generally makes it very clear what is being protected against.
10+
11+
The main disadvantage of dynamic checks is that they can only run when the compile-time code is being evaluated, which is after monomorphization.
12+
We generally try to avoid post-monomorphization errors as they make for a bad user experience.
13+
14+
[Promotion analysis](promotion.md) also makes little sense dynamically as it is about code transformation.
15+
All we can do is check after the transformation if the generated code makes sense.
16+
17+
## Static checks
18+
19+
Static checks work by "looking" at the code.
20+
(This is "static" as in [static analysis](https://en.wikipedia.org/wiki/Static_analysis), not to be confused with Rust's `static` keyword.)
21+
The idea is to predict what the code will do without actually executing it.
22+
That means we can even analyze code that we cannot run pre-monomorphization.
23+
However, static checks are necessarily less precise than dynamic checks (this is the famous halting problem), which means they will reject code that the dynamic checks would accept.
24+
25+
The key property is that the static check is *sound*, which means that everything accepted by the static checks will also be accepted by the dynamic checks.
26+
It might seem like this makes the dynamic checks unnecessary, but they are still tremendously useful.
27+
On the one hand, the dynamic checks serve as a safety net for when we have bugs in the static checks (dynamic checks are much easier to get right, typically).
28+
On the other hand, having the dynamic checks forces us through the helpful exercise of figuring out what the dynamic property we are enforcing actually *is*, which is crucial when we want to adjust the static check to be more precise.
29+
The dynamic check serves as the "ground truth" that the static check approximates, and we can improve that approximation over time.

static.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ Statics (`static`, `static mut`) are the simplest kind of compile-time evaluated
1414
## `Drop`
1515

1616
The compiler rejects intermediate values (created and discarded during the computation of a static initializer) that implement `Drop`.
17-
The reason for this is simply that the `Drop` implementation might be non-`const fn`.
17+
The reason for this is simply that the `Drop` implementation might be non-`const fn`
18+
(so really, this is just a special case of static initializers not being able to call non-`const` functions).
1819
This restriction can be lifted once `const impl Drop for Type` (or something similar) is supported.
1920

2021
```rust

0 commit comments

Comments
 (0)