rust-lang-nursery / lazy-static.rs

A small macro for defining lazy evaluated static variables in Rust.
Apache License 2.0
1.91k stars 111 forks source link

Use lazy_static for declaring global channels #93

Closed siscia closed 6 years ago

siscia commented 6 years ago

Hi all,

I was trying to get a pair of global channels.

Unfortunately, it seems impossible to use lazy_static for this. I believe the problem is just that declaring a channel means to use the following syntax:

static ref (rx, tx): (Receiver<_>, Sender<_>) = channel();

That return a compile error:

error: no rules expected the token `(`
  │  --> src/lib.rs:33:16
  │   |
  │33 |     static ref (A, B): Sender<_>, Receiver<_> = channel();
  │   |                ^
  │
  │error: aborting due to previous error

The problem I believe is simply the first parenthesis.

Is this something that we are interested in fixing or we prefer to use alternative syntax and keep lazy_static fairly simple?

Thanks,

Simone

siscia commented 6 years ago

For anybody else having the same problem with channels here is a possible solution: https://users.rust-lang.org/t/global-sync-mpsc-channel-is-possible/14476

Kimundi commented 6 years ago

lazy statics use the same syntax as normal statics - that is, you can not destructure a pattern in them.

What you can do is just storing a tuple variable:

static ref my_channel: (Receiver<T>, Sender<T>) = channel();

I had not planned to extend this unless the regular Rust syntax also gets extended. :)

raphtlw commented 3 years ago

I tried doing what @Kimundi mentioned above, but the code simply failed to compile.

[1] error[E0412]: cannot find type `T` in this scope
[1]   --> src/main.rs:33:52
[1]    |
[1] 33 |         static ref server_channel: (mpsc::Receiver<T>, mpsc::Sender<T>) = mpsc::channel();
[1]    |                                                    ^ not found in this scope
[1] 
[1] error[E0412]: cannot find type `T` in this scope
[1]   --> src/main.rs:33:69
[1]    |
[1] 33 |         static ref server_channel: (mpsc::Receiver<T>, mpsc::Sender<T>) = mpsc::channel();
[1]    |                                                                     ^ not found in this scope
[1] 
[1] warning: unused import: `dev::Server`
[1]   --> src/main.rs:10:5
[1]    |
[1] 10 |     dev::Server, get, middleware, rt, web, App, Error, HttpRequest, HttpResponse, HttpServer,
[1]    |     ^^^^^^^^^^^
[1]    |
[1]    = note: `#[warn(unused_imports)]` on by default
[1] 
[1] error[E0277]: `std::cell::UnsafeCell<isize>` cannot be shared between threads safely
[1]   --> src/main.rs:32:5
[1]    |
[1] 32 | /     lazy_static! {
[1] 33 | |         static ref server_channel: (mpsc::Receiver<T>, mpsc::Sender<T>) = mpsc::channel();
[1] 34 | |     }
[1]    | |_____^ `std::cell::UnsafeCell<isize>` cannot be shared between threads safely
[1]    | 
[1]   ::: /home/raphael/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/inline_lazy.rs:19:20
[1]    |
[1] 19 |   pub struct Lazy<T: Sync>(Cell<Option<T>>, Once);
[1]    |                      ---- required by this bound in `lazy_static::lazy::Lazy`
[1]    |
[1]    = help: within `(std::sync::mpsc::Receiver<[type error]>, std::sync::mpsc::Sender<[type error]>)`, the trait `std::marker::Sync` is not implemented for `std::cell::UnsafeCell<isize>`
[1]    = note: required because it appears within the type `std::sync::mpsc::shared::Packet<[type error]>`
[1]    = note: required because it appears within the type `alloc::sync::ArcInner<std::sync::mpsc::shared::Packet<[type error]>>`
[1]    = note: required because it appears within the type `std::marker::PhantomData<alloc::sync::ArcInner<std::sync::mpsc::shared::Packet<[type error]>>>`
[1]    = note: required because it appears within the type `std::sync::Arc<std::sync::mpsc::shared::Packet<[type error]>>`
[1]    = note: required because it appears within the type `std::sync::mpsc::Flavor<[type error]>`
[1]    = note: required because it appears within the type `std::cell::UnsafeCell<std::sync::mpsc::Flavor<[type error]>>`
[1]    = note: required because it appears within the type `std::sync::mpsc::Receiver<[type error]>`
[1]    = note: required because it appears within the type `(std::sync::mpsc::Receiver<[type error]>, std::sync::mpsc::Sender<[type error]>)`
[1]    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
[1] 
[1] error[E0277]: `*mut std::sync::mpsc::sync::Node` cannot be shared between threads safely
[1]   --> src/main.rs:32:5
[1]    |
[1] 32 | /     lazy_static! {
[1] 33 | |         static ref server_channel: (mpsc::Receiver<T>, mpsc::Sender<T>) = mpsc::channel();
[1] 34 | |     }
[1]    | |_____^ `*mut std::sync::mpsc::sync::Node` cannot be shared between threads safely
[1]    | 
[1]   ::: /home/raphael/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-1.4.0/src/inline_lazy.rs:19:20
[1]    |
[1] 19 |   pub struct Lazy<T: Sync>(Cell<Option<T>>, Once);
[1]    |                      ---- required by this bound in `lazy_static::lazy::Lazy`
[1]    |
[1]    = help: within `(std::sync::mpsc::Receiver<[type error]>, std::sync::mpsc::Sender<[type error]>)`, the trait `std::marker::Sync` is not implemented for `*mut std::sync::mpsc::sync::Node`
[1]    = note: required because it appears within the type `std::sync::mpsc::sync::Queue`
[1]    = note: required because it appears within the type `std::sync::mpsc::sync::State<[type error]>`
[1]    = note: required because it appears within the type `std::cell::UnsafeCell<std::sync::mpsc::sync::State<[type error]>>`
[1]    = note: required because it appears within the type `std::sync::Mutex<std::sync::mpsc::sync::State<[type error]>>`
[1]    = note: required because it appears within the type `std::sync::mpsc::sync::Packet<[type error]>`
[1]    = note: required because it appears within the type `alloc::sync::ArcInner<std::sync::mpsc::sync::Packet<[type error]>>`
[1]    = note: required because it appears within the type `std::marker::PhantomData<alloc::sync::ArcInner<std::sync::mpsc::sync::Packet<[type error]>>>`
[1]    = note: required because it appears within the type `std::sync::Arc<std::sync::mpsc::sync::Packet<[type error]>>`
[1]    = note: required because it appears within the type `std::sync::mpsc::Flavor<[type error]>`
[1]    = note: required because it appears within the type `std::cell::UnsafeCell<std::sync::mpsc::Flavor<[type error]>>`
[1]    = note: required because it appears within the type `std::sync::mpsc::Receiver<[type error]>`
[1]    = note: required because it appears within the type `(std::sync::mpsc::Receiver<[type error]>, std::sync::mpsc::Sender<[type error]>)`
[1]    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
[1] 
[1] error: aborting due to 4 previous errors; 1 warning emitted
Kleptine commented 2 years ago

@raphtlw You need to specify a concrete type for T. The T in the example is just for reference.