Skip to content

Commit 57be540

Browse files
committed
Merge pull request #5 from alexcrichton/const-vs-static
Clarify taking addresses of globals in globals
2 parents 7e7fab1 + 9782d4a commit 57be540

File tree

1 file changed

+35
-5
lines changed

1 file changed

+35
-5
lines changed

active/0000-const-vs-static.md

+35-5
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ times. There are number of interrelated issues:
4040
can write `static MY_COUNTER: AtomicUint = INIT_ZERO` or some
4141
such. It should not be possible to modify these initializer
4242
constants.
43-
43+
4444
The current design is that we have only one keyword, `static`, which
4545
declares a global variable. By default, global variables do not have a
4646
significant address and can be inlined into the program. You can make
@@ -98,10 +98,10 @@ have generic parameters. For example, the following constant is legal:
9898

9999
struct WrappedOption<T> { value: Option<T> }
100100
const NONE<T> = WrappedOption { value: None }
101-
101+
102102
Note that this makes no sense for a `static` variable, which represents
103103
a memory location and hence must have a concrete type.
104-
104+
105105
### Possible extension: constant functions
106106

107107
It is possible to imagine constant functions as well. This could help
@@ -111,7 +111,7 @@ we can limit them syntactically to a single constant expression that
111111
can be expanded at compilation time (no recursion).
112112

113113
struct LockedData<T:Send> { lock: Lock, value: T }
114-
114+
115115
const LOCKED<T:Send>(t: T) -> LockedData<T> {
116116
LockedData { lock: INIT_LOCK, value: t }
117117
}
@@ -135,7 +135,37 @@ an `UnsafeCell` in its interior, the compiler may place it in
135135
read-only memory, but otherwise it must be placed in mutable memory.
136136

137137
`mut` statics may have any type. All access is considered unsafe.
138-
They may not be placed in read-only memory and their values may
138+
They may not be placed in read-only memory.
139+
140+
## Globals referencing Globals
141+
142+
It is possible to create a `const` or a `static` which references another
143+
`const` or another `static` by its address. For example:
144+
145+
struct SomeStruct { x: uint }
146+
const FOO: SomeStruct = SomeStruct { x: 1 };
147+
const BAR: &'static SomeStruct = &FOO;
148+
149+
Constants are generally inlined into the stack frame from which they are
150+
referenced, but in a static context there is no stack frame. Instead, the
151+
compiler will reinterpret this as if it were written as:
152+
153+
struct SomeStruct { x: uint }
154+
const FOO: SomeStruct = SomeStruct { x: 1 };
155+
const BAR: &'static SomeStruct = {
156+
static TMP: SomeStruct = FOO;
157+
&TMP
158+
};
159+
160+
Here a `static` is introduced to be able to give the `const` a pointer which
161+
does indeed have the `'static` lifetime. Due to this rewriting, the compiler
162+
will disallow `SomeStruct` from containing an `UnsafeCell` (interior
163+
mutability). In general a constant A cannot reference the address of another
164+
constant B if B contains an `UnsafeCell` in its interior.
165+
166+
If a `static` references the address of a `const`, then a similar rewriting
167+
happens, but there is no interior mutability restriction (only a `Sync`
168+
restriction).
139169

140170
# Drawbacks
141171

0 commit comments

Comments
 (0)