-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rustc: Add const
globals to the language
#17853
Conversation
I'll note that this is very much a break-the-world change due to the new restrictions being placed on statics. I don't really know a great way to provide a smooth path forward in all respects, so I didn't put forth any effort in this patch for a deprecation path. I'll also note that this implements a clarified version of the RFC which may be surprising at first. The PR description/commit messages should have the info though. I'm always open to suggestions for more tests, I tried to write a test for everything I could think of along the way, but I surely missed something here or there! |
OK, this looks great overall, just a few nits. r=me with changes, awesome! |
Remove a bunch of two-space tabs
f40593a
to
3db4f45
Compare
This change is an implementation of [RFC 69][rfc] which adds a third kind of global to the language, `const`. This global is most similar to what the old `static` was, and if you're unsure about what to use then you should use a `const`. The semantics of these three kinds of globals are: * A `const` does not represent a memory location, but only a value. Constants are translated as rvalues, which means that their values are directly inlined at usage location (similar to a #define in C/C++). Constant values are, well, constant, and can not be modified. Any "modification" is actually a modification to a local value on the stack rather than the actual constant itself. Almost all values are allowed inside constants, whether they have interior mutability or not. There are a few minor restrictions listed in the RFC, but they should in general not come up too often. * A `static` now always represents a memory location (unconditionally). Any references to the same `static` are actually a reference to the same memory location. Only values whose types ascribe to `Sync` are allowed in a `static`. This restriction is in place because many threads may access a `static` concurrently. Lifting this restriction (and allowing unsafe access) is a future extension not implemented at this time. * A `static mut` continues to always represent a memory location. All references to a `static mut` continue to be `unsafe`. This is a large breaking change, and many programs will need to be updated accordingly. A summary of the breaking changes is: * Statics may no longer be used in patterns. Statics now always represent a memory location, which can sometimes be modified. To fix code, repurpose the matched-on-`static` to a `const`. static FOO: uint = 4; match n { FOO => { /* ... */ } _ => { /* ... */ } } change this code to: const FOO: uint = 4; match n { FOO => { /* ... */ } _ => { /* ... */ } } * Statics may no longer refer to other statics by value. Due to statics being able to change at runtime, allowing them to reference one another could possibly lead to confusing semantics. If you are in this situation, use a constant initializer instead. Note, however, that statics may reference other statics by address, however. * Statics may no longer be used in constant expressions, such as array lengths. This is due to the same restrictions as listed above. Use a `const` instead. [breaking-change] [rfc]: rust-lang/rfcs#246
The tables in libunicode are far too large to want to be inlined into any other program, so these tables are all going to remain `static`. For them to be legal, they cannot reference one another by value, but instead use references now. This commit also modifies the src/etc/unicode.py script to generate the right tables.
This crate is largely just one giant header file, so there's no need for any of these values to actually have a memory location, they're all just basically a regular #define.
This leaves the ziggurat tables as `pub static` as they're likely too large to want to go into the metadata anyway.
This commit repurposes most statics as constants in the standard library itself, with the exception of TLS keys which precisely have their own memory location as an implementation detail. This commit also rewrites the bitflags syntax to use `const` instead of `static`. All invocations will need to replace the word `static` with `const` when declaring flags. Due to the modification of the `bitflags!` syntax, this is a: [breaking-change]
This require a bit of finesse to work around the changes with libunicode, but nothing too major!
At the same time, migrate statics to constants.
Instead of returning &'static [u8], an invocation of `bytes!()` now returns `&'static [u8, ..N]` where `N` is the length of the byte vector. This should functionally be the same, but there are some cases where an explicit cast may be needed, so this is a: [breaking-change]
Additionally, add lots of tests for new functionality around statics and `static mut`.
3db4f45
to
a3e8f41
Compare
f4a26f3
to
fdffaa7
Compare
👯 |
fdffaa7
to
0b51711
Compare
This change is an implementation of [RFC 69][rfc] which adds a third kind of global to the language, `const`. This global is most similar to what the old `static` was, and if you're unsure about what to use then you should use a `const`. The semantics of these three kinds of globals are: * A `const` does not represent a memory location, but only a value. Constants are translated as rvalues, which means that their values are directly inlined at usage location (similar to a #define in C/C++). Constant values are, well, constant, and can not be modified. Any "modification" is actually a modification to a local value on the stack rather than the actual constant itself. Almost all values are allowed inside constants, whether they have interior mutability or not. There are a few minor restrictions listed in the RFC, but they should in general not come up too often. * A `static` now always represents a memory location (unconditionally). Any references to the same `static` are actually a reference to the same memory location. Only values whose types ascribe to `Sync` are allowed in a `static`. This restriction is in place because many threads may access a `static` concurrently. Lifting this restriction (and allowing unsafe access) is a future extension not implemented at this time. * A `static mut` continues to always represent a memory location. All references to a `static mut` continue to be `unsafe`. This is a large breaking change, and many programs will need to be updated accordingly. A summary of the breaking changes is: * Statics may no longer be used in patterns. Statics now always represent a memory location, which can sometimes be modified. To fix code, repurpose the matched-on-`static` to a `const`. static FOO: uint = 4; match n { FOO => { /* ... */ } _ => { /* ... */ } } change this code to: const FOO: uint = 4; match n { FOO => { /* ... */ } _ => { /* ... */ } } * Statics may no longer refer to other statics by value. Due to statics being able to change at runtime, allowing them to reference one another could possibly lead to confusing semantics. If you are in this situation, use a constant initializer instead. Note, however, that statics may reference other statics by address, however. * Statics may no longer be used in constant expressions, such as array lengths. This is due to the same restrictions as listed above. Use a `const` instead. [breaking-change] Closes #17718 [rfc]: rust-lang/rfcs#246
…oyuVanilla feat: `min-exhaustive-patterns` Resolves rust-lang#17851
This change is an implementation of RFC 69 which adds a third kind of
global to the language,
const
. This global is most similar to what the oldstatic
was, and if you're unsure about what to use then you should use aconst
.The semantics of these three kinds of globals are:
A
const
does not represent a memory location, but only a value. Constantsare translated as rvalues, which means that their values are directly inlined
at usage location (similar to a #define in C/C++). Constant values are, well,
constant, and can not be modified. Any "modification" is actually a
modification to a local value on the stack rather than the actual constant
itself.
Almost all values are allowed inside constants, whether they have interior
mutability or not. There are a few minor restrictions listed in the RFC, but
they should in general not come up too often.
A
static
now always represents a memory location (unconditionally). Anyreferences to the same
static
are actually a reference to the same memorylocation. Only values whose types ascribe to
Sync
are allowed in astatic
.This restriction is in place because many threads may access a
static
concurrently. Lifting this restriction (and allowing unsafe access) is a
future extension not implemented at this time.
A
static mut
continues to always represent a memory location. All referencesto a
static mut
continue to beunsafe
.This is a large breaking change, and many programs will need to be updated
accordingly. A summary of the breaking changes is:
Statics may no longer be used in patterns. Statics now always represent a
memory location, which can sometimes be modified. To fix code, repurpose the
matched-on-
static
to aconst
.change this code to:
Statics may no longer refer to other statics by value. Due to statics being
able to change at runtime, allowing them to reference one another could
possibly lead to confusing semantics. If you are in this situation, use a
constant initializer instead. Note, however, that statics may reference other
statics by address, however.
Statics may no longer be used in constant expressions, such as array lengths.
This is due to the same restrictions as listed above. Use a
const
instead.[breaking-change]
Closes #17718