Skip to content
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: An edition-compatible system for "removing" deprecated items from the standard library #3088

Closed
wants to merge 2 commits into from

Conversation

bstrie
Copy link
Contributor

@bstrie bstrie commented Feb 24, 2021

The Rust standard library contains many items marked as "deprecated", implying that users should avoid using them in favor of alternatives. Despite their undesirability, these deprecated items can never be outright removed from the standard library, in keeping with Rust's stability guarantee. However, with the aid of the edition mechanism, the use of a deprecated item can be made into a compile-time error, thereby allowing such items to be "removed" from the standard library in a way that remains fully edition-compatible.

This RFC proposes the following:

  1. A mechanism by which selected deprecated items in the Rust standard library can have their lint level upgraded from "warn" to "deny" based on the Rust edition that the user has selected.
  2. A policy of applying this mechanism to items that have previously been deprecated for at least one full edition cycle.
  3. A policy of additionally marking such items as #[doc(hidden)], thereby removing them from the generated documentation.
  4. A policy of employing Rustdoc aliases to explicitly redirect users of deprecated items to their replacements in Rustdoc search results.
  5. An exhaustive list of items that have been deprecated since before the Rust 2018 edition that would be subject to these policies for the Rust 2021 edition.

A working implementation of the technical aspects of this proposal can be found here.

Rendered

@bstrie
Copy link
Contributor Author

bstrie commented Feb 24, 2021

(Errata: while researching this RFC I discovered two deprecated items that accidentally weren't deprecated at all, and additionally that the entire os::haiku::raw module has been sitting around waiting to be deprecated since Rust 1.8. Additionally, note that the POC implementation above is based on my proposed refactor of the deprecation handling attributes in the compiler; that PR isn't actually required to make this RFC's mechanisms work, I just think it makes the logic nicer.)

@scottmcm scottmcm added T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC. labels Feb 24, 2021
@scottmcm
Copy link
Member

A policy of employing Rustdoc aliases to explicitly redirect users of deprecated items to their replacements in Rustdoc search results.

Would it make sense to have this redirection be a part of the rustc_deprecated attribute itself? It seems likely that the replacement is mentioned in the human text of the deprecation; making that machine accessible could be nice.

(Also true of other lint attributes, like many of the must_use attributes point to other simpler methods if the result is unused.)

@steveklabnik
Copy link
Member

I wish I had the time to write a longer comment, but I do not. Sorry in advance.

Historically, I have not found sufficient motivation for actually hiding things. It doesn't have any of the traditional advantages of removal, because they're not removed, only hidden. It also creates work for people, for unclear (to me) benefit.

Upon reading this RFC, it seems like the only clear benefit is "the documentation is smaller." I am not sure that that carries the weight of adding entire new mechanisms, and putting work on some of our users (and probably, our largest users...).

@comex
Copy link

comex commented Feb 25, 2021

My concern: People reading code sometimes search the docs for APIs used by that code in order to figure out what they do. (I hear that IDEs tend to have this built in, but personally I just do it by hand.) If we start removing items from the docs entirely, someone reading code from an old edition might try to look one up and be left baffled.

@ssokolow
Copy link

ssokolow commented Feb 25, 2021

@comex Maybe some kind of "collapse and/or fade" behaviour for APIs removed on the current edition so they don't draw undue attention from people working on the current edition but people working on older editions can still find them.

Something like this but maybe with some kind of "removed" icon or annotation that's visible when collapsed without being as bulky and eye-catching as the current "Deprecated since" blocks:

Screenshot_20210225_034323

(I didn't think to try it, but maybe a strikethrough on the collapsed, faded elements which gets replaced with a "Removed in [edition]" block when expanded. That seems like an intuitive way to communicate what's going on.)

@djc
Copy link
Contributor

djc commented Feb 25, 2021

Removing these from the generated documentation seems... not great. I'd like deprecations to become deny by default in newer editions, but if they're still in older editions I still might want to look them up in the docs. Making that harder seems like it has no advantages.

@bstrie
Copy link
Contributor Author

bstrie commented Mar 8, 2021

Responding to comments:


A policy of employing Rustdoc aliases to explicitly redirect users of deprecated items to their replacements in Rustdoc search results.

Would it make sense to have this redirection be a part of the rustc_deprecated attribute itself? It seems likely that the replacement is mentioned in the human text of the deprecation; making that machine accessible could be nice.

Actually, this might already be supported, to a degree. #[rustc_deprecated] has both a mandatory reason field, which is shown to the user in warning messages, and an optional suggestion field, which seems like it is intended for machine consumption via cargo fix and the like. The problem is that documentation of this field is so nonexistent that even in the rare places where it's being used, it's being used incorrectly: e.g. here is the suggestion that motivated that this field be added in the first place, and yet cargo fix exits with an error when it tries and invariably fails to apply this suggestion. Here is an item where cargo fix applies the suggestion properly. AFAICT the current implementation is limited to only transforming one identifier into another identifier, without being able to do anything smarter e.g. transforming an identifier into an expression, changing parameter order, adding import paths, etc. But even with those limitations this could still probably be successfully applied to several of the items mentioned in the RFC (currently none at all are making use of this). I'll update the RFC with this in mind.


Historically, I have not found sufficient motivation for actually hiding things. It doesn't have any of the traditional advantages of removal, because they're not removed, only hidden.

For users of the new edition these items would be effectively removed; the only stronger statement would be to forbid instead of deny them, which would also be fully within the purview of an edition's capabilities.

Upon reading this RFC, it seems like the only clear benefit is "the documentation is smaller."

The goal is not smallness, rather it is that the documentation should not be permanently cluttered with things that users are encouraged not to use. To illustrate, as of Rust 1.52, of the 61 stable modules in the Rust stdlib, 12 of them will be marked as deprecated; a full fifth of the modules listed on the index page will be for modules that users are expected to ignore. Of course, due to the conservative policy proposed here, these specific modules would not actually be removed for several more years, but it would be nice to think that someday they would no longer clutter the index. This problem of increasing noise in the documentation is only going to become more acute as time passes; this RFC seeks to tackle it before it becomes too onerous.


My concern: People reading code sometimes search the docs for APIs used by that code in order to figure out what they do.

This is addressed by the following:

  1. When a user uses a deprecated item, they currently receive a compiler warning telling them what the suggested replacement is. Under this RFC, for users on new editions this warning would become an error, but the compiler message would remain the same. It is simple to search for the documentation of the suggested replacement.
  2. As proposed by this RFC, Rustdoc aliases would be leveraged so that even users who haven't compiled the code would be shown the documentation of its suggested replacement.
  3. As mentioned above, and as will be proposed by the next revision of this RFC, the suggestion field may be leveraged to automate the transition away from deprecated items, reducing the number of occurrences wherein a user has an excuse to examine a deprecated item.

Maybe some kind of "collapse and/or fade" behaviour for APIs removed on the current edition

An interesting idea, I'll add this to the alternatives section, and will pursue it further if there is continued resistance to the doc(hidden) aspect of this RFC.


I'd like deprecations to become deny by default in newer editions, but if they're still in older editions I still might want to look them up in the docs. Making that harder seems like it has no advantages.

The RFC's argument is not that there are no disadvantages, but rather that on balance it is a positive for consumers of the documentation. For example, see the search results page when searching for "max"; on my screen, of the 23 results that are immediately visible and above the fold, 14 of them are deprecated; if you were looking for a numeric constant, the 14 deprecated ones have pushed all but 3 of the suggested replacements off the bottom of the screen, below the fold. This is exacerbated by the fact that search results show no deprecation warning, and by the fact that deprecated items are sorting before non-deprecated ones; fixing both of these would involved annotating search results with additional markup and metadata, further swelling the enormous multi-megabyte JSON file that powers the search engine and which is starting to contribute to complaints of slowness of Rustdoc's search. Removing old deprecated items would free up size budget that could be spent treating newer deprecated items more intelligently, which would benefit every user of the docs, even those that aren't searching for anything related to a deprecated item.

@programmerjake
Copy link
Member

maybe deprecated things could be put in their own separate section at the end of the docs, minimized by default, such that you don't have to be distracted by them, but the docs are still there if you really need them.

@joshtriplett
Copy link
Member

I don't think we should hide or remove the documentation for old deprecated APIs. The old edition still exists, code may still call those APIs, and the documentation should continue to be available.

I do otherwise think this is a good idea.

@bstrie
Copy link
Contributor Author

bstrie commented May 30, 2021

Closing based on the sentiment in the discussion at https://rust-lang.zulipchat.com/#narrow/stream/268952-edition-2021/topic/denying.20edition.202015.20deprecated.20APIs/near/237190120 .

@bstrie bstrie closed this May 30, 2021
@Diggsey
Copy link
Contributor

Diggsey commented May 30, 2021

The discussion on zulip seemed to focus a lot on how this would be reflected in rustdoc in a way that's not confusing and is still useful for people on older editions.

One option that I didn't see mentioned is to have a drop-down in the documentation to pick the edition. This dropdown would have "2015", "2018", "2021", etc. as options.

If you select "2021", then items which were deprecated with the 2018 edition would be completely gone. Items which were deprecated with the 2021 edition would be present but marked as deprecated. If you select 2018 then all items accessible to the 2018 edition (including new ones added in 2021) are shown, and items deprecated with the 2018 edition are shown as deprecated.

@bstrie
Copy link
Contributor Author

bstrie commented May 30, 2021

Yes, I think there are a lot of improvements that can be made to rustdoc in order to achieve much of what was proposed here. I intend to pursue those in the medium-term.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants