-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Prelude additions #3090
Prelude additions #3090
Changes from all commits
981eb6d
afc2fd1
5ad7dd0
f9d5094
c197f06
0b88294
5942f04
2944db8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
- Feature Name: `prelude_2021` | ||
- Start Date: 2021-02-16 | ||
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) | ||
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
A new prelude for the 2021 edition, featuring several extra traits. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
While types and free functions can be added to the prelude independent of edition boundaries, the same is not true for traits. Adding a trait to the prelude can cause compatibility issues because calls to methods named the same as methods of the newly in scope traits can become ambiguous. Because editions are opt-in, they represent an opportunity to add new traits to the prelude. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is true, but AFAIK T-libs doesn't actually consider that a breaking change (since otherwise every time they added an inherent method, or a new method to a trait, it could break code). Not sure if you want to mention that or not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the official terminology is that it's a "minor change": https://rust-lang.github.io/rfcs/1105-api-evolution.html#minor-change-adding-a-defaulted-item So allowed despite the breakage. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's still worth keeping this explanation, and just expanding it to make it clear that while we can make such a change, we may choose not to due to the possibility of breakage. The explanation should also make clear that many traits we might want to add are especially likely to cause breakage, because they may conflict with similar traits from the crate ecosystem that exist to fill the same need that the standard library trait would. |
||
|
||
The expected outcome is to make the newly added traits more accessible to users, potentially stimulating their use compared to alternatives. | ||
|
||
# Guide-level explanation | ||
[guide-level-explanation]: #guide-level-explanation | ||
|
||
The compiler currently brings all items from `std::prelude::v1` into scope for each module (for code using `std`). Crates that declare usage of the 2021 edition will instead get items from `std::prelude::edition2021` imported into scope. With the implementation of this RFC, we will add `edition2015` and `edition2018` modules in `std::prelude`, and a crate configuring a particular edition will get the prelude appropriate for its edition. The `v1` module will stick around for compatibility reasons, although it might be deprecated in the future. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Module names are snake_case by convention. This should be Citation: You might say, “but In the very distant past, well before 1.0, there was some momentum for joinedlowerwords crate and module names, as Python does with its packages and modules, but that was steadily dismantled in favour of snake_case. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think that's correct, you're inferring from something that matches There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there anywhere else we use "edition_2021", "edition 2021", "edition-2021", or "edition2021"? If we do, we should aim to be consistent with that. In |
||
|
||
The `core` prelude will parallel the `std` prelude, containing the same structure and the same items as far as they are available in `core`. | ||
|
||
This RFC proposes to add the following traits to `std::prelude::edition2021`, but not `std::prelude::v1`: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While most users will never see it, it's still odd to have the modules be named There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've updated this to explain the plan a bit more, see also the initial implementation PR. Does that make things sufficiently clear? |
||
|
||
- `TryFrom`/`TryInto` | ||
- `FromIterator` | ||
|
||
Apart from the 2021-specific prelude, this RFC also proposes to add several items to preludes for all editions. These changes do not have to be aligned with an edition boundary, since there is no compatibility hazard (explicitly imported names always shadow prelude names). | ||
|
||
- `std::{mem, fmt}` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like modules are a pretty large change here, so far we've only ever had types, traits, and functions in the prelude, if modules are included then people may think they are crates. This drawback should be called out and addressed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given that e2018 makes all cratenames implicitly present in every scope, I personally am very skeptical of having any other source of implicit inclusion of lowercase symbols. Currently, the preludes only import one function: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should the RFC specify what happens if the module name collides with a crate? There are already There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, the prelude is just a glob import, glob imports have well-defined behavior around this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mbartlett21 it's also possible that other packages explicitly specify the cargo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While adding mem/fmt to the prelude could be pragmatic, I think the drawback of introducing a "separate root" (apparently, effectively) like |
||
- `std::collections::{HashMap, HashSet}` | ||
- `std::path::{Path, PathBuf}` | ||
- `std::sync::Arc` | ||
- `std::borrow::Cow` | ||
- `std::fs::File` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Though on that note, having There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would second adding There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe Read/Write but actually not the types? Unsure considering the AsyncRead concern, but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They could be added as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the prelude includes |
||
- `std::cmp::{min, max}` | ||
|
||
Except for newly added traits, the `v1` and `edition2021` preludes should be kept in sync. Items that are added to the `edition2021` prelude should also be added to the `v1` prelude if there is negligible risk for compatibility. On the other hand, newer edition preludes may decide not to include items from an older edition's prelude. | ||
|
||
# Reference-level explanation | ||
[reference-level-explanation]: #reference-level-explanation | ||
|
||
The new prelude will be named after the edition that introduces it to make the link to the edition more obvious. Each edition will have a separate prelude, whether the contents are actually different or not. | ||
|
||
Importantly, we'll need to make the upgrade path to an edition containing new traits in the prelude as smooth as possible. To that end, cargo fix will update code that calls `try_from()` or `try_into()` in a scope that does not have the std traits in scope to use the explicit disambiguation syntax. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Speaking from experience from the 2018 edition, this is extremely underspecified. I'm going to leave a comment there as well, but each edition RFC that has breakages should have a section that:
The 2018 edition RFCs tended to handwave about migration, and when the time came to implement it I realized that there wasn't actually a workable plan and as an implementor I had to come up with it at the last moment, trying to quickly build consensus. We should strongly avoid this situation recurring. |
||
|
||
Currently, diagnostics for trait methods that are not in scope suggest importing the originating trait. For traits that have become part of the prelude in a newer edition, the diagnostics should be updated such that they suggest upgrading to the latest edition in addition to importing the relevant trait. | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
Making the prelude contents edition-dependent makes the difference between different editions larger, and could thus increase confusion especially in the early phase when older editions and newer ones are used in parallel. | ||
|
||
Adding more traits to the prelude makes methods from other traits using the same names as prelude traits harder to access, requiring calls to explicitly disambiguate (`<usize as try_from::TryFrom>::try_from()`). | ||
|
||
# Rationale and alternatives | ||
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
## `TryFrom`/`TryInto` | ||
|
||
The `TryFrom`/`TryInto` traits could not be added to the prelude without an edition boundary. This was [tried](https://github.com/rust-lang/rust/pull/49305) around the time of the 2018 edition, but failed due to breaking substantial parts of the ecosystem. However, `TryFrom`/`TryInto` offer a generic conversion mechanism that is more robust than `as` because the conversions are explicitly fallible. Their usage is more widely applicable than the `From`/`Into` traits because they account for fallibility of the conversions. | ||
|
||
Without doing this, the `TryFrom`/`TryInto` traits remain less accessible than the infallible `From`/`Into` conversion traits, providing a disincentive to implement/use fallible conversions even where conversion operations are intrinsically fallible. | ||
|
||
## `FromIterator` | ||
|
||
The documentation for `FromIterator`'s `from_iter()` method currently reads: | ||
|
||
> `FromIterator::from_iter()` is rarely called explicitly, and is instead used through `Iterator::collect()` method. See `Iterator::collect()`'s documentation for more examples. | ||
|
||
However, it is reasonably common that type inferencing fails to infer the full type of the target type, in which case an explicit type annotation or turbofishing is needed (such as `iter.collect::<HashMap<_, _>>()` -- the type of the iterator item is available, so wildcards can be used for this). In these cases, `HashMap::from_iter(iter)` can be a more concise and readable way to spell this, which would be easier if the trait was in scope. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ??? use std::iter::FromIterator;
use std::collections::HashMap;
fn main() {
dbg!(HashMap::from_iter(vec![(1_u64, 2_u64), (3, 4)].into_iter()));
} Compiling this gives an error:
So no you still need to write There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I my experience let foo: Vec<_> = bar
.iter()
.flatten()
.chain(baz)
.cloned()
.collect(); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I don't believe that occasionally saving two characters and bringing another problem is big enough advantage to justify importing whole trait in prelude. I have same experience with it being used almost exclusively with combinators. |
||
|
||
## `std::{mem, fmt}` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bunch of stuff for these is also applicable to other modules, like So I'm not convinced by the justification in here that specifically these two is the right thing to do. |
||
|
||
It is reasonably common to use functions from the `mem` module such as `replace()` or `swap()`. These method names are generic enough that it is useful to keep the `mem::` prefix explicitly. Providing a `mem` name as part of the prelude makes this pattern more obvious and, given the short module name, will not require any imports to make use of the items in this module. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you justify why this means that this module should be added to the prelude? I don't think that an item being imported a lot actually justifies adding it to the prelude. Especially given that we have no way of actually knowing whether "imported a lot" is true. (You can prove it for your code, and maybe for some of the code in public online, but there is so much more Rust code than that.) It is also worth discussing what we think the prelude should even be for. It's hard to discuss which particular items should go in before we've all agreed on that. In general, I don't think saving people from writing something like I am reasonably in favor of adding some common traits like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We can, and in my opinion should (because I think it would be cool as well as educational), grep crater for the proportion of Rust modules that use symbols from the distribution libraries, whether by There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I guess my point is that not only is that data not complete (because it ignores a huge swath of non-open source code), it also embeds the assumption that usage is sufficient justification. We'd need to define what the prelude is actually for before we get there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In the absence of raised evidence to the contrary, I think that assuming closed-source code has the same statistical shape as open-source code, especially given the volume to which crater has access, is a fairly safe thing to do. A clearer philosophical decision about what the prelude is and should be is certainly worth doing regardless of whether its contents change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think this is probably not that true, since AFAIK crater has overwhelmingly more library crates than binaries. My experience is that this distribution isn't the same for private code. That said, I don't know that we can do much here. At the end of the day, we use the data we have access to. |
||
|
||
Explicit (non-derive) implementations of `Debug` and `Display` are relatively common and require a set of items from the `fmt` module (the trait itself, the `Formatter` type and the `fmt::Result` type). | ||
|
||
## `std::collections::{HashMap, HashSet}` | ||
|
||
Especially when coming from another language where hashmaps and sets are language built-ins with literals provided as part of the language, it can be a little surprising at first that these have to be imported before use. Their usage can be especially common in script-like code, for which effortless usage will be especially helpful. | ||
|
||
While a number of third-party hashmaps are in common use (most of which reexport or wrap the std `HashMap` with a different hasher), bringing the std `HashMap` into the prelude should not cause issues, since explicit imports will always override prelude imports. | ||
|
||
## `std::{{fs::File}, path::{Path, PathBuf}}` | ||
|
||
Are very commonly used, not least of which in script-like CLI tools. | ||
|
||
## `std::sync::{Arc, Mutex, RwLock}` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Subjectively, this batch feels a lot less "universal" or "general-purpose" to me than the rest. Multi-threading logic might be contained to a small number of modules, so I feel this is getting into diminishing returns territory. And if these items qualify for the prelude, shouldn’t (insert list of favorites) qualify too? Overall it’d be nice to have statistics about how often various items are imported in a some corpus of code, to better support the choices made by this RFC in what to include or not. Lacking that, I’d err on the side of fewer additions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The guide-level explanation only mentions There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, I missed that when I was updating it, will fix that soon. |
||
|
||
Help write threaded code. A potential concern is that async code may want to use async variants of these, although even then the [sync Mutex](https://docs.rs/tokio/1.1.1/tokio/sync/struct.Mutex.html#which-kind-of-mutex-should-you-use) may provide better performance. | ||
|
||
Use of alternative implementations (in particular from parking_lot) is fairly common. | ||
djc marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## `std::borrow::Cow` | ||
|
||
Unlikely to clash with other types, yet this type can be of great help in bridging the gap between references and owned types, particular for `String`/`str` and `Vec`/`slice` types. | ||
|
||
## `std::cmp::{min, max}` | ||
|
||
It has come up in [discussions](https://internals.rust-lang.org/t/am-i-the-only-one-confused-by-a-min-b-and-a-max-b/13252) that the method forms of `min()` and `max()` attached to std numeric types can be confusing to understand. In order to level the playing field with the two-argument free functions of the same names, it would be helpful to import these into the prelude. | ||
|
||
## Other traits that have been suggested for inclusion | ||
|
||
Other traits that have been suggested as prelude candidates: | ||
|
||
- `std::ops::Not`: for chaining purposes, it is sometimes useful to have an trailing `.not()` call rather than the prefix `!` operator. Therefore, [it has been suggested](https://internals.rust-lang.org/t/pre-rfc-adding-bool-not-method/13935) that the `Not` trait which brings that method in scope could be added to the prelude. This RFC author feels this use case is better served by adding an inherent impl to `bool`, since that serves the majority of the same use case with less complexity. | ||
- `std::fmt::Display`: users of this trait generally don't need to import it because the `ToString` trait which relies on the `Display` implementation is already in the prelude. Implementers of the `Display` trait however need several other items from `std::fmt` to do so; therefore, just importing `Display` into the prelude does not help much. This RFC suggests adding `fmt` to the prelude to improve this use case. | ||
- `std::fmt::Debug`: similar to `Display`, although there's no `to_debug()`. However, usage will usually go through `dbg!()` or the formatting mechanism (as a `{:?}` format string). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Caveat: The E.g: use core::fmt;
use core::fmt::Display;
struct MyStruct(u32);
impl Display for MyStruct {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f) // Just delegate to the inner impl
}
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand what you're getting at. That code seems to compile just fine? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you have a prelude that then implicitly imports // The prelude with Debug:
mod prelude {
pub(super) use core::fmt::Debug;
}
// Prelude import
use prelude::*;
use core::fmt;
use core::fmt::Display;
struct MyStruct(u32);
impl Display for MyStruct {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f) // Just delegate to the inner impl
}
} |
||
- `std::future::Future`: `Future`'s `poll()` method is usually not called directly, but most often used via `async`/`await`, therefore including `Future` in the prelude does not seem as useful. | ||
- `std::error::Error`: while this is commonly implemented, calling its methods directly does not seem to be common enough that adding this is as useful. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Another drawback: this would be ambiguous with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah calling both types Error was a big flub :/ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Lokathor it's a rather common design choice to reuse names in different modules. This means that you have to write There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A common misconception. Only std::io and std::fmt do that weird thing where you're supposed to use the module name as a prefix. Every other error in the standard library just has a sensible name that doesn't need a prefix. Either way, it's a bad plan at this point to put something called It's possible that the confusion wouldn't be too high because one is a trait and the others are structs, but better to avoid the possibility. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think (EDIT: When I replied to this it was in the thread about the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don’t think it’s useful to blame users for following the standard library’s pattern of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True, but the standard library has since moved away from that pattern (AllocError, Utf8Error, etc). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AllocError is not stable and there's an open point about renaming it. Utf8Error is not in an utf8 module, so it's not changing any conventions. I believe I've heard some Error was accidentally stabilized not following that convention though. But I'm pretty sure there's no real precedent for changing that convention. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Personally I find it annoying that I have to write There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I kind of wish atomics were just in
I don't think this bears out in practice. Most of the code I see and interact with isn't written this way. Additionally, autoimport functionality in IDEs doesn't work this way. |
||
|
||
## Other types that have been suggested for inclusion | ||
|
||
- `std::sync::{Mutex, RwLock}`: async code will regularly want different versions of these types, and there is an ongoing discussion of introducing different versions of these types without poisoning semantics. As such, this does not seem like an opportune time to include these. | ||
- `std::ops::Range` (and friends): while adding these to the prelude could make sense in the future, discussion is ongoing about revising `Range` to fix some long-standing warts. This might result in new `Range` types being added to `std`, so adding these now seems like a bad idea. | ||
|
||
(See [references](#references) below.) | ||
|
||
# Prior art | ||
[prior-art]: #prior-art | ||
|
||
<details> | ||
<summary markdown="span">RFC template</summary> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. leftover? |
||
Discuss prior art, both the good and the bad, in relation to this proposal. | ||
A few examples of what this can include are: | ||
|
||
- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? | ||
- For community proposals: Is this done by some other community and what were their experiences with it? | ||
- For other teams: What lessons can we learn from what other communities have done here? | ||
- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background. | ||
|
||
This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. | ||
If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. | ||
|
||
Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC. | ||
Please also take into consideration that rust sometimes intentionally diverges from common language features. | ||
</details> | ||
|
||
# Unresolved questions | ||
[unresolved-questions]: #unresolved-questions | ||
|
||
* Should there be compatibility lints warning about methods named the same as proposed prelude edition trait methods? | ||
* How do per-prelude editions affect macro hygiene/resolution? | ||
|
||
# Future possibilities | ||
[future-possibilities]: #future-possibilities | ||
|
||
Future editions could add more items and/or remove some. | ||
|
||
# Previous discussions | ||
[references]: #references | ||
|
||
* [Rust Edition 2021](https://hackmd.io/3eG6OZWHRbSMxoRxzwNhGQ?view#-Prelude-changes) | ||
* [Zulip: Prelude 2021](https://rust-lang.zulipchat.com/#narrow/stream/268952-edition/topic/Prelude.202021) | ||
* [Zulip: T-lang asking T-libs for per-edition preludes coordination](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/T-lang.20asking.20T-libs.20for.20per-edition.20preludes.20coordination) | ||
* [GitHub: MCP: per-edition preludes](https://github.com/rust-lang/lang-team/issues/44) | ||
* [GitHub: Tracking issue for vNext edition prelude](https://github.com/rust-lang/rust/issues/65512) | ||
* [GitHub: Tracking issue for the 2018 edition’s prelude](https://github.com/rust-lang/rust/issues/51418) | ||
* [IRLO: Add `std::mem::{swap, replace, take}` to the prelude](https://internals.rust-lang.org/t/add-std-swap-replace-take-to-the-prelude/14035) | ||
* [IRLO: Propose additions to std::prelude](https://internals.rust-lang.org/t/propose-additions-to-std-prelude/7189) | ||
* [IRLO: `std::prelude::v2` with `TryFrom`/`TryInto` on edition 2021?](https://internals.rust-lang.org/t/std-v2-with-tryfrom-tryinto-on-edition-2021/12157) | ||
* [IRLO: Should the Future trait be part of the prelude](https://internals.rust-lang.org/t/should-the-future-trait-be-part-of-the-prelude/10669) | ||
* [IRLO: Random Idea: A new prelude for Rust 2018?](https://internals.rust-lang.org/t/random-idea-a-new-prelude-for-rust-2018/7158) | ||
* [IRLO: [pre-RFC] Adding `bool::not()` method](https://internals.rust-lang.org/t/pre-rfc-adding-bool-not-method/13935) | ||
* [IRLO: Pre-pre-RFC: syntactic sugar for `Default::default()`](https://internals.rust-lang.org/t/pre-pre-rfc-syntactic-sugar-for-default-default/13234/10) | ||
* [IRLO: Am I the only one confused by `a.min(b)` and `a.max(b)`?](https://internals.rust-lang.org/t/am-i-the-only-one-confused-by-a-min-b-and-a-max-b/13252) | ||
* [IRLO: The is_not_empty() method as more clearly alternative for !is_empty()](https://internals.rust-lang.org/t/the-is-not-empty-method-as-more-clearly-alternative-for-is-empty/10612) | ||
* [IRLO: Pre-RFC: Add FromIterator to the prelude](https://internals.rust-lang.org/t/pre-rfc-add-fromiterator-to-the-prelude/4324) | ||
* [IRLO: I analysed 5000 crates to find the most common standard library imports](https://internals.rust-lang.org/t/i-analysed-5000-crates-to-find-the-most-common-standard-library-imports/12218) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like a thing that's missing here is a general policy for what we consider prelude-worthy. We don't have one right now, and my gut feeling is that this RFC goes many steps too far in expanding the prelude. Having an actual policy we can verify proposals against seems to be better than having a grab bag of things that people think should be in the prelude.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it would help future edition changes make choices about the prelude, even if it's just a ponce... a policy only used once, I mean. We should be later able to revisit and see if the rationales were Bad, Actually. ( I am speaking from an assumption that, by sheer weight of inertia, people will think additions are good and subtractions are bad, so there will be a felt need of active justifications to undo a decision but not to make further expansive decisions. )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 to this. Without an agreed philosophy I suspect this will get bogged down substantially by all the details, since every single possible
editionaddition (doh!) could be its own long conversation.Operationally, to get it in for the edition, I think it would make sense to focus this to a small number of minimally-controversial changes that very clearly fit the philosophy and need to be edition tied. Then future RFCs can be about specific additions to focus the conversation about them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strong agree.
I'd imagine this goes along the lines of: