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

Is the separate nightly version still needed after 1.27.0? #102

Closed anp closed 6 years ago

anp commented 6 years ago

A very slightly modified copy of nightly_lazy.rs compiles against 1.27 now that hint::unreachable_unchecked was stabilized. I don't actually know if the nightly version is in some way preferred or what nursery crates' compiler backcompat story is. I'm sure there are other things to consider there too.

Would a PR to make it the default be of interest?

BurntSushi commented 6 years ago

If this is going to be done, please do it with care so that we don't cause the entire ecosystem to bump their minimum Rust version. lazy-static is as core of a crate as it gets. We should be conservative.

KodrAus commented 6 years ago

One option could be to use a build script to determine whether we're compiling against 1.27+ to decide whether we use the lazy.rs or nightly_lazy.rs source instead of (or as well as) the nightly feature since the public API is the same.

BurntSushi commented 6 years ago

@KodrAus Yup! That's what I did with the regex crate to solve the same problem (but for SIMD).

KodrAus commented 6 years ago

@anp If you're interested, would you like to submit a PR that determines whether we're compiling on 1.27+ using a build.rs, similar to how regex does for simd, that enables a build feature like core_unreachable, and uses that core_unreachable feature to pull in nightly_lazy.rs instead of lazy.rs, rather than the current nightly feature? We might also want to rename nightly_lazy...

anp commented 6 years ago

Sounds great to me. I'll try to do this tonight, but if someone comes along in weeks/months/years and I've abdicated please feel free to pick up!

eddyb commented 6 years ago

You don't need language support for unreachable_unchecked if your goal is to tell the compiler that you expect an Option to be in the Some state. You can polyfill it with this:

unsafe fn unreachable_unchecked() -> ! {
    enum Void {}
    match ::std::mem::uninitialized::<Void>() {}
}

And you wouldn't even a version check, this polyfill works great (check LLVM IR/ASM), and I expect you won't need to use the one in core/std. You can just wait to remove the polyfill until you (if ever) bump the minimum needed version past 1.27.

EDIT: You can see that it works even on Rust 1.0: https://godbolt.org/g/sxroUe EDIT2: Of course someone has made a crate already: https://docs.rs/unreachable.