Open traviscross opened 2 months ago
It's interesting that this is a place where that version we're recording on stabilized features might actually be useful for something. AFAIK it's completely unused today.
I think it should never be the normal-and-expected things that lints have to look at the MSRV, nor that lints only apply if your MSRV is at least as high as the version in which the lint was added.
But a clippy lint for "use this new standard library API" or a rustc lint for "use this new thing" both seem like places were it would be reasonable for a lint to make some minor effort to not emit the lint, if the thing it's suggesting is reasonably-new. (If it's suggesting something that's -- strawman -- over a year old then I don't think we should ask people to bother.)
And it should never be expected to be perfect. If there are edge cases where things aren't gated, I think that's entirely fine, just like how the version number in the standard library docs doesn't update every time a tweak is made to a method.
The full answer must always be that the only 100% reliable way is to only deny lints on your MSRV CI build, and permit them on any builds you do on newer toolchains. This should be a "reasonable-effort to let us lint on things sooner" mechanism (rather than waiting a few releases like we often do today), rather than a strict "anything that leaks through is necessarily a bug" hard requirement.
Could this be used to prevent future breakage like the recent issue with time
? With this Rustc could hide impls that weren't available on the given MSRV.
Furthermore it could be used to completely hide other items from newer than MSRV as well, which would reduce the need for testing on older versions. (A suitable lint that thr item is available on a newer MSRV would be needed in this case.)
I don't think we should use this to gate features; let's not turn random Rust versions into pseudo-editions. But I very much want to see this used both to reduce the impact of lints and to tailor lint suggestions.
If we're emitting a lint already, I don't think we should omit lint suggestions based on MSRV, but I think we should give an indication if applying the suggestion will raise MSRV. Ideally, that indication would be machine-readable, and cargo fix
could then decide either "don't apply suggestions that would raise MSRV" or "apply suggestions that would raise MSRV and update the MSRV accordingly".
There are a number of related problems that can be tackled here, and I think we should go for a solution that can address multiple of them.
My understanding of the thread is that this is the original problem statement: "lint is introduced that makes you write code not accepted in an earlier version of Rust". While I think that's a problem worth solving, it feels too narrow to tackle by itself with a compiler flag.
If we're emitting a lint already, I don't think we should omit lint suggestions based on MSRV, but I think we should give an indication if applying the suggestion will raise MSRV.
I think I agree, but "if we're emitting a lint already" is doing a lot of work there. I would never want to emit the lint removed by #129103 in crates targeting older MSRVs, because it's more of a style than correctness issue, and bumping MSRV is therefore not a reasonable action to recommend.
I think it would be really nice to lint (at least as a best effort) against use of features that are later than the MSRV. This is to aid crate authors, not create actual language-level editions in every new version of Rust. As above, the warning cases in the compiler can be cleaned up after some number of Rust versions.
#[stable]
I think really have to solve the specific problem @VorpalBlade mentions, of breaking crates when we introduce new items in std, in one way or another.
Controlling visibility of crate items with a version requirement is, in my view, much less scary than a general edition mechanism. In the case of core/alloc/std, the version number happens to be >=MSRV, but it's important to note that this is for std the crate and not the compiler: If we ever supported decoupling the version of std from the version of rustc, we would look at the version requirement for std and not the MSRV.
In the case of other crates, we would check whatever version requirement is listed in your Cargo.toml against any #[stable]
attributes in that crate (assuming of course that we stabilize the attribute). This is useful not only for limiting breakage when a toolchain or crate graph is globally updated, but also for checking the version requirements listed in a crate's manifest.
Another way is to have a flag that says "lint as if you were this version" and decouple that from updating the actual compiler. This flag nearly does that, but only in the very narrow sense I mentioned above. --lint-version
seems like a decent name.
We can and should only do this as a best-effort and for significant expansions as mentioned before. As an added benefit, we can remove the special casing after some number of Rust releases, without the baggage of a separate lint name.
There are like three RFCs in this comment, but anyway. These flags map to the following:
--msrv
#[stable]
--extern
or similar)--lint-version
I think we should have both flags, but it would not be worth it to stabilize --msrv
and only ever use it to solve the original problem in this thread. --msrv
does nothing to solve the more general problem of lint churn, especially in large codebases where there is no MSRV, just ~one Rust version.
Could this be used to prevent future breakage like the recent issue with
time
? With this Rustc could hide impls that weren't available on the given MSRV.
I don't think so, for the same reason that editions can't change trait impls. Trait solving isn't localized to particular tokens, rather it encompasses things from your crate and any you call, which might be on different editions.
(Things like the array IntoIter
changed method resolution between editions, but the actual impl
was added to all editions.)
There's an open proposal to add an
--msrv
flag to the compiler:The idea is that this could be used, in a similar way to the current
--edition
flag, to gate lints (or features?) based on the MSRV.As a process matter, since lang approves new lints and how they are gated, it seems that it might be helpful to T-compiler to know whether and how lang might intend to use this gating. So let's discuss that.
@rustbot labels +T-lang +C-discussion +I-lang-nominated
cc @rust-lang/lang @compiler-errors