Skip to content

Commit 965fbeb

Browse files
committed
Initial documents
1 parent fab6ed9 commit 965fbeb

File tree

3 files changed

+86
-0
lines changed

3 files changed

+86
-0
lines changed

README.md

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Constant Evaluation
2+
3+
Constant evaluation is the process of running Rust code at compile-time
4+
in order to use the result e.g. to set the discriminant of enum variants
5+
or as an array length.
6+
7+
Examples:
8+
9+
```rust
10+
enum Foo {
11+
A = 5,
12+
B = 7 - 3,
13+
}
14+
type NineStrings = [&str, 3 * 3];
15+
```
16+
17+
The Rust compiler runs the [MIR](https://rust-lang-nursery.github.io/rustc-guide/mir/index.html)
18+
in the [`MIR` interpreter (miri)](https://rust-lang-nursery.github.io/rustc-guide/const-eval.html),
19+
which sort of is a virtual machine using `MIR` as "bytecode".
20+
21+
## Related RFCs
22+
23+
### Const Promotion
24+
25+
[RFC 1414](https://github.com/rust-lang/rfcs/pull/1414) injects a hidden static for any
26+
`&foo` expression as long as `foo` follows a certain set of rules.
27+
These rules are discussed [here](promotion.md)
28+
29+
### Drop types in constants/statics
30+
31+
[RFC 1440](https://github.com/rust-lang/rfcs/pull/1440) allows using types that implement
32+
`Drop` (or have fields that do so) inside constants and statics. It is guaranteed that the
33+
`Drop::drop` method will never be called on the static/const object.
34+
35+
### Constants in Repeat expressions
36+
37+
[RFC 2203](https://github.com/rust-lang/rfcs/pull/2203) allows the use `!Copy` types for the
38+
initializer of repeat expressions, as long as that value is constant.
39+
40+
This permits e.g. `[Vec::new(); 42]`.
41+
42+
### Statically known bugs and panics in runtime code are warnings
43+
44+
[RFC 1229](https://github.com/rust-lang/rfcs/pull/1229) formalized the concept that
45+
46+
```rust
47+
let x: usize = 1 - 2;
48+
```
49+
50+
is allowed to produce a `lint` but not an `error`. This allows us to make these analyses
51+
more powerful without suddenly breaking compilation. The corresponding lint is the `const_err`
52+
lint, which is `deny` by default and will thus break compilation of the crate currently being built,
53+
even if it does not break the compilation of the current crate's dependencies.
54+
55+
### Various new const-eval features
56+
57+
* [`loop`](https://github.com/rust-lang/rfcs/pull/2344)
58+
* [`if` and `match`](https://github.com/rust-lang/rfcs/pull/2342)
59+
* [`panic!`](https://github.com/rust-lang/rfcs/pull/2345)
60+
* [`locals and destructuring`](https://github.com/rust-lang/rfcs/pull/2341)
61+
62+
Some of these features interact. E.g.
63+
64+
* `match` + `loop` yields `while`
65+
* `panic!` + `if` + `locals` yields `assert!`

const_safety.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Const safety

promotion.md

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Const promotion
2+
3+
## Rules
4+
5+
### 1. No side effects
6+
7+
Promotion is not allowed to throw away side effects.
8+
This includes panicking. So in order to promote `&(0_usize - 1)`,
9+
the subtraction is thrown away and only the panic is kept.
10+
11+
### 2. Const safety
12+
13+
Only const safe code gets promoted. This means that promotion doesn't happen
14+
if the code does some action which, when run at compile time, either errors or
15+
produces a value that differs from runtime.
16+
17+
An example of this would be `&1 as *const i32 as usize == 42`. While it is highly
18+
unlikely that the address of temporary value is `42`, at runtime this could be true.
19+
20+
The exact details for `const safety` are discussed in [here](const_safety.md).

0 commit comments

Comments
 (0)