Skip to content

Commit

Permalink
move const/static section to other promotion contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Aug 13, 2020
1 parent 9d36e9a commit 61b55a0
Showing 1 changed file with 30 additions and 30 deletions.
60 changes: 30 additions & 30 deletions promotion.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,36 @@ attribute, introduced in
specify these parameters and (aggressively, see below) try to promote the
corresponding arguments.

### Promotion inside `const` and `static`

Lifetime extension is also responsible for making code like this work:

```rust
const FOO: &'static i32 = {
let x = &13;
x
};
```

Like in run-time code, a part of the MIR (the one computing `13`) is spliced
into a separate MIR body, and evaluated like a separate constant. In the case
of `const` and `static` initializers, this does not affect how the code is
evaluated (everything happens at compile-time), but it still affects the
lifetimes.

Notice that some code involving `&` *looks* like it relies on lifetime
extension but actually does not:

```rust
const EMPTY_BYTES: &Vec<u8> = &Vec::new(); // Ok without lifetime extension
```

`Vec::new()` cannot get promoted because it needs dropping. And yet this
compiles. Why that? The reason is that the reference obtains the lifetime of
the "enclosing scope", similar to how `let x = &mut x;` creates a reference
whose lifetime lasts for the enclosing scope. This is decided during MIR
building already, and does not involve lifetime extension.

## Implicit and explicit promotion

On top of what applies to [consts](const.md), promoteds suffer from the additional issue that *the user did not ask for them to be evaluated at compile-time*.
Expand Down Expand Up @@ -78,36 +108,6 @@ mutability and values that need dropping are not promoted.

[warn-rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1229-compile-time-asserts.md

## Promotion inside `const` and `static`

Lifetime extension is also responsible for making code like this work:

```rust
const FOO: &'static i32 = {
let x = &13;
x
};
```

Like in run-time code, a part of the MIR (the one computing `13`) is spliced
into a separate MIR body, and evaluated like a separate constant. In the case
of `const` and `static` initializers, this does not affect how the code is
evaluated (everything happens at compile-time), but it still affects the
lifetimes.

Notice that some code involving `&` *looks* like it relies on lifetime
extension but actually does not:

```rust
const EMPTY_BYTES: &Vec<u8> = &Vec::new(); // Ok without lifetime extension
```

`Vec::new()` cannot get promoted because it needs dropping. And yet this
compiles. Why that? The reason is that the reference obtains the lifetime of
the "enclosing scope", similar to how `let x = &mut x;` creates a reference
whose lifetime lasts for the enclosing scope. This is decided during MIR
building already, and does not involve lifetime extension.

## Promotability

We have described the circumstances where promotion is desirable, but what
Expand Down

0 comments on commit 61b55a0

Please sign in to comment.