-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: #[cfg(accessible(..) / version(..))] #2523
Conversation
cc @MajorBreakfast re. use case for futures. :) |
On September 13, 2019 11:28:54 AM PDT, David Kellum ***@***.***> wrote:
(a) Might changing the name from `version`, to something like
`min_rustc_version(1.38)` clarify that its both a `>=` bounds and only
relevant to rustc versions (not any other compiler)?
I think rather than encoding `min` in the name, I'd like to treat it like a Cargo semver bound, where 1.38 means ^1.38, and we then have the option to introduce more syntax in the future.
|
Two points here:
The breaking ways may not affect everyone using a specific feature. As such, it may create needless churn on nightly and additionally discourage folks from using nightly. Speaking as a rustc developer myself, keeping track of this also doesn't sound like much fun to be honest. |
On keeping the
I'd personally favor using an explicit On my suggestion of versioning or sub-feature name suffixes:
I'm just suggesting that the current RFCs feature design, would allow such a scheme as a tool to manage the breakage and selectively allow future-proofing. If you don't want to use that tool, that is your prerogative. :) |
text/0000-cfg-path-version.md
Outdated
This flag requires that a `path` fragment be specified in it inside parenthesis | ||
but not inside a string literal. The `$path` must start with leading `::` | ||
and may not refer to any parts of the own crate (e.g. with `::crate::foo`, | ||
`::self::foo`, or `::super::foo` if such paths are legal). |
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.
Does this imply that #[cfg(accessible(path)]
can be used with dependencies other than core
or std
? For example, can I write #[cfg(accessible(::lazy_static::lazy_static)]
?
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.
Yes, you can do that.
We say that a release announcement of a new version of Rust includes a new version of the language version. Before this RFC, this is purely a rhetorical/theoretical/social device. Nothing can see the language version. It doesn't exist mechanically. This RFC changes that to something that is mechanical, and that should, IMO, be mentioned as a drawback, if only for academic purposes. Any industrial second implementation (Note: I don't expect there to ever be one) would have to understand the feature set of each six week release to properly set their version. It also semi-locks us into this release versioning scheme. I say semi-locks because we could at any time freeze the cfg(version(...)) version if we decide it's bad or retroactively tie it to rustc's version instead. |
text/0000-cfg-path-version.md
Outdated
`rustc` in the numbering and what features it provides. This is probably not | ||
too unreasonable as we can expect `rustc` to be the reference implementation | ||
and that other ones will probably lag behind. Indeed, this is the experience | ||
with `GHC` and alternative Haskell compilers. |
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.
A drawback of this approach is that using #[cfg(version(1.28))]
would make libsyntax fail to parse this syntax on all pre-existing toolchains.
That is, if you have to support toolchains older than whatever toolchain version this attribute is this shipped in, you need to put the #[cfg(version(...))]
behind a feature gated module like this to avoid older toolchains from trying to parse it:
// In the module where you actually want to use `#[cfg(version)]`
cfg_if! {
if #[cfg(toolchain_supports_cfg_version)] {
mod internal;
use internal::*;
}
}
// and then in a separate internal.rs file
#[cfg(version(1.42))]
struct Foo;
and then have a build.rs
that detects the rust toolchain version and sets --cfg toolchain_supports_cfg_version
.
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.
and then have a build.rs that detects the rust toolchain version and sets --cfg toolchain_supports_cfg_version.
I mean, at that point, we can just implement this as a library that can be easily used from build.rs
to define such config macros, which would allow the code above to just be written as:
// In the module where you actually want to use `#[cfg(version)]`
#[cfg(rust_ge_1_42_0)]
struct Foo;
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.
Note that the following syntax does not have this problem and is IIRC backward compatible down to Rust 1.0:
#[cfg(rust_version = "1.42.0")] // in the cargo sense
struct Foo;
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.
@gnzlbg I think everyone considering using this feature understands that it will only work going forward, in versions that support version
and accessible
. That's still quite useful.
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.
@joshtriplett when it comes to older versions, there's a difference between "doesn't work" and "can't be parsed". I'd like to avoid the second situation if possible.
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.
This does bring though the idea that whichever release version
becomes stable will probably become the new minimum stable rust version that a lot of libraries will bump to. It might be good to pair it's release with a major feature(s) so that the most amount of people can be benefit from them.
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.
It's probably not that difficult to support two versions; it's mostly just a bit of parsing inside or outside the string and they'll be uniform otherwise.
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.
@XAMPPRocky that's pretty clever =P will just have to find some major feature to couple with heh.
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.
This does bring though the idea that whichever release version becomes stable will probably become the new minimum stable rust version that a lot of libraries will bump to.
At best, depending on how cfg(version)
is shipped, projects might be able to just use it for detecting newer features, but it will live alongside the feature-detection code that these projects are already using. The "old" feature detection code is simple and low maintenance, so bumping the MSRV to be able to exclusively use cfg(version)
is something that doesn't add much value, while compromising something that's important for these project: the only reason a project would do feature detection is to be able to support older toolchains, so the project must see value in that.
I think that maybe eventually all projects might be able to just use cfg(version)
, but that will be a consequence of them bumping the MSRV due to other issues, and not because there is a lot of value in bumping the MSRV to a toolchain that supports cfg(version)
.
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.
At best, depending on how cfg(version) is shipped, projects might be able to just use it for detecting newer features
I don't think cfg(version)
has to be immediately valuable. Eventually more features will be covered under cfg(version)
than those features that aren't, and then it will be more compelling for more libraries.
so bumping the MSRV to be able to exclusively use cfg(version) is something that doesn't add much value
Unless your MSRV is one version behind cfg(version)
your value won't be exclusively cfg(version)
. If your MSRV is 1.15 for example and cfg(version)
was released in 1.40.0 you'd be getting everything from 1.16.0–1.40.0, and you'd be able to use cfg(version)
to ease future feature development.
Another point is that things that are gated sill need to use valid rust grammar. Let's assume that the version 1.42 adds support for throwing function, and using .if:
This won't compile in current rust, even after this rfc is implemented, because this is not valid grammar, and rustc still check the grammar of items even if they are going to be removed by attribute macro or cfg attribute. I suppose it would not make sense to relax the parsing rules of items that are disabled by #[cfg] So one must wrap the item inside a macro such as Btw, I've made a crate with a macro |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. The RFC will be merged soon. |
🎉 Huzzah! This RFC has been merged! 🎉 Tracking issues: |
🖼️ Rendered
⏭ Tracking issue (
#[cfg(version(..))]
⏭ Tracking issue (
#[cfg(accessible(..))]
📝 Summary
Permit users to
#[cfg(..)]
on whether:#[cfg(version(1.27))]
).#[cfg(accessible(::std::mem::ManuallyDrop))]
).💖 Thanks
To @eddyb, @rpjohnst, @kennytm, @aturon, and @rkruppe for discussing the feature with me.
To @Mark-Simulacrum, @MajorBreakfast, @alexreg, @alercah, and @joshtriplett for reviewing the draft version of this RFC.