lazy-static.rs icon indicating copy to clipboard operation
lazy-static.rs copied to clipboard

lazy_static! fails to compile when a static ref is cfg'd out

Open LunarLambda opened this issue 5 years ago • 7 comments

rustc: 1.40.0 lazy_static: 1.4.0

I am calling a thread-unsafe unix libc function. So, I have a Mutex in my code to mitigate this issue. Linux provides a thread-safe version, so it's not needed on there.

So, I have the following code:

lazy_static! {
    #[cfg(all(unix, not(target_os = "linux")))]
    static ref MY_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(());
}

This configuration predicate works fine on functions, types, and even normal statics, but when used inside lazy_static!, I instead get a rather unhelpful "expected type, found static MY_MUTEX" error.

LunarLambda avatar Jan 01 '20 23:01 LunarLambda

That error does not have anything to do with the attribute. The type of MY_MUTEX is not Mutex<()>, but rather a new type (named MY_MUTEX) that derefs to Mutex<()>. You may need to do e.g. &*MY_MUTEX to get a &Mutex<()>.

sfackler avatar Jan 02 '20 00:01 sfackler

I am confused. What type should I put there then? Besides, it compiles if I remove the attribute, or change it to be simpler (for example, #[cfg(unix)] works...)

On Thu, 2 Jan 2020, 01:02 Steven Fackler, [email protected] wrote:

That error does not have anything to do with the attribute. The type of MY_MUTEX is not Mutex<()>, but rather a new type (named MY_MUTEX) that derefs to Mutex<()>. You may need to do e.g. &*MY_MUTEX to get a &Mutex<()>.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rust-lang-nursery/lazy-static.rs/issues/165?email_source=notifications&email_token=AJI55IRHEMR4WY7CEMGLEZLQ3UVHZA5CNFSM4KB5JVH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEH5PHTI#issuecomment-570094541, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJI55IUV6T3NPTINLAS3JTLQ3UVHZANCNFSM4KB5JVHQ .

LunarLambda avatar Jan 02 '20 12:01 LunarLambda

What code specifically compiles or does not compile?

sfackler avatar Jan 02 '20 12:01 sfackler

The snippet shown in the issue. My code is not the problem, as I could reproduce it in a completely empty crate as well.

It gives me the error on the macro invocation itself, not on subsequent use of the Mutex.

On Thu, 2 Jan 2020, 13:21 Steven Fackler, [email protected] wrote:

What specifically compiles or does not compile?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rust-lang-nursery/lazy-static.rs/issues/165?email_source=notifications&email_token=AJI55IXHUONIUUAH2DNLP7TQ3XL6LA5CNFSM4KB5JVH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEH6HGUA#issuecomment-570192720, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJI55IWSGEA33KSWZKOECTDQ3XL6LANCNFSM4KB5JVHQ .

LunarLambda avatar Jan 02 '20 12:01 LunarLambda

Oh, sorry, I thought that error was coming from the usage site.

It doesn't appear to be due to the complexity of the cfg, just if the cfg evaluates to true or false. You can move the cfg to the macro call itself as a workaround:

#[cfg(all(unix, not(target_os = "linux")))]
lazy_static! {
    static ref MY_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(());
}

sfackler avatar Jan 02 '20 12:01 sfackler

Ah. I was slightly mislead by the documentation saying doc comments and attributes are supported, but the only example showed doc comments being placed on the static item, not the macro invocation.

Thank you!

On Thu, 2 Jan 2020, 13:32 Steven Fackler, [email protected] wrote:

Oh, sorry, I thought that error was coming from the usage site.

It doesn't appear to be due to the complexity of the cfg, just if the cfg evaluates to true or false. You can move the cfg to the macro call itself as a workaround:

#[cfg(all(unix, not(target_os = "linux")))]lazy_static! { static ref MY_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(()); }

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rust-lang-nursery/lazy-static.rs/issues/165?email_source=notifications&email_token=AJI55ISTJRA62PR5HO6DZLDQ3XNHHA5CNFSM4KB5JVH2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEH6HXVY#issuecomment-570194903, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJI55IWBV6UHFY76SKQNXNLQ3XNHHANCNFSM4KB5JVHQ .

LunarLambda avatar Jan 02 '20 12:01 LunarLambda

Since lazy_static evaluates to multiple items, and not all of those items accept all attributes, we'd potentially break callers if we fixed this by duplicating the attributes on the impl blocks. If we could replace the macro internals with something like https://github.com/rust-lang/rfcs/pull/2788 so that the macro expanded to a single item then it might be possible, but that would probably also break uses.

KodrAus avatar Jan 13 '20 06:01 KodrAus