Skip to content

Commit cf2fbba

Browse files
Merge pull request #166 from Havvy/rfc-1440
Document RFC 1440.
2 parents 11f33bd + 0def4b6 commit cf2fbba

File tree

4 files changed

+60
-33
lines changed

4 files changed

+60
-33
lines changed

src/expressions.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -209,25 +209,25 @@ then it is a compiler error if the value must be evaluated at compile time,
209209
otherwise it is just a warning, but the code will most likely panic when run.
210210

211211
The following expressions are constant expressions, so long as any operands are
212-
also constant expressions:
212+
also constant expressions and do not cause any [`Drop::drop`][destructors] calls
213+
to be ran.
213214

214215
* [Literals].
215216
* [Paths] to [functions](items/functions.html) and constants.
216217
Recursively defining constants is not allowed.
217218
* [Tuple expressions].
218219
* [Array expressions].
219-
* [Struct] expressions, where the type does not implement [`Drop`](the-drop-trait.html).
220-
* [Enum variant] expressions, where the enumeration type does not implement `Drop`.
221-
* [Block expressions] (and `unsafe` blocks) which only contain items and
222-
possibly a (constant) tail expression.
220+
* [Struct] expressions.
221+
* [Enum variant] expressions.
222+
* [Block expressions], including `unsafe` blocks, which only contain items and
223+
possibly a constant tail expression.
223224
* [Field] expressions.
224225
* Index expressions, [array indexing] or [slice] with a `usize`.
225226
* [Range expressions].
226227
* [Closure expressions] which don't capture variables from the environment.
227228
* Built in [negation], [arithmetic, logical], [comparison] or [lazy boolean]
228229
operators used on integer and floating point types, `bool` and `char`.
229-
* Shared [borrow], except if applied to a type with [interior
230-
mutability](interior-mutability.html).
230+
* Shared [borrow]s, except if applied to a type with [interior mutability].
231231
* The [dereference operator].
232232
* [Grouped] expressions.
233233
* [Cast] expressions, except pointer to address and
@@ -269,4 +269,6 @@ exist in `core::ops` and `core::cmp` with the same names.
269269
[negation]: expressions/operator-expr.html#negation-operators
270270
[overflow]: expressions/operator-expr.html#overflow
271271

272+
[destructors]: destructors.html
273+
[interior-mutability]: interior-mutability.html
272274
[slice]: types.html#array-and-slice-types

src/interior-mutability.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Interior Mutability
22

3-
Sometimes a type needs be mutated while having multiple aliases, in Rust this
3+
Sometimes a type needs be mutated while having multiple aliases. In Rust this
44
is achieved using a pattern called _interior mutability_. A type has interior
55
mutability if its internal state can be changed through a [shared reference] to
66
it. This goes against the usual [requirement][ub] that the value pointed to by a
77
shared reference is not mutated.
88

9-
[`std::cell::UnsafeCell<T>`] type is the only legal way in Rust to disable this
10-
requirement. When `UnsafeCell<T>` is immutably aliased, it is still safe to
9+
[`std::cell::UnsafeCell<T>`] type is the only allowed way in Rust to disable
10+
this requirement. When `UnsafeCell<T>` is immutably aliased, it is still safe to
1111
mutate, or obtain a mutable reference to, the `T` it contains. As with all
1212
other types, it is undefined behavior to have multiple `&mut UnsafeCell<T>`
1313
aliases.

src/items/constant-items.md

+28-7
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@ wherever they are used, meaning that they are copied directly into the relevant
1010
context when used. References to the same constant are not necessarily
1111
guaranteed to refer to the same memory address.
1212

13-
Constant values must not have destructors, and otherwise permit most forms of
14-
data. Constants may refer to the address of other constants, in which case the
13+
Constants must be explicitly typed. The type must have a `'static` lifetime: any
14+
references it contains must have `'static` lifetimes.
15+
16+
Constants may refer to the address of other constants, in which case the
1517
address will have elided lifetimes where applicable, otherwise – in most cases
16-
– defaulting to the `static` lifetime. (See below on [static lifetime
18+
– defaulting to the `static` lifetime. (See [static lifetime
1719
elision].) The compiler is, however, still at liberty to translate the constant
1820
many times, so the address referred to may not be stable.
1921

20-
Constants must be explicitly typed. The type may be any type that doesn't
21-
implement [`Drop`] and has a `'static` lifetime: any references it contains
22-
must have `'static` lifetimes.
23-
2422
```rust
2523
const BIT1: u32 = 1 << 0;
2624
const BIT2: u32 = 1 << 1;
@@ -39,6 +37,29 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
3937
};
4038
```
4139

40+
## Constants with Destructors
41+
42+
Constants can contain destructors. Destructors are ran when the value goes out
43+
of scope.
44+
45+
```rust
46+
struct TypeWithDestructor(i32);
47+
48+
impl Drop for TypeWithDestructor {
49+
fn drop(&mut self) {
50+
println!("Dropped. Held {}.", self.0);
51+
}
52+
}
53+
54+
const ZERO_WITH_DESTRUCTOR: TypeWithDestructor = TypeWithDestructor(0);
55+
56+
fn create_and_drop_zero_with_destructor() {
57+
let x = ZERO_WITH_DESTRUCTOR;
58+
// x gets dropped at end of function, calling drop.
59+
// prints "Dropped. Held 0.".
60+
}
61+
```
62+
4263
[constant value]: expressions.html#constant-expressions
4364
[static lifetime elision]: items/static-items.html#static-lifetime-elision
4465
[`Drop`]: the-drop-trait.html

src/items/static-items.md

+20-16
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,23 @@
55
> &nbsp;&nbsp; `static` `mut`<sup>?</sup> [IDENTIFIER] `:` [_Type_]
66
> `=` [_Expression_] `;`
77
8-
A *static item* is similar to a *constant*, except that it represents a precise
8+
A *static item* is similar to a [constant], except that it represents a precise
99
memory location in the program. A static is never "inlined" at the usage site,
1010
and all references to it refer to the same memory location. Static items have
1111
the `static` lifetime, which outlives all other lifetimes in a Rust program.
12-
Static items may be placed in read-only memory if they do not contain any
13-
interior mutability.
12+
Static items may be placed in read-only memory if the type is not [interior
13+
mutable]. Static items do not call `drop` at the end of the program.
1414

15-
Statics may contain interior mutability through the `UnsafeCell` language item.
1615
All access to a static is safe, but there are a number of restrictions on
1716
statics:
1817

19-
* Statics may not contain any destructors.
20-
* The types of static values must ascribe to `Sync` to allow thread-safe
21-
access.
18+
* The type must have the `Sync` trait bound to allow thread-safe access.
2219
* Statics allow using paths to statics in the
2320
[constant-expression](expressions.html#constant-expressions) used to
24-
initialize them, but statics may not refer to other statics by value, only by
25-
reference.
21+
initialize them, but statics may not refer to other statics by value, only
22+
through a reference.
2623
* Constants cannot refer to statics.
2724

28-
Constants should in general be preferred over statics, unless large amounts of
29-
data are being stored, or single-address and mutability properties are
30-
required.
31-
3225
## Mutable statics
3326

3427
If a static item is declared with the `mut` keyword, then it is allowed to be
@@ -64,7 +57,7 @@ unsafe fn bump_levels_unsafe2() -> u32 {
6457
```
6558

6659
Mutable statics have the same restrictions as normal statics, except that the
67-
type of the value is not required to ascribe to `Sync`.
60+
type does not have to implement the `Sync` trait.
6861

6962
## `'static` lifetime elision
7063

@@ -97,8 +90,6 @@ the standard elision rules ([see discussion in the nomicon][elision-nomicon]).
9790
If it is unable to resolve the lifetimes by its usual rules, it will default to
9891
using the `'static` lifetime. By way of example:
9992

100-
[elision-nomicon]: ../nomicon/lifetime-elision.html
101-
10293
```rust,ignore
10394
// Resolved as `fn<'a>(&'a str) -> &'a str`.
10495
const RESOLVED_SINGLE: fn(&str) -> &str = ..
@@ -112,6 +103,19 @@ const RESOLVED_MULTIPLE: Fn(&Foo, &Bar, &Baz) -> usize = ..
112103
const RESOLVED_STATIC: Fn(&Foo, &Bar) -> &Baz = ..
113104
```
114105

106+
## Using Statics or Consts
107+
108+
In can be confusing whether or not you should use a constant item or a static
109+
item. Constants should, in general, be preferred over statics unless one of the
110+
following are true:
111+
112+
* Large amounts of data are being stored
113+
* The single-address or non-inlining property of statics is required.
114+
* Interior mutability is required.
115+
116+
[constant]: items/constant-items.html
117+
[interior mutable]: interior_mutability.html
115118
[IDENTIFIER]: identifiers.html
116119
[_Type_]: types.html
117120
[_Expression_]: expressions.html
121+
[elision-nomicon]: ../nomicon/lifetime-elision.html

0 commit comments

Comments
 (0)