Basically the longer it takes to deprecate stuff, the greater number of
code will exist that will be affected by deprecation changes.
I (and obviously a number of others) think there is a good middle ground where we can steer people away from using deprecated features (and effectively remove them from their reach if they want to use a given version) without ever breaking things.
Yes, it will have a cost for those maintaining std (in that public facing APIs must be kept effectively forever unless its inherent breakage outweighs the breakage from removing it), but the resulting stability will be oh so worth it.
thatās true. there are constructs which are legal in c++03 but not c++11, and so on
however, what you wonāt find is some cutover point where with release 3.5 of gcc or 2008 of MSVC you can no longer use X but have access to Y. thereās no āx.0ā releases in the sense used by semantic versioning of libraries, where an api is removed or replaced - there are standard versions, which implementations support to greater or lesser degrees (sometimes dropping support for old ones, but not as an immediate transition!)
rustc is an implementation which also serves as its own specification. unless serving quite a different set of users, it wonāt be possible for it to go 1.x->2.0 in the traditional semver sense - not without experiencing exactly the same adoption problems as, say, python 3.
once an implementation is used in industry then a long term requirement for that implementation is support of older unchanged code. i say requirement rather than e.g. good idea because if this is not done, people will simply never upgrade.
none of that makes deprecation a bad idea, btw. at minimum thereās always java style ādeprecate without ever removingā and you surely donāt need to be as backward compatible as java.
however I donāt think it should be planned or its āaggressivenessā measured with reference to some cutover semver-major breaking release. thatās a recipe to stall adoption or scare it away from ever occurring.
Just a reminder that Iāve set up RFC PR #1147 on rust-lang/rfc. So I invite all of you who want to discuss how rust should handle deprecation, please come over there. General (not rust-specific) discussion about deprecation can then continue here. Thank you!
I havenāt read all of the comments so far, but Iām curious if using a different mechanism for avoiding warnings would be useful. The idea would be to have a targeted rust version specified for a program and have each deprecation list a rust version that it applies to and the warning would only be shown when the targeted rust version is less than or equal to the version that the deprecation applies to.
That would also allow the reverse, which is warning when using features that are newer than the desired version, though I understand thatās an entirely different consideration.
Oh, and just to be clear, I support aggressive deprecation. For example, I like the way the Lua designers deal with removing things from the library (i.e. they do it when required to make things better).
Lua has a very different set of needs. With Lua, it is expected that your code lives embedded in an application, and all given code targets the same version. Incidentially, this is why so many gaming shops are still running 5.0 or 5.1 (and IIRC, ScummVM bundles an even older Lua still).
With target version based deprecation, we can (mostly) have all versions of std side-by-side, which each library using the one most suited. This affords us the much of the same flexibility as the Lua authors, while removing most avenues for breakage.
This discussion has become quite quiet (now say that three times, fast!), meanwhile the discussion is raging over the first breaking change over at Nikoās RFC PR and elsewhere.
I hope to rectify this (and hopefully get you people back to this discussion, because itās important for Rustās future) and also give a small overview of the changes I made to my RFC PR since I wrote it to capture the spirit of the discussion here:
Deprecation and removal because of security considerations are separate concerns and should be handled separately. Therefore my RFC proposes an additional #[insecure(reason="...")] attribute that can be used to warn even when deprecation would otherwise be allowed.
The idea of opt-in/opt-out was brought up (also in other RFC PRs) and I included it unter alternatives. Seeing that the base idea is very useful (and has been thrown around here under pythonās from __future__ import ... moniker (perhaps a bit one-sided, one could also concievably want to import from past ), I want to include it as part of the main proposal (but I want to think the consequences through and have an appealing syntax for it).
Some people suggested we use the current rust version by default if no target version is specified. I rejected this, because it would break all current code by default. However, this solution basically blesses 1.0 as the default version, which we may want to reconsider in the future (e.g. when 2.0 hits, we may want to change the default).
The solution which @nikomatsakis originally proposed was that calling rustc directly would default to the latest version (since usually one would be testing small bits of code and want the latest version), while running cargo on a crate with no version specified in Cargo.toml would default to 1.0 (for backward compatibility with existing published crates). Additionally, Cargo would automatically add a version specifier to all newly created crates (defaulting to the current version).
This seems like the most sensible approach to me, if we go with a version-based system.
Seems like a good idea ā perhaps putting the target version into Cargo.toml is the better solution after all. Iāll try to think it through and update the RFC if apropos.
Update: I have extensively rewritten my RFC PR #1147. It now covers both language and API changes, uses a rust = "1.2.0" pseudo-dependency within cargo + a --target argument on rustc and removes the more complicated machinery.
Iām broadly in favour of aggressive deprecation (e.g. because Javaās libraries are huge and a mess of inconsistencies). But Iām less in favour of #[allow(deprecated)], except for use with specific features.
In my opinion, the compiler should output only something like this by default:
5 deprecated features used. Re-run with --show-deprecations for details.
Your RFC covers a lot of ground. My point is that (non-security) deprecations shouldnāt be overlooked entirely, but are low-priority enough that itās not worth throwing a lot of messages at the user immediately. A one-liner seemed like a good compromise.
What i really hope is that the major libraries, say a java nio, swing or concurrent package equivalents are specifically developed out of tree, so that people are forced to pull them and they canāt complain about major redesigns. Itās over ten years after maven and ivy.
The real deprecation trouble in my experience doesnāt come from std apis, which are always extremely careful to do stuff gradually and often leave the (wrong) code in just for bad code to keep working badly (like Thread.stop).
It comes from essential libraries upgrades. If Cargo and Rust compiler and linker keep being robust enough to keep building old versions of popular libraries and those versions targeted to old-rust-whatever, keep being upgraded as Rust deprecates parts on tip and backports and using them even on modern rust keeps being possible, 99% of the pain of ādeprecationsā will be a non-issue, just upgrade for the next minor version of the library. Ofc this kinda requires that libraries are careful of what interfaces/traits they expose and are especially careful not to expose external ones (more for other sub-libraries than Rust std lib). This in turn leads to duplicated code.
Anyway it would be helpful if crates.io had a āwall of shameā for minor releases, something like āv0.4 of this library uses deprecated APIs: [list]ā warning in its page.