2

I can not get the following piece of code to work:

extern crate gtk

use gtk::prelude::*
use gtk::Window;
use gtk::WindowType;
// ...

static mut appWindow: Option<Window> = None;

fn main() {
    // ...
    appWindow = Some(Window::new(WindowType::Toplevel))
    // ...
}

The compiler produces the error:

error: mutable statics are not allowed to have destructors [E0397]
static mut appWindow: Option<Window> = None;

Surrounding everything with unsafe { ... } doesn't help.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
CodenameLambda
  • 1,486
  • 11
  • 23
  • 2
    `Optional` is not a type provided by the standard library. Where does it come from? Is it provided by the GTK crate? Please produce a [MCVE] when asking a question on Stack Overflow. You may also be interested in [How do I create a global, mutable singleton?](http://stackoverflow.com/questions/27791532/how-do-i-create-a-global-mutable-singleton). You should also note that Rust style is `snake_case`, not `camelCase` (should be `app_window`). – Shepmaster Jun 08 '16 at 17:42
  • @Shepmaster It is from `std::option::Option`, as far as I am concerned. But it seems that I don't need to explicitly import it, for some reason. And explicitly importing it changes nothing. – CodenameLambda Jun 08 '16 at 17:46
  • See [this link](http://rustbyexample.com/std/option.html). This is where I got that `Optional<...>`-part from. – CodenameLambda Jun 08 '16 at 17:48
  • 2
    `Optional` is very different from `Option`. It's not extremely useful to ask for help on code that has invalid syntax, thus why a [MCVE] is highly recommended. For example, I'd bet that `Optional` [sic] is a red-herring here. – Shepmaster Jun 08 '16 at 17:51

1 Answers1

3

Here's code that reproduces the same error that you've shown:

struct Foo;

impl Drop for Foo {
    fn drop(&mut self) {}
}

static mut f: Foo = Foo;

fn main() {}

Produces the errors:

error: mutable statics are not allowed to have destructors [E0397]
static mut f: Foo = Foo;
                    ^~~

error: statics are not allowed to have destructors [E0493]
static mut f: Foo = Foo;
                    ^~~

As the message says, Rust disallows having any kind of static item with destructors. A proposed change to the language discusses the origin of this:

This was historically motivated by the question of when to run the destructor:

  • There where worries about supporting life before/after main() for, eg, static variables due to them having historically caused trouble in, eg, C++ code bases.
  • Leaking the destructor was also for the most time not known to be a feasible option due to leaking possibly being bad.

RFC 1440 has been accepted to allow these types. As of Rust 1.9, there is an unstable feature that allows them: #![feature(drop_types_in_const)].

As the RFC says:

Destructors do not run on static items (by design), so this can lead to unexpected behavior when a type's destructor has effects outside the program (e.g. a RAII temporary folder handle, which deletes the folder on drop). However, this can already happen using the lazy_static crate.

Which leads to an alternate solution before the feature is stabilized: you can create a non-mutable static variable with lazy_static, which can then be wrapped in a thread-safe mutability wrapper. The type may contain a destructor:

How do I create a global, mutable singleton?

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Thank you for the explanation, it is actually pretty interesting. But: Is there a way to use `Optional` or something different too have the possibility to use a `None`-like value? Or do I need to trick around with a `struct` that contains the `Optional`? (Without using unstable features) – CodenameLambda Jun 08 '16 at 18:14
  • @CodingLambdas there *still* isn't an `Optional` type. When placed in an `Option`, `Option` then has has a destructor that might need to be called, which isn't allowed in stable Rust as of 1.9. – Shepmaster Jun 08 '16 at 18:19
  • Ok, I created a struct that contains the window. It still doesn't work (same error). And I didn't implement `Drop`. – CodenameLambda Jun 08 '16 at 18:23
  • Sry, I am used to writing `Optional`. As I already stated, I am new to Rust, coming from Python, and the snippet in the question was wrong because I didn't copy it. (Although I think I will never leave python... But it isn't compilable.) – CodenameLambda Jun 08 '16 at 18:24
  • @CodingLambdas *And I didn't implement `Drop`* — if your type contains a type that implements `Drop`, you can't "trick" the compiler into not calling it. `Drop` will be called unless you specifically go out of your way to forget the value (which wouldn't help for statics anyway). – Shepmaster Jun 08 '16 at 18:28
  • Ok... So the conclusion is: I cannot use global variables for that without using unstable features. Thanks! – CodenameLambda Jun 08 '16 at 18:30
  • 1
    @CodingLambdas did you read the link that has been posted twice that describes how to create global variables in stable Rust? Not that global variables are a *good* thing and I can **almost guarantee** you don't need it, but it's factually incorrect to say *I cannot use global variables for that without using unstable features* – Shepmaster Jun 08 '16 at 18:35