Skip to content

Latest commit

 

History

History
37 lines (29 loc) · 1.74 KB

static.md

File metadata and controls

37 lines (29 loc) · 1.74 KB

Statics

Statics (static, static mut) are the simplest kind of compile-time evaluated data:

  • The user explicitly requested them to be evaluated at compile-time, so evaluation errors from computing the initial value of a static are no concern (in other words, const safety is mostly not an issue).
  • They observably get evaluated once, with the result being put at some address known at run-time, so there are no fundamental restrictions on what statics can do.
  • The compiler checks that statics are Sync, justifying sharing their address across threads.
  • Constants and promoteds are not allowed to read from statics, so their final value does not have have to be const-valid in any meaningful way. As of 2019-08, we do check them for validity anyway, to be conservative; and indeed constants could be allowed to read from frozen statics.

Drop

The compiler rejects intermediate values (created and discarded during the computation of a static initializer) that implement Drop. The reason for this is simply that the Drop implementation might be non-const fn (so really, this is just a special case of static initializers not being able to call non-const functions). This restriction can be lifted once const impl Drop for Type (or something similar) is supported.

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {
        println!("foo dropped");
    }
}

static FOOO: Foo = Foo; // Ok, drop is never run

// Not ok, cannot run `Foo::drop` because it's not a const fn
static BAR: i32 = (Foo, 42).1;

Dynamic check. The Miri engine dynamically checks that this is done correctly by not permitting calls of non-const functions.