Skip to content

Tracking issue for RFC 2523, #[cfg(version(..))] #64796

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

Open
6 of 10 tasks
Centril opened this issue Sep 26, 2019 · 119 comments
Open
6 of 10 tasks

Tracking issue for RFC 2523, #[cfg(version(..))] #64796

Centril opened this issue Sep 26, 2019 · 119 comments
Labels
B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC F-cfg_version `#![feature(cfg_version)]` I-lang-radar Items that are on lang's radar and will need eventual work or consideration. T-lang Relevant to the language team

Comments

@Centril
Copy link
Contributor

Centril commented Sep 26, 2019

This is a tracking issue for #[cfg(version(..))] (rust-lang/rfcs#2523).

Steps:

Unresolved questions:

@Centril Centril added B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. T-lang Relevant to the language team C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC labels Sep 26, 2019
@Centril Centril added the F-cfg_version `#![feature(cfg_version)]` label Sep 26, 2019
csmoe added a commit to csmoe/rust that referenced this issue Sep 29, 2019
@pickfire
Copy link
Contributor

@csmoe Are you working on this? If not I might want to try out this task first since @petrochenkov mentioned that this task is easier than cfg(accessible = ::path).

@csmoe
Copy link
Member

csmoe commented Nov 16, 2019

@pickfire I didn't have much bandwidth on this, seems you have already made some progress on cfg(accessible = ::path), so feel free to check this :)
(Don't forget to assign yourself with @rustbot claim)

@pickfire
Copy link
Contributor

@csmoe Nice, thanks a lot for telling me that. I did not know such thing exist.

@rustbot claim

@rustbot rustbot self-assigned this Nov 16, 2019
@pickfire
Copy link
Contributor

Can anyone please help to write up the mentoring instructions. Based on what I know, this should be similar to #64797 (comment)

1. Syntax:
   
   1. Add a new `sym::accessible` in https://doc.rust-lang.org/nightly/nightly-rustc/src/syntax_pos/symbol.rs.html#22.
   2. Feature gate `accessible` in [`GATED_CFGS`](https://doc.rust-lang.org/nightly/nightly-rustc/syntax/feature_gate/builtin_attrs/constant.GATED_CFGS.html). Also add `cfg_accessible` to `active.rs`: https://doc.rust-lang.org/nightly/nightly-rustc/src/syntax/feature_gate/active.rs.html#530. This will also require a new `sym::cfg_accessible`.
   3. Introduce a match arm for `sym::accessible` in [`cfg_matches`](https://doc.rust-lang.org/nightly/nightly-rustc/syntax/attr/fn.cfg_matches.html). This should look mostly like [the case for `sym::not`](https://doc.rust-lang.org/nightly/nightly-rustc/src/syntax/attr/builtin.rs.html#591).
      Here you need to extract an [`&ast::Path`](https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/struct.Path.html) and delegate the interpretation to a function of the rough shape `fn is_accessible(sess: &ParseSess, path: &Path) -> bool { ... }`

2. Implement `fn is_accessible`.
   
   1. First do some validation. We want to emit errors if [`!path.is_global()`](https://doc.rust-lang.org/nightly/nightly-rustc/syntax/ast/struct.Path.html#method.is_global). Use [`sess.span_diagnostic.struct_span_err`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Handler.html#method.struct_span_err).

I believed step 1 and 2 should be the same. For step 3, based on what I know requires me to modify somewhere around

MetaItemKind::List(..) => {
error(cfg.span, "unexpected parentheses after `cfg` predicate key")
}
.

Based on fn is_accessible, the next thing to be done should be to implement fn min_version and then somehow reference version_check on how to do the min_version logic by checking the CFG_VERSION environment variable?

@mibac138
Copy link
Contributor

Hi, @pickfire. Are you still working on this?

@pickfire
Copy link
Contributor

No, I was stuck working on this and don't know how to proceed.

@mibac138
Copy link
Contributor

Ok, thanks for quick response. I'll take my shot at this.
@rustbot claim

@rustbot rustbot assigned rustbot and unassigned rustbot Apr 18, 2020
@pickfire
Copy link
Contributor

@mibac138 Do you want me to publish my progress?

@mibac138
Copy link
Contributor

@pickfire sure, that'd be great!

@pickfire
Copy link
Contributor

pickfire commented Apr 20, 2020

@mibac138 Err, no need. You have already done more than me, I don't know how to change the eval_condition. Oh, it didn't seemed that hard after looking at your PR but I didn't know how to work on that.

@petrochenkov
Copy link
Contributor

Status update: #71314 implemented this RFC with a slightly different syntax - #[cfg(version("1.2.3"))] instead of #[cfg(version(1.2.3))].

The reason is that 1.2.3 doesn't fit into some existing attribute-parsing infrastructure in the compiler (MetaItems), so it requires separate work.

Additionally, the version_check crate currently used to parse versions wants a string as an input, so we need to stringify 1.2.3 before passing it, which we can only do imprecisely (up to whitespaces).
So we can turn 1 . 2 .3 into e.g. "1.2.3" during stringification and it may be a problem depending on what exactly we are supposed to accept as a valid version.

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 3, 2020
Implement RFC 2523, `#[cfg(version(..))]`

Hi! This is my first contribution to rust, I hope I didn't miss anything. I tried to implement this feature so that `#[cfg(version(1.44.0))]` works but the parser was printing an error that I wasn't sure how to fix so I just opted for implementing `#[cfg(version("1.44.0"))]` (note the quotes).

Tracking issue: rust-lang#64796
@roblabla
Copy link
Contributor

roblabla commented May 6, 2020

The RFC had an unresolved question about how this feature would interact with nightly/beta. Should #[cfg(version("1.45.0"))] return true or false for nightly/beta 1.45.0?

Currently, the implementation returns true. E.G. for rustc 1.45.0-nightly, the following code prints Yes:

#![feature(cfg_version)]
fn main() {
    test();
}

#[cfg(version("1.45.0"))]
fn test() {
    println!("Yes")
}

#[cfg(not(version("1.45.0")))]
fn test() {
    println!("No")
}

IMO, this is a mistake. The main use-case for cfg(version), at least for me, is to allow use of new features that are known to be stable at a given version. For instance, in the core-error crate, I was planning to use cfg(version) to implement my custom core::error::Error trait on the various error structures of libcore/liballoc automatically, based on cfg(version). Unfortunately, this is not possible as it will certainly cause breakage in the in-between nightly versions that are reported as implementing a version, whilst not having all the types associated with it.

@nikomatsakis
Copy link
Contributor

That sounds like good reasoning to me, but I've not been following this RFC that closely. @joshtriplett -- I feel like you were "liaison'ing" for this before we had a term for it, do you have a take?

@nikomatsakis
Copy link
Contributor

Nominating for lang-team meeting to discuss

@dekellum
Copy link

dekellum commented May 6, 2020

Currently, the implementation returns true

Which is most useful, the way it is, AFAICT.

Isn't there a way to combine this with cfg test(s) for "train", e.g. beta or nightly and unstable feature gates?

@Nemo157
Copy link
Member

Nemo157 commented May 6, 2020

Isn't there a way to combine this with cfg test(s) for "train", e.g. beta or nightly and unstable feature gates?

Code written for the stable compiler should not have to know about beta or nightly.

@dekellum
Copy link

dekellum commented May 6, 2020

I'm not surprised with that as a goal, but I can think of cases where for practical reasons I nead to dev on 1.45 nightly with expectation that it will then work on 1.45 stable. I'm surprised if I'm the only one.

@joshtriplett
Copy link
Member

joshtriplett commented May 14, 2025

I've been the primary person who has expressed that we need cfg(accessible(...)) before we stabilize cfg(version(...)), based on experience with the C ecosystem (e.g. compiler-version-based feature detection vs LLVM's much better __has_feature and __has_include and similar macros) and the browser ecosystem (feature detection vs version detection).

I'm withdrawing that objection, and I think we should go ahead and ship cfg(version(...)) as soon as it's ready to stabilize and we confirm that it behaves the way we expect.

I still believe it's incredibly important that we have accessible, and more things like it as well (e.g. named language features), in both rustc and cargo. But accessible has made good progress, and I trust that it'll still get finished and shipped even if version exists. And even once we have accessible, there will be more things we need as well to avoid version detection, and we shouldn't block version detection on all of them. Sometimes the easiest approach really is "this works in version 1.xy".

And on the flip side, the sooner we do ship version, the sooner the ecosystem can start using it, because only crates whose MSRVs are new enough to have stable cfg(version) support will be able to eliminate build scripts and similar.

cc @epage @rust-lang/lang

@traviscross
Copy link
Contributor

@rustbot labels -S-blocked +I-lang-radar

Given the above, if you are someone who is able and interested in putting together a stabilization PR with a stabilization report for cfg(version(..)), I'd encourage you to do that, and I'd estimate that it will receive a warm reception.

(Have a look at our new draft stabilization report template.)

@nvzqz
Copy link
Contributor

nvzqz commented May 14, 2025

@joshtriplett I appreciate the insight from your change in perspective. In particular:

the browser ecosystem (feature detection vs version detection)

This comparison to browsers puts into perspective for me that Rust using version detection in lieu of feature detection is actually fine, since Rust features are tied to versions unlike browser features which vary wildly across vendors.

Also, compile times have been a longstanding pain point of Rust adoption. So reducing the need for build scripts would be another big step along with the great effort that's been made in this area.

@rustbot rustbot added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. and removed S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels May 14, 2025
@epage
Copy link
Contributor

epage commented May 16, 2025

With this unblocked, I realized it would be good to stabilize the rustc and cargo sides at the same time. I've created rust-lang/cargo#15531 to track the Cargo side of this.

@est31
Copy link
Member

est31 commented May 16, 2025

I think a stabilization on the rust side should be pretty straightforward. The one big remaining issue I see is testing. There is only one test right now added by #71314, and it only checks the parsing, not the actual functionality. I suppose we can extend cfg(version) to read the env var added in #124339 and make a test based on that.

I will file a PR in the coming days. Also needs a stabilization report, but that one should be easy.

@est31
Copy link
Member

est31 commented May 17, 2025

Stabilization PR filed: #141137

I'd like the lang team to decide on whether stabilization should sync up with cargo, or it is better to have support for #[cfg(version)] in the language as early as possible.

There is also a limitation in the clippy lint incompatible_msrv, which should probably be addressed before stabilization: rust-lang/rust-clippy#14827

@Lokathor
Copy link
Contributor

I'm unclear on a point: What would be the effect of having it in rustc but not in cargo? Would it be usable on rustc somehow without the cargo support?

@est31
Copy link
Member

est31 commented May 17, 2025

@Lokathor the cargo side is tracked in rust-lang/cargo#15531. It's about supporting it in Cargo.toml, i.e.:

[target.'cfg(not(version(1.70.0))`.dependencies]
is-terminal = "0.4.2"

The rust side of course will work without cargo.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue May 23, 2025
Make #[cfg(version)] respect RUSTC_OVERRIDE_VERSION_STRING

The `#[cfg(version(...))]` feature is currently under-tested. Part of it is the difficulty that it is hard to write a test that never changes, while the version of the Rust compiler indeed *does* change.

PR rust-lang#81468 added the first and so far only test of `#[cfg(version(...))]`'s functionality (there is one other test for the *syntax*, that also acts as feature gate). But that test uses a proc macro that parses the version: the text of the test doesn't contain the actual `#[cfg(version(...))]`.

This PR makes `#[cfg(version(...))]` respect `RUSTC_OVERRIDE_VERSION_STRING`, added by PR rust-lang#124339, allowing us to virtually pin the rustc version and write tests from all directions against some specific version.

The PR also adds a functional test of `#[cfg(version(...))]` that leverages `RUSTC_OVERRIDE_VERSION_STRING`.

Pulled out of rust-lang#141137.

Tracking issue: rust-lang#64796
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue May 24, 2025
Make #[cfg(version)] respect RUSTC_OVERRIDE_VERSION_STRING

The `#[cfg(version(...))]` feature is currently under-tested. Part of it is the difficulty that it is hard to write a test that never changes, while the version of the Rust compiler indeed *does* change.

PR rust-lang#81468 added the first and so far only test of `#[cfg(version(...))]`'s functionality (there is one other test for the *syntax*, that also acts as feature gate). But that test uses a proc macro that parses the version: the text of the test doesn't contain the actual `#[cfg(version(...))]`.

This PR makes `#[cfg(version(...))]` respect `RUSTC_OVERRIDE_VERSION_STRING`, added by PR rust-lang#124339, allowing us to virtually pin the rustc version and write tests from all directions against some specific version.

The PR also adds a functional test of `#[cfg(version(...))]` that leverages `RUSTC_OVERRIDE_VERSION_STRING`.

Pulled out of rust-lang#141137.

Tracking issue: rust-lang#64796
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this issue May 25, 2025
Make #[cfg(version)] respect RUSTC_OVERRIDE_VERSION_STRING

The `#[cfg(version(...))]` feature is currently under-tested. Part of it is the difficulty that it is hard to write a test that never changes, while the version of the Rust compiler indeed *does* change.

PR rust-lang#81468 added the first and so far only test of `#[cfg(version(...))]`'s functionality (there is one other test for the *syntax*, that also acts as feature gate). But that test uses a proc macro that parses the version: the text of the test doesn't contain the actual `#[cfg(version(...))]`.

This PR makes `#[cfg(version(...))]` respect `RUSTC_OVERRIDE_VERSION_STRING`, added by PR rust-lang#124339, allowing us to virtually pin the rustc version and write tests from all directions against some specific version.

The PR also adds a functional test of `#[cfg(version(...))]` that leverages `RUSTC_OVERRIDE_VERSION_STRING`.

Pulled out of rust-lang#141137.

Tracking issue: rust-lang#64796
rust-timer added a commit that referenced this issue May 25, 2025
Rollup merge of #141413 - est31:cfg_version_env_var, r=jieyouxu

Make #[cfg(version)] respect RUSTC_OVERRIDE_VERSION_STRING

The `#[cfg(version(...))]` feature is currently under-tested. Part of it is the difficulty that it is hard to write a test that never changes, while the version of the Rust compiler indeed *does* change.

PR #81468 added the first and so far only test of `#[cfg(version(...))]`'s functionality (there is one other test for the *syntax*, that also acts as feature gate). But that test uses a proc macro that parses the version: the text of the test doesn't contain the actual `#[cfg(version(...))]`.

This PR makes `#[cfg(version(...))]` respect `RUSTC_OVERRIDE_VERSION_STRING`, added by PR #124339, allowing us to virtually pin the rustc version and write tests from all directions against some specific version.

The PR also adds a functional test of `#[cfg(version(...))]` that leverages `RUSTC_OVERRIDE_VERSION_STRING`.

Pulled out of #141137.

Tracking issue: #64796
jieyouxu added a commit to jieyouxu/rust that referenced this issue May 26, 2025
Pull out dedicated `cfg_version` syntax test from feature gate test

Tracking issue: rust-lang#64796.
Closes rust-lang#141452, as a follow-up to rust-lang#141413 (comment) (point 3 of that is probably too pedantic).

The feature gate test was dual-purposing causing feature gate errors to distract from syntax exercises.

`@rustbot` label +F-cfg_version
r? `@est31`
compiler-errors added a commit to compiler-errors/rust that referenced this issue May 27, 2025
Pull out dedicated `cfg_version` syntax test from feature gate test

Tracking issue: rust-lang#64796.
Closes rust-lang#141452, as a follow-up to rust-lang#141413 (comment) (point 3 of that is probably too pedantic).

The feature gate test was dual-purposing causing feature gate errors to distract from syntax exercises.

``@rustbot`` label +F-cfg_version
r? ``@est31``
rust-timer added a commit that referenced this issue May 27, 2025
Rollup merge of #141552 - jieyouxu:cfg-version-tests, r=est31

Pull out dedicated `cfg_version` syntax test from feature gate test

Tracking issue: #64796.
Closes #141452, as a follow-up to #141413 (comment) (point 3 of that is probably too pedantic).

The feature gate test was dual-purposing causing feature gate errors to distract from syntax exercises.

``@rustbot`` label +F-cfg_version
r? ``@est31``
@est31
Copy link
Member

est31 commented May 30, 2025

Next try for a stabilization PR: #141766

Now explicitly without cfg_has_version, and the other non-stabilization changes of #141137 put into separate (now merged) PRs #141552 and #141413.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-RFC-approved Blocker: Approved by a merged RFC but not yet implemented. C-tracking-issue Category: An issue tracking the progress of sth. like the implementation of an RFC F-cfg_version `#![feature(cfg_version)]` I-lang-radar Items that are on lang's radar and will need eventual work or consideration. T-lang Relevant to the language team
Projects
None yet
Development

No branches or pull requests