0

I'm trying to define static non-mutable data, to use them in AVR's flash memory (hence static), but I'm stuck on this case (this is a resume).

trait MenuOption {
    fn get_title(&self) -> String;
}

struct Op<'a> {
    title: &'a str,
}

impl MenuOption for Op<'static> {
    fn get_title(&self) -> String {
        self.title.to_string()
    }
}

struct Menu<'a> {
    options: &'a [&'a MenuOption],
}

static MAIN_MENU: Menu = Menu {
    options: &[&Op { title: "Op1" }],
};

fn main() {}

This code gives me this error:

error[E0277]: the trait bound `MenuOption + 'static: std::marker::Sync` is not satisfied in `Menu<'static>`
  --> src/main.rs:19:1
   |
19 | / static MAIN_MENU: Menu = Menu {
20 | |     options: &[&Op { title: "Op1" }],
21 | | };
   | |__^ `MenuOption + 'static` cannot be shared between threads safely
   |
   = help: within `Menu<'static>`, the trait `std::marker::Sync` is not implemented for `MenuOption + 'static`
   = note: required because it appears within the type `&'static MenuOption + 'static`
   = note: required because it appears within the type `[&'static MenuOption + 'static]`
   = note: required because it appears within the type `&'static [&'static MenuOption + 'static]`
   = note: required because it appears within the type `Menu<'static>`
   = note: shared static variables must have a type that implements `Sync`

I can solve this either by declaring MAIN_MENU as const instead of static, or by defining Menu::options as &'a [&'a Op<'a>]

Using the struct Op I want to use the constraint MenuOption.

At this point I'm a bit confused. Whats the problem of sharing non-mutable data? This is probably not related to the data being non-mutable but related to using the constraint.

Can this be done without making MAIN_MENU a const? Is it OK to use const? I know this won't have a fixed allocation but instead the compiler will inject the data as needed.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
neu-rah
  • 1,662
  • 19
  • 32
  • Please feel free to come hang out with us in the [avr-rust gitter channel](https://gitter.im/avr-rust/Lobby). – Shepmaster Sep 25 '17 at 17:11
  • The duplicates answer [applied to your question](https://play.rust-lang.org/?gist=5b0ae312cb0f19fc0bcd40a3d7de37b1&version=stable). – Shepmaster Sep 25 '17 at 17:18
  • 1
    Your type `Menu` does not guarantee that the *trait object* `&MenuOption` implements `Sync`, so there's no guarantee that an arbitrary `Menu` can be stored in static storage. – Shepmaster Sep 25 '17 at 17:55

0 Answers0