Rust: Tracking issue for RFC 2523, `#[cfg(version(..))]`

Created on 26 Sep 2019  路  53Comments  路  Source: rust-lang/rust

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

Steps:

Unresolved questions:

  • [x] What is cfg(version(...)) relative to in terms of nightly compilers?

    We could check against what rustc --version says, e.g. nightly being 1.40.0, beta being 1.39.0, and stable being 1.38.0. We could also have cfg(version(...)) at most be relative to the beta compiler. See the RFC for a longer discussion.

  • [ ] Should we also support version = "..." so that crates having a MSRV below when version(...) was stabilized can use the flag?

  • [ ] Dependency updates cause language changes (https://github.com/rust-lang/rust/issues/79010)


This issue has been assigned to @mibac138 via this comment.


B-RFC-approved C-tracking-issue F-cfg_version T-lang

Most helpful comment

We discussed the unresolved question (as explained in https://github.com/rust-lang/rust/issues/64796#issue-498617312) in today's lang team triage meeting.

We had general consensus on the following behavior:

Version | cfg(version("1.48")) | cfg(version("1.49")) | cfg(version("1.50"))
------------ | ------------- | ------------ | -------------
1.48 stable | true | false | false
1.49 beta | true | true | false
1.50 nightly | true | true | false

In other words, stable and beta compilers will both report being at least version V for any version up to and including their own version, while nightly compilers will report being at least version V for any version up to but not including their own version.

Some rationale:

  • Using features that only exist on nightly is likely to require the use of feature gates or other special cases.
  • Crates that have extra features on nightly commonly handle nightly via a separate feature flag.
  • Most crates don't have great support for nightlies older than the last stable, because they typically assume "nightly" means "latest bleeding-edge". This seems likely to at least somewhat improve that situation, while reporting the nightly version seems likely to make that worse (because crates would assume that cfg(version("1.50")) means "supports all the features of stable 1.50", which will break the nightlies leading up to 1.50).
  • The primary use case of this feature is for crates that want to support older compilers, not for crates supporting nightly (for which we don't have any good way of distinguishing between builds of nightly with the same version number).

All 53 comments

@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).

@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)

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

@rustbot claim

Can anyone please help to write up the mentoring instructions. Based on what I know, this should be similar to https://github.com/rust-lang/rust/issues/64797#issuecomment-540350338

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 https://github.com/rust-lang/rust/blob/b56b23988de532744fd05301f87c329b612700e3/src/libsyntax/attr/builtin.rs#L566-L568.

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?

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

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

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

@mibac138 Do you want me to publish my progress?

@pickfire sure, that'd be great!

@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.

Status update: https://github.com/rust-lang/rust/pull/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.

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.

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?

Nominating for lang-team meeting to discuss

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?

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.

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.

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

Not currently, and I don't think it'd be a good idea anyways. Rust 1.45.0-nightly can refer to many different nightlies with many different implemented features. The original RFC had an additional cfg(nightly) proposal for this reason, but it had to be dropped because it was controversial IIRC.

IMO to target nightly and beta, cfg_accessible is a better alternative when possible (e.g. for all the features that expose a type or function). Otherwise, the only way to write robust code that spans multiple nightlies would be to match on build dates.

I guess "robust code" is the important phrase in your comment, because in practice, the way it is currently implemented (what you documented above) works just fine (if not robustly) for 9 out of 10 cases where I've personally needed it.

Edit: And I should add I think it works "just fine" on the nightlies because of a somewhat non-robust assumption that future users download a nightly after whichever nightly I'm currently developing on. :)

First off, note that, while rarely, sometimes features are unstabilized before they get released, as problems are discovered. In this instance, downloading newer nightlies will break your compilation.

Matching on build dates isn't as robust as it seems. Custom builds of rustc master also have custom build dates that base on the commit date. If any custom patches are introduced, they affect the build date. So it's no robust piece of information to base checks on.

From what I could gather, pinning nightlies is a common thing to do in corporate environments, and some even do custom patches. In these scenarios, having 1.45-nightly count as 1.45 would be a problem, and build date based checks even more. Imagine you are adding a patch to fix a bug, only to get even more bugs because you increased the date to something very recent. One could argue that these environments likely already use nightly features so can expect breakage, but this would be breakage relating only stable features, and part of the Rust stability story is making the potential for breakage still opt-in even in nightly (that's what -Z options and #![feature] are for).

I'm not even sure whether 1.45-beta should count as 1.45, but I'm leaning towards yes, because there are two more reasons speaking in favour. First, beta has a smaller user base and it's less likely that someone is pinning betas instead of using stable. Second, beta is meant to be a staging environment and thus should help discover any bugs that newly stabilized features have. However, even here, every now and then (un-)stabilizations are being backported to beta so it can still be considered unfinished. But a) this is less common today than it used to be and b) due to people not pinning betas I don't consider this as too much of a problem.

Anyways, no matter the decision, it can always be changed in the future, in both directions. There is no compatibility hazard here unlike in many other stabilization scenarios.

TLDR: I'd advocate for never treating nightly as the release version, while treating beta and stable as it.

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?

I agree that nightly 1.45 shouldn't pass a cfg(version("1.45.0")) check. Beta should, though.

This kind of complication is a big part of why I'd like to see cfg(accessible(...)) used much more often, and cfg(version(...)) used only as a last resort.

This kind of complication is a big part of why I'd like to see cfg(accessible(...)) used much more often, and cfg(version(...)) used only as a last resort.

Yes, but cfg(accessible(...)) have some complications right now IIRC, such as not able to match all different kind of paths? Correct me if I am wrong.

I agree that nightly 1.45 shouldn't pass a cfg(version("1.45.0")) check. Beta should, though.

This is unproductive rehash/relitigation of same issues raised during RFC. Making attempts to optimize this for "maximum robustness" WRT to nightly, is likely to mean people will just keep using rustc --version in build.rs, and without any additional nightly considerations. That doesn't sound like it really matches your goals.

@dekellum Does cfg_accessible not work for your use-case? It'd help to know what you're using cfg(version) to gate your code for.

We discussed the unresolved question (as explained in https://github.com/rust-lang/rust/issues/64796#issue-498617312) in today's lang team triage meeting.

We had general consensus on the following behavior:

Version | cfg(version("1.48")) | cfg(version("1.49")) | cfg(version("1.50"))
------------ | ------------- | ------------ | -------------
1.48 stable | true | false | false
1.49 beta | true | true | false
1.50 nightly | true | true | false

In other words, stable and beta compilers will both report being at least version V for any version up to and including their own version, while nightly compilers will report being at least version V for any version up to but not including their own version.

Some rationale:

  • Using features that only exist on nightly is likely to require the use of feature gates or other special cases.
  • Crates that have extra features on nightly commonly handle nightly via a separate feature flag.
  • Most crates don't have great support for nightlies older than the last stable, because they typically assume "nightly" means "latest bleeding-edge". This seems likely to at least somewhat improve that situation, while reporting the nightly version seems likely to make that worse (because crates would assume that cfg(version("1.50")) means "supports all the features of stable 1.50", which will break the nightlies leading up to 1.50).
  • The primary use case of this feature is for crates that want to support older compilers, not for crates supporting nightly (for which we don't have any good way of distinguishing between builds of nightly with the same version number).

That's lame.

That's lame.

Please be constructive.

@joshtriplett How do we teach others this? This looks like weird condition that people might not expect. I think we should keep the version for nightly with it coming with a warning when people are checking current version on nightly. We could also do this but I think a warning is better than just false which may make people go looking why does it not work.

@pickfire I'd explain it this way: during a nightly cycle, the features that comprise the new release are being assembled on nightly. The release is considered unfinished. The #[cfg(version)] is based on the last finished release and ignores all unfinished releases. The story of nightly is: "we don't know yet what it's going to include". The story of beta is "we know what it will include and ask for QC and testing". The story of stable is "this is the tested and stable release of Rust for wide community use".

Yes, I understand that here after reading it in the above posts, but how does someone who did not read this comments understand our reasoning? Is there anyway to let other people using the command know? Preferably without reading any docs since they may read the wrong docs or misread some tiny details like this.

So from what I will say, rather than implicitly disable it, we explicitly warn about the use of version on nightly regardless we allow/disallow the use of version on nightly, so they don't even need to read the docs for this. Still, I prefer to have both warning while allowing the use of version on nightly.

Another piece of rationale that I found convincing was that declaring that "version" is testing the most recent beta version (and not the "nightly version") enables you to do something, but declaring that version is the nightly version doesn't give any new capabilities.

  • If we say that version is testing the "beta version", then you can build crates that successfully build with any version of the compiler (including random nightly builds that may have "evolved" the feature) (the only exception is when we rollback a stabilization). Given the fact that we often make small changes in the runup to stabilization (as the feature is getting attention), this seems important.

  • If you want to incorporate (but gate) support for features that are "not yet stabilized", you can still do that via cfg-accessible, custom cfg flags, or even custom cargo features.

@pickfire Warning on cfg(version) would introduce noise for code that's trying to use cfg(version) to decide if it should use a feature or not.

This feature seems to require that rustc's versioning scheme (along with the language features supported in each version) will be part of the Rust language forever, unless alternative implementations are supposed to use their own version number for this. I don't think the RFC is sufficiently clear on what's meant by this. The reference-level explanation in the RFC is especially light on details and I would really like to see it expanded before this is stabilized.

The RFC mentions that feature-based detection is not being pursued because it would stabilize the names of features, but if the implemented "language version" is instead used it would mean that the full set of features at every version (every 6 weeks!) would need to be stabilized (and, eventually, specified). This seems significantly less elegant (and also like more work) to me than just stabilizing feature names, and it would mean that alternative Rust implementation could only add new features in lock-step with rustc (since you couldn't claim to be version X as long as you're still missing one tiny feature from that version).

In case the intention is that an implementation would just return its implementation version, regardless of which features are available, and regardless of which versioning scheme is used, then this feature looks fairly similar to user-agent detection in browsers, except with the crucial missing ability to tell apart different implementations, making the feature useless for writing Rust code that is portable between implementations.

@jonas-schievink I'm hoping that cfg(accessible) satisfies much of the demand for feature detection, and I think we may potentially provide other feature detection in the future. cfg(version) is intended as a last resort for subtle things that don't correspond to a specific feature. People can already do the same detection via build scripts, so we're not giving access to a capability people didn't already have.

cfg(version) is defined in terms of versions of rustc; other similar features, such as MSRV, are also defined in terms of versions of rustc. An alternative implementation of rustc should only advertise cfg(version) for a given version if it's entirely compatible with the features of that rustc version; if not, crates expecting such a version will break on such an alternative implementation.

Rust the language and rustc the compiler have the same release cadence and release versions. They're still technically two different version numbers.

I think the answer is that this is testing the version of Rust the language, and that a new version of Rust the language is released every six weeks. That seems ok to me. That pace of evolution may slow down at some point, or it may not.

It's true that, as a result of this feature, if there is some alternative rust compiler out there (let's call it alt-rustc), it would have to know which version of "rust the language" it supports, so that it can emulate the correct set of available features. In other words, if it advertises itself as Rust 1.22, then it ought to support everything that Rust 1.22 supported.

It's not true that it would necessarily have to know or have recorded at which version each feature became available (although we do have that information in our annotations) -- but it does have to know which version of the spec it fully supports.

And of course it may offer additional features beyond those that were available in Rust 1.22, which is why cfg(accessible) remains a superior (and more convenient) option.

That sounds very reasonable.

I would like to push back on https://github.com/rust-lang/rust/issues/64796#issuecomment-625474439; I think that is the wrong decision. 1.N nightly (any date) should have cfg(version("1.N")) as true.

Context: I maintain some widely used crates, many that support a broad range of compiler versions (back to 1.15.0, 1.13.0, a few 1.0.0), and many that have done version detection in build.rs for years, including both stable and unstable things. One example: https://github.com/serde-rs/serde/blob/v1.0.110/serde/build.rs

I found the following rationales in the discussion, none of which are a compelling justification to me:

  • Note that, while rarely, sometimes features are unstabilized before they get released, as problems are discovered. In this instance, downloading newer nightlies will break your compilation.

    But that breakage happens either way. If something is stabilized in nightly and I publish a use of it behind a version cfg using the anticipated version it's stabilized in, and then it's unstabilized, that code will break. I want it to break in nightly asap. Waiting until beta for the version cfg to tick over and it to break isn't better. Also that harms things like crater runs on the release candidates. Also ecosystem coverage of beta in CI is still not great so an author who uses only nightly and/or stable locally wouldn't even find out about the unstabilization until the stable release is out and their crate doesn't work in it because the feature was unstabilized.

  • Using features that only exist on nightly is likely to require the use of feature gates or other special cases.
    Crates that have extra features on nightly commonly handle nightly via a separate feature flag.

    Yes. That looks like #![cfg_attr(all(feature = "..", version("1.N")), feature(..))] where 1.N is the version whose nightly landed the current form of the unstable thing you are enabling.

  • Most crates don't have great support for nightlies older than the last stable, because they typically assume "nightly" means "latest bleeding-edge". This seems likely to at least somewhat improve that situation, while reporting the nightly version seems likely to make that worse (because crates would assume that cfg(version("1.50")) means "supports all the features of stable 1.50", which will break the nightlies leading up to 1.50).

    Having been involved in this discussion for 4 years (remember a crate called serde_macros which was nightly only?), providing any more than accidental support for old nightlies is a lost cause. If someone is pinning nightly and using unstable features, they need to pin their crates too. If someone is pulling in crate updates and using unstable features, they need to be prepared to pull in nightlies too. The thing that this rationale refers to as being made worse is a non-issue in my experience with my crates.


I don't see rationales in the other direction so adding one:

  • If today an exciting stabilization lands in 1.N nightly and I want my crate to be in good shape to use it as soon as 1.N is stable, how do I even develop under the proposed approach?

    • Do I fork the project and do all implementation work involving the new feature off of master for the next 3 weeks until beta, without putting version cfg anywhere, just so I can compile and test the code, then after 3 weeks when beta is out I insert all the required version cfgs everywhere and do a massive merge?
    • Or do I develop on master using a version("1.N") gate, but I need to comment out all of the feature gates locally in order to compile and test my changes, meaning I get zero coverage of the new code in CI for 3 weeks?
    • Or do I develop on master using a version("1.N-1") gate and turn off my beta build in CI for the next 3 weeks?

    The developer experience here is bad.


If someone is pinning nightly and using unstable features, they need to pin their crates too. If someone is pulling in crate updates and using unstable features, they need to be prepared to pull in nightlies too.

Note that this includes never updating _stable_ dependencies either, if you have a pinned nightly from early on in 1.50-nightly, and a dependency of yours starts using a feature stabilized in 1.50-stable behind a cfg(version) check, that feature may have been stabilized _after_ the nightly you are using (or worse, stabilized before it, but with a subtle change in behaviour after stabilization before beta). Currently even if you are building on a pinned nightly you can assume that updating any stable crates that guarantee a MSRV before your nightly is a non-breaking change.

If something is stabilized in nightly and I publish a use of it behind a version cfg using the anticipated version it's stabilized in, and then it's unstabilized, that code will break. I want it to break in nightly asap.

Pushing code you don't test for isn't really a good development practice.

If today an exciting stabilization lands in 1.N nightly and I want my crate to be in good shape to use it as soon as 1.N is stable, how do I even develop under the proposed approach?

I have wondered about this myself as well and pondered about proposing a nightly-only cargo/rustc -Zassume-complete-nightly option that enables the version(1.N) check for 1.N nightly. Generally it's beneficial to have bug testing of features on nightly as much as possible as getting fixes into beta is harder than onto master. However, ultimately I felt like it didn't have enough weight as it doesn't prevent testing per se, only enabling it via version(1.N). Ideally, a feature is tested before it's stable where version(...) doesn't help you anyways.

Given your statement though, I could totally live with a -Zassume-complete-nightly option as a compromise.

Currently people can do #[cfg(hello)] and then do cargo rustc -- --cfg hello or similar to test stuff. Once beta is cut, it won't be hard to grep for hello and replace it with version(1.N). Admittedly it would be even easier if you could just do version(1.N) right away.

The entire point of this feature is to support older compiler versions. The point of contention is whether the feature should include older nightly versions or not. I think people pin nightly as often as they pin stable, and I think we should do our best to discourage people from enabling RUSTC_BOOTSTRAP.

Thanks @dtolnay for the pushback =)

One important factor in this discussion seems to be #[cfg(accessible)]. I think there was some assumption that the "right" way to test for an individual feature being available would be to use cfg(accessible), but afaik that feature hasn't even been prototyped. I'm not sure how to think about that.

I'm going to nominate for us to rediscuss, regardless.

Actually the ideal would probably be for some smaller set of folks (including @dtolnay) to setup a meeting and hash it out.

#[cfg(accessible)] has been prototyped and is available in nightly. It is accessible as #[cfg_accessible], see the implementation PR and the tracking issue.

It apparently has some limitations, though I haven't played with it enough to know what exactly the limitations are.

Oh, great! I stand corrected!

We discussed this in last week's lang-team meeting and I was supposed to write a summary, but I didn't get to it until now. Eep. I don't think we came up with a remarkably new twist, except to note that the correct workflow for a library, in part, depends on whether you expect people to be using pinned nightly results. I don't think it was really anything that hadn't already been said in this thread, to be honest.

(One side note is that we did have an example of the sort of language feature that cfg(accessible) couldn't be used to test for, which was a const fn stabilization, such as adding the ability to use loops in a const fn.)

So, I am re-reading @dtolnay's comment and I think that this part stands out to me:

Having been involved in this discussion for 4 years (remember a crate called serde_macros which was nightly only?), providing any more than accidental support for old nightlies is a lost cause. If someone is pinning nightly and using unstable features, they need to pin their crates too. If someone is pulling in crate updates and using unstable features, they need to be prepared to pull in nightlies too. The thing that this rationale refers to as being made worse is a non-issue in my experience with my crates.

I think my feeling has shifted. In part, I am not willing to second guess @dtolnay's experience in what is the best workflow for managing library development and nightly crates and so forth.

I think I would be happy to reverse the decision, and to have #[cfg(version)] test the nightly version, but I would like to see a kind of comprehensive guide to how do to develop against nightly features. This should cover both advice for library authors and advice for folks who are using nightly -- e.g., if you're going to pin nightly, you need to coordinate that with upgrading of Cargo.lock, and so forth. It seems clear that this is not the smoothest experience right now but that's ok. I imagine it would also talk about cfg(accessible) vs cfg(version) and when you should use each one.

I feel like that guide ought to be written before we stabilize either feature. It seems like the knowledge is there and it wouldn't be that hard for us to write it. That said, while I long to volunteer my time towards doing so, I know that's a bad idea, so I'm curious if there's anybody out there who'd like to take a stab at it, and run it by e.g. @dtolnay for feedback.

Also, obviously, other folks on the @rust-lang/lang team may disagree with my assessment here, this is just me speaking for me.

Related to const fn, though admittedly tangential to this thread, is the "preferred" way to handle that just rewriting the entire method (or using something like the const_fn crate to do it for you), or is there some better way I'm not aware of?

I don't have much new to add either. I see the downsides in both solutions, but ultimately the ecosystem would adapt to either one.

  • In favor of my design, the point I find most compelling is the discussion of how to do nightly development at the bottom of https://github.com/rust-lang/rust/issues/64796#issuecomment-634546711. https://github.com/rust-lang/rust/issues/64796#issuecomment-634634733 brings up some ways that we could make the lang team's original design work but none of those seem like a satisfying experience to me; I fear we would give up a lot of eyes on features in the most critical window between when the stabilization lands in nightly and when the stable release ships. I don't have numbers but my sense is that features often see a spike in usage in this window as people get their crates ready for the release, and that's a big opportunity to discover last-minute blockers or polish.

  • In favor of the lang team's original design, the point I find most compelling is the ability to do "back in time" compilation where, in a world where everything uses cfg(version()) perfectly, we can take current code and compile it on an old nightly, for example to bisect bugs. Obviously I find this less compelling than the previous. The fact that the code being compiled changes as we go back versions already reduces the usefulness of this in attempting bisects. The way I'd prefer this use case to be addressed instead is via tooling which can update you to crate versions "as of" a given date.

@dtolnay @nikomatsakis What if we introduce a compiler option that causes the compiler to identify as the previous beta (or the previous stable), and introduced some kind of integration that makes it easy for people pinning a specific nightly version to use that option? That way, people working on a pinned nightly will get the behavior that doesn't break with features introduced after their pinned nightly version and before the next beta/stable, while people working on latest nightly will get the behavior they expect?

I like that.

Two examples of companies using something like pinned nightlies: Fuchsia , Dropbox . Admittedly though, Fuchsia seems to update versions regularly (something like once per week) and the dropbox comment is a bit old by now. Furthermore if you want to pin nightlies, you can always use nightlies that were released short before beta cutoff, they should have the full feature set of their specific release available. So I'd guess it'd be okay to have an option as @joshtriplett suggests.

I think having an option seems fine but I'm not quite sure where/how it's supposed to be set by people.

Was this page helpful?
0 / 5 - 0 ratings