-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Automatically use the allocation-free API for Rust 1.27.0+. #103
Conversation
Looks like nightly builds are failing right now for what I can only assume is an unrelated reason. The 1.21.0 and stable tests are passing on travis. |
Thanks @anp! I'll dig into this later today. Yeh it looks like the latest |
Thanks @anp! I think we could simplify the What do you think? |
@KodrAus I like that idea a lot. Want to take a look at this approach (assuming CI passes after I write this)? |
I'm not able to reproduce this compiletest failure locally, but it seems like it's probably tripping up on an error message whose format has changed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased and squashed, thanks for the fast turnaround on CI repair! |
@KodrAus looks like we're all green. |
Actually, can we hold off on merging for a bit? Specifically I want to ask about a soundness issue before this becomes part of the de facto 1.0 API for the crate, but it's late here. |
The reasons to hold are both simplification (#102 (comment)) and soundness (#105). |
1.27.0 stabilized hint::unreachable, allowing the previously nightly-only API to be used on stable. The version detection can still be overridden using `cfg`s (or their related environment variables through cargo), and both the nightly and spin_no_std features are preserved for compatibility.
This is to patch an obscure soundness hole. With the fields public, it is possible to for a consumer crate to access and call the std::sync::Once without assigning the correct value to the pointer in the tuple's first field, making it possible to later deref a null pointer from safe code. However now that lazy_static targets 1.21.0+, we can use an associated constant in the __lazy_static_create macro instead of requiring consumers to literally construct the inner values post-expansion. This is technically a breaking change, but given that any existing use of these inner fields is very likely to cause unsoundness I think it's consistent with Rust's semver policy to make this change and stay at 1.0.
Alright, thanks for being patient with me here. Unfortunately it's not possible to achieve all of the cleanup @eddyb suggested, as the inline impl requires Drop in statics, which wasn't stable until 1.22.0. If bumping the minimum compiler version of lazy_static to 1.22 is on the table, then we could go from 3 implementations to 2. Since I'm guessing it's not on the table (for good reasons), I've pushed some new commits to try to maximize outcomes for all consumers:
|
Looks like the AppVeyor build failed due to network timeout -- is there an easy way to restart those? |
Thanks @anp! This looks good to me with a quick scan on mobile. The rejigging of features looks like a good change 👍 I'll dig through again shortly. Unfortunately there isn't an easy way to retry AppVeyor builds short of updating your branch. Their account model is a bit clumsier for organization ownership so a lot of projects end up tied to individual users. |
…le_unchecked. Also editing the commit message to force a CI run. Woo!
OK, I edited a commit message and re-pushed. CI is re-running. |
CI passed this time. I think this is good to go, pending review of the extra complexity I've added to the build matrix. |
src/inline_lazy.rs
Outdated
} | ||
|
||
#[cfg(lazy_static_core_unreachable_unchecked)] | ||
use core::hint::unreachable_unchecked; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to bother with core::hint::unreachable_unchecked
at all with our polyfill?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, we can wait until the minimum version is raised for some other reason, to switch to the std
version.
src/inline_lazy.rs
Outdated
/// Polyfill for core::hint::unreachable_unchecked. Included to support Rust prior to 1.27. See | ||
/// [issue #102](https://github.com/rust-lang-nursery/lazy-static.rs/issues/102#issuecomment-400959779) | ||
/// for details. | ||
unsafe fn unreachable_unchecked() -> ! { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to do this yourself, turns out, https://docs.rs/unreachable exists.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I think it's reasonable in this case for lazy_static
to include this very simple function to avoid bringing in 2 additional dependencies.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah that's fine, if the rationalization is added to the comment.
Thanks for the feedback, addressed both of these. |
@KodrAus ping |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your patience @anp! This looks good to me. We'll do a crater run to sniff out any breakage from the visibility changes.
Looks like the crater run came back clean! |
Merged 🎉 We might have a build fail on |
Introduces a buildscript to help decide which implementation to use by default. If using a version of Rust >= 1.27.0, what I've renamed the "inline" implementation will be automatically selected. On older versions of Rust, what I'm calling the "heap" implementation (previously the default one) will be selected. Originally I had removed the nightly feature entirely, but then I decided to keep it to preserve semver-major compatibility (let me know if you think this is taking compatibility too far -- it'd be nice to clean the feature up).
Another decision I made was to re-use the
rustc_version
crate for parsing version numbers rather than rolling our own as @BurntSushi did for regex. This does add build-time dependencies although no extra crates will be added to consumers' binaries. I think it improves clarity slightly and reduces overall churn. Happy to discuss if there's disagreement though.Test plan: tests pass locally with 1.21.0, 1.27.0, and nightly-2018-06-20. Also will see what CI says.
Closes #102.