Skip to content

Commit df68146

Browse files
committed
---
yaml --- r: 274221 b: refs/heads/stable c: 289020b h: refs/heads/master i: 274219: 1a6ba22
1 parent 4fda1cb commit df68146

File tree

2 files changed

+51
-37
lines changed

2 files changed

+51
-37
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: e06d2ad9fcd5027bcaac5b08fc9aa39a49d0ecd3
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: c0221c8897db309a79990367476177b1230bb264
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: c0984e42bd598ea119b128b4a52066dae7cb64d3
32+
refs/heads/stable: 289020b21c95a4c8f8578e51cdea79a2182515e6
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/librustc_passes/diagnostics.rs

Lines changed: 50 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -150,26 +150,36 @@ If you really want global mutable state, try using `static mut` or a global
150150
"##,
151151

152152
E0018: r##"
153-
The value of static and const variables must be known at compile time. You
154-
can't cast a pointer as an integer because we can't know what value the
155-
address will take.
156153
157-
However, pointers to other constants' addresses are allowed in constants,
158-
example:
154+
The value of static and constant integers must be known at compile time. You
155+
can't cast a pointer to an integer because the address of a pointer can
156+
vary.
159157
158+
For example, if you write:
160159
```
161-
const X: u32 = 50;
162-
const Y: *const u32 = &X;
160+
static MY_STATIC: u32 = 42;
161+
static MY_STATIC_ADDR: usize = &MY_STATIC as *const _ as usize;
162+
static WHAT: usize = (MY_STATIC_ADDR^17) + MY_STATIC_ADDR;
163163
```
164164
165-
Therefore, casting one of these non-constant pointers to an integer results
166-
in a non-constant integer which lead to this error. Example:
165+
Then `MY_STATIC_ADDR` would contain the address of `MY_STATIC`. However,
166+
the address can change when the program is linked, as well as change
167+
between different executions due to ASLR, and many linkers would
168+
not be able to calculate the value of `WHAT`.
169+
170+
On the other hand, static and constant pointers can point either to
171+
a known numeric address or to the address of a symbol.
167172
168173
```
169-
const X: u32 = 1;
170-
const Y: usize = &X as *const u32 as usize;
171-
println!("{}", Y);
174+
static MY_STATIC_ADDR: &'static u32 = &MY_STATIC;
175+
// ... and also
176+
static MY_STATIC_ADDR2: *const u32 = &MY_STATIC;
177+
178+
const CONST_ADDR: *const u8 = 0x5f3759df as *const u8;
172179
```
180+
181+
This does not pose a problem by itself because they can't be
182+
accessed directly.
173183
"##,
174184

175185
E0019: r##"
@@ -347,55 +357,59 @@ From [RFC 246]:
347357
[RFC 246]: https://github.com/rust-lang/rfcs/pull/246
348358
"##,
349359

360+
350361
E0395: r##"
351-
The value assigned to a constant expression must be known at compile time,
352-
which is not the case when comparing raw pointers. Erroneous code example:
362+
The value assigned to a constant scalar must be known at compile time,
363+
which is not the case when comparing raw pointers.
353364
365+
366+
Erroneous code example:
354367
```
355-
static foo: i32 = 42;
356-
static bar: i32 = 43;
368+
static FOO: i32 = 42;
369+
static BAR: i32 = 42;
357370
358-
static baz: bool = { (&foo as *const i32) == (&bar as *const i32) };
371+
static BAZ: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
359372
// error: raw pointers cannot be compared in statics!
360373
```
361374
362-
Please check that the result of the comparison can be determined at compile time
363-
or isn't assigned to a constant expression. Example:
375+
The address assigned by the linker to `FOO` and `BAR` may or may not
376+
be identical, so the value of `BAZ` can't be determined.
377+
378+
If you want to do the comparison, please do it at run-time.
379+
380+
For example:
364381
365382
```
366-
static foo: i32 = 42;
367-
static bar: i32 = 43;
383+
static FOO: i32 = 42;
384+
static BAR: i32 = 42;
368385
369-
let baz: bool = { (&foo as *const i32) == (&bar as *const i32) };
386+
let baz: bool = { (&FOO as *const i32) == (&BAR as *const i32) };
370387
// baz isn't a constant expression so it's ok
371388
```
372389
"##,
373390

374391
E0396: r##"
375-
The value assigned to a constant expression must be known at compile time,
376-
which is not the case when dereferencing raw pointers. Erroneous code
377-
example:
392+
The value behind a raw pointer can't be determined at compile-time
393+
(or even link-time), which means it can't be used in a constant
394+
expression.
378395
396+
For example:
379397
```
380-
const foo: i32 = 42;
381-
const baz: *const i32 = (&foo as *const i32);
398+
const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
382399
383-
const deref: i32 = *baz;
400+
const VALUE: u8 = unsafe { *REG_ADDR };
384401
// error: raw pointers cannot be dereferenced in constants
385402
```
386403
387-
To fix this error, please do not assign this value to a constant expression.
388-
Example:
404+
A possible fix is to dereference your pointer at some point in run-time.
389405
390-
```
391-
const foo: i32 = 42;
392-
const baz: *const i32 = (&foo as *const i32);
406+
For example:
393407
394-
unsafe { let deref: i32 = *baz; }
395-
// baz isn't a constant expression so it's ok
396408
```
409+
const REG_ADDR: *const u8 = 0x5f3759df as *const u8;
397410
398-
You'll also note that this assignment must be done in an unsafe block!
411+
let reg_value = unsafe { *REG_ADDR };
412+
```
399413
"##,
400414

401415
E0397: r##"

0 commit comments

Comments
 (0)