- Start Date: 2014-08-08
- RFC PR: rust-lang/rfcs#246
- Rust Issue: rust-lang/rust#17718
Summary
Divide global declarations
- constants定数declare宣言するconstant定数values. These represent a value, not a memory address. This is the most common thing one would reach for and would replace
static
as we know it today in almost all cases.静的な - statics静的なdeclare宣言するglobal variables変数、ストレージ. These represent a memory address. They would be rarely used: the primary主要な、初等の、第一のuse cases are global locks, global atomic counters, and interfacing with legacy C libraries.
Motivation
We have been wrestling with the best way to represent globals for some times. There are a number of interrelated issues:
- Significant addresses and inlining: For optimization purposes, it is useful to be able to inline constant定数values directly直接into the program. It is even more useful if those constant定数values do not have known addresses, because that means the compiler is free to replicate them as it wishes. Moreover,その上if a constant定数is inlined into downstream crates, then they must be recompiled whenever that constant定数changes.
- Read-only memory: Whenever possible, we'd like to place large constants定数into read-only memory. But this means that the data must be truly immutable,不変のor else a segfault will result.結果、戻り値
- Global atomic counters and the like: We'd like to make it possible for people to create global locks or atomic counters that can be used without resorting to unsafe code.
- Interfacing with C code: Some C libraries require the use of global, mutable data. Other times it's just convenient and threading is not a concern.
- Initializer constants:定数There must be a way to have initializer constants定数for things like locks and atomic counters, so that people can write
static
or some such. It should not be possible to modify these initializer constants.静的なMY_COUNTER: AtomicUint = INIT_ZERO定数
The current designstatic
, which declares#[inline(never)]
. Furthermore, you can declarestatic
: all accesses to static
variablesstatic
values to be placed in read-only memory, they are forbidden from having a type that includes interior mutable data (that is, an appearance of UnsafeCell
type).
Some concrete
- There is no way to have a safe global counter or lock. Those must be placed in
static
variables,静的なmut変数、ストレージwhich means that access to them is illegal.文法違反To resolve解決するthis, there is an alternative代わりのもの、選択肢proposal, accordingaccording to 〜に応じてto which, access tostatic
is considered静的なmutみなす、考慮するsafe if the type of the static静的なmut meets theSync
trait. - The significance (no pun intended) of the
#[inline(never)]
annotation is not intuitive. - There is no way to have a generic type constant.定数
Other less practical and more aesthetic concerns are:
- Although
static
and静的なlet
look and feel analogous, the two behave quite differently. Generally speaking,static
declarations静的な宣言do not declare宣言するvariables変数、ストレージbut rather values, which can be inlined and which do not have fixed addresses. You cannot have interior mutability in astatic
variable,静的な変数、ストレージbut you can in alet
. So thatstatic
variables静的な変数、ストレージcan appear現れるin patterns, it is illegal文法違反to shadow astatic
variable静的な変数、ストレージ-- butlet
variables変数、ストレージcannot appear現れるin patterns. Etc. - There are other constructs作る、構成体in the language,言語such as nullary enum variants and nullary structs,構造、構造体which look like global data but in fact act振る舞うquite differently. They are actual実際のvalues which do not have addresses. They are categorized as rvalues and so forth.
Detailed design設計(する)
Constants定数
Reintroduce a const
declaration
const name: type = value;
Constants
Possible extension: Generic constants定数
As a possible extension, it is perfectly reasonable for constants
struct WrappedOption<T> { value: Option<T> }
const NONE<T> = WrappedOption { value: None }
Note that this makes no sense for a static
variable,
Possible extension: constant定数 functions
It is possible to imagine constant
struct LockedData<T:Send> { lock: Lock, value: T }
const LOCKED<T:Send>(t: T) -> LockedData<T> {
LockedData { lock: INIT_LOCK, value: t }
}
This would allowvalue
field on UnsafeCell
private, among other things.
Static静的な variables変数、ストレージ
Repurpose the static
declarationstatic
variablesmut
. The lifetime of a static
variable'static
. It is not legal
Non-mut
staticsSync
bound.UnsafeCell
in its interior, the compiler may place it in read-only memory, but otherwise it must be placed in mutable memory.
mut
statics
Globals referencing Globals
const => const
It is possible to create a const
or a static
which referencesconst
or another static
by its address. For example:
struct SomeStruct { x: uint }
const FOO: SomeStruct = SomeStruct { x: 1 };
const BAR: &'static SomeStruct = &FOO;
Constants
struct SomeStruct { x: uint }
const FOO: SomeStruct = SomeStruct { x: 1 };
const BAR: &'static SomeStruct = {
static TMP: SomeStruct = FOO;
&TMP
};
Here a static
is introduced to be able to give the const
a pointer which does indeed have the 'static
lifetime. Due to this rewriting, the compiler will disallowSomeStruct
from containingUnsafeCell
(interior mutability). In general,UnsafeCell
in its interior.
const => static静的な
It is illegal
static静的な => const
If a static
referencesconst
, then a similarSync
restriction).
static静的な => static静的な
It is illegalstatic
to referencestatic
by value. It is required that all references
If a by-value reference
- It's an initializer pattern. This is the purpose of
const
, however. - The values are kept in sync. This is currently technically infeasible.
Instead of falling into one of these two categories, the compiler will instead disallow
Patterns
Today, a static
is allowedconst
, however, a static
will be forbidden from appearingconst
can appear.
Drawbacks
This RFC introduces two keywords for global data. Global data is kind of an edge feature so this feels like overkill. (On the other hand, the only keyword that most Rust programmers should need to know is const
-- I imagine static
variables
Alternatives
The other designstatic
be consideredSync
. For the details of this discussion, please see RFC 177.
One serious concern is with regard to timing. Addingstatic
rules, or perhaps the variation where access to static
is safe, for the time being, and create const
declarations
Unresolved questions
-
Should the compiler be allowed
許可する、可能にするto inline the values ofstatic
variables静的な変数、ストレージwhich are deeply immutable不変の(and thusそれゆえに、従って、force recompilation)? -
Should we permit
許すstatic
variables静的な変数、ストレージwhose type is notSync
, but simply make access to them unsafe? -
Should we permit
許すstatic
variables静的な変数、ストレージwhose type is notSync
, but whose initializer value does not actually contain含むinterior mutability? For example, astatic
of静的なOption<UnsafeCell<uint>>
with the initializer ofNone
is in theory safe. -
How hard are the envisioned extensions to implement? If easy, they would be nice to have. If hard, they can wait.