Use rustversion to detect available Rust version - #165
Conversation
8573
commented
Jul 9, 2022
This change was tested in my fork: https://github.com/8573/tinyvec/actions/runs/2640914561 |
`tinyvec` currently uses crate features `rustc_1_40`, `rustc_1_55`, and `rustc_1_57` to enable functions and optimizations that require Rust versions higher than the library's base MSRV of 1.34.0. This patch replaces the uses of these crate features with dtolnay's macro `rustversion`, which automatically detects the version of `rustc` with which the code is being compiled, thus allowing the optimizations enabled by newer Rust versions to be applied regardless of whether a dependent requests any of the `rustc_*` crate features. This may be especially useful for dependents whose own MSRVs would bar them from using those crate features without gating them behind crate features of their own, potentially requiring a proliferation of such crate features through a dependency tree. I would have limited this patch to using `rustversion` to enable optimizations automatically and not to replace the use of the crate features to gate functions that require Rust versions newer than 1.34.0, because I thought that using `rustversion` rather than the crate features to gate such functions might have been undesirable because it would mean losing the "Available on crate feature xyz only" hints on Docs.rs, but I see that Docs.rs doesn't apply those hints to functions anyway, so no such hints are lost by switching the gating mechanism to `rustversion`. This patch further uses `rustversion` to add compilation errors in case one of the `rustc_*` crate features is requested and the available Rust version is too old, such that the `rustc_*` crate features now function simply as static assertions that the running `rustc` supports the indicated Rust version. This patch, of course, adds a dependency on `rustversion`, which becomes this library's only non-optional dependency. Its MSRV is 1.31.0 and so does not raise the MSRV of this library. If having a non-optional dependency is unacceptable, an alternative could be to have `rustversion` be an optional, on-by-default dependency and to rely on the `rustc_*` crate features as before if `rustversion` is disabled. Rather than #[rustversion::since(1.57)] the conditional compilation clauses would look like #[cfg(any(feature = "rustversion", feature = "rustc_1_57"))] #[cfg_attr(feature = "rustversion", rustversion::since(1.57))] which is verbose enough that I suspect that rejecting `rustversion` altogether would be preferred. I admit that I do not understand why the comment in `Cargo.toml` on the crate feature `rustc_1_40` seems to say that "us[ing] Vec::append if possible in TinyVec::append" and overriding `DoubleEndedIterator::nth_back` require Rust 1.37 and Rust 1.40 respectively, when the standard library documentation says that `Vec::append` and `DoubleEndedIterator::nth_back` were stabilized in Rust 1.4.0 and Rust 1.37.0 respectively.
73f2787 to
45a8d4fCompareShnatsel
commented
Jul 9, 2022
I believe this would tie I understand it also ties the crate to rustc, making it difficult to build with alternative implementations such as gcc-rust or mrustc. I am not strictly opposed to this change, but I wanted to note this to make sure we understand the trade-offs. |
8573
commented
Jul 9, 2022
I hadn't thought of that. It looks like
How much of a concern is a build system not supporting build scripts, given the necessity(?) of supporting Autotools? |
Lokathor
commented
Jul 9, 2022
I don't think a non-optional dependency is a good fit for this crate. Though separately it is interesting that a few things have the wrong minimum version. I think what probably happened is that a 1.40 change added several things, only one of which truly required 1.40, and they just got bundled up together. |
8573
commented
Jul 9, 2022
I was advised by @dkm |
8573
commented
Jul 11, 2022
I'll close the ticket on the assumption that having it as an optional dependency is also not desired (e.g., the extra verbosity is seen as not worth the benefit). |
tinyveccurrently uses crate featuresrustc_1_40,rustc_1_55, andrustc_1_57to enable functions and optimizations that require Rust versions higher than the library's base MSRV of 1.34.0.This patch replaces the uses of these crate features with dtolnay's macro
rustversion, which automatically detects the version ofrustcwith which the code is being compiled, thus allowing the optimizations enabled by newer Rust versions to be applied regardless of whether a dependent requests any of therustc_*crate features. This may be especially useful for dependents whose own MSRVs would bar them from using those crate features without gating them behind crate features of their own, potentially requiring a proliferation of such crate features through a dependency tree.I would have limited this patch to using
rustversionto enable optimizations automatically and not to replace the use of the crate features to gate functions that require Rust versions newer than 1.34.0, because I thought that usingrustversionrather than the crate features to gate such functions might have been undesirable because it would mean losing the "Available on crate feature xyz only" hints on Docs.rs, but I see that Docs.rs doesn't apply those hints to functions anyway, so no such hints are lost by switching the gating mechanism torustversion.This patch further uses
rustversionto add compilation errors in case one of therustc_*crate features is requested and the available Rust version is too old, such that therustc_*crate features now function simply as static assertions that the runningrustcsupports the indicated Rust version.This patch, of course, adds a dependency on
rustversion, which becomes this library's only non-optional dependency. Its MSRV is 1.31.0 and so does not raise the MSRV of this library. If having a non-optional dependency is unacceptable, an alternative could be to haverustversionbe an optional, on-by-default dependency and to rely on therustc_*crate features as before ifrustversionis disabled. Rather thanthe conditional compilation clauses would look like
which is verbose enough that I suspect that rejecting
rustversionaltogether would be preferred.I admit that I do not understand why the comment in
Cargo.tomlon the crate featurerustc_1_40seems to say that "us[ing] Vec::append if possible in TinyVec::append" and overridingDoubleEndedIterator::nth_backrequire Rust 1.37 and Rust 1.40 respectively, when the standard library documentation says thatVec::appendandDoubleEndedIterator::nth_backwere stabilized in Rust 1.4.0 and Rust 1.37.0 respectively.