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

Tracking issue for the 2018 edition’s prelude #51418

Closed
SimonSapin opened this issue Jun 7, 2018 · 17 comments
Closed

Tracking issue for the 2018 edition’s prelude #51418

SimonSapin opened this issue Jun 7, 2018 · 17 comments
Labels
A-rust-2018-preview Area: The 2018 edition preview C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. E-help-wanted Call for participation: Help is requested to fix this issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. WG-epoch Working group: Epoch (2018) management

Comments

@SimonSapin
Copy link
Contributor

SimonSapin commented Jun 7, 2018

Currently, every module has something like use std::prelude::v1::*; implicitly inserted into it by default.

In #49305 we added the TryFrom and TryInto traits to the prelude, and reverted that in #49518 because that a breaking change for a significant number on crates that had their own TryFrom or TryInto traits. (Ironically, identical to the std ones and duplicated because those were still unstable.)

Consensus is that we’d still like to have those traits in the prelude, but to avoid breakage we need to make that opt-in. The upcoming 2018 edition seems to be a good opportunity for that. For modules in crates that opt into the 2018 edition, we could replace v1 in that inserted code with edition2018 and create src/libstd/prelude/edition2018.rs and src/libcore/prelude/edition2018.rs like so:

pub use super::v1::*;
pub use convert::{TryFrom, TryInto};

Are there more items we considered adding to the prelude but didn’t because of breakage or breakage risk?


Update: implemented in #51434.

@SimonSapin SimonSapin added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. A-rust-2018-preview Area: The 2018 edition preview labels Jun 7, 2018
@SimonSapin
Copy link
Contributor Author

every module has something like use std::prelude::v1::*; implicitly inserted into it

(Not exactly, but close enough for an easier explanation. The relevant code is in src/libsyntax/std_inject.rs.)

@eddyb
Copy link
Member

eddyb commented Jun 7, 2018

Should we rename v1 to edition2015 and add an alias for it? Then the compiler can just plug in the edition year into the path.

@SimonSapin
Copy link
Contributor Author

@eddyb Maybe. Either way seems easy enough for the compiler.

@clarfonthey
Copy link
Contributor

I really like naming the preludes after the editions instead sequential v1, etc., although I'd suggest going with rust2015 instead of edition2015.

@clarfonthey
Copy link
Contributor

clarfonthey commented Jun 8, 2018

Also, what I think should be added, ordered from most important to least important:

  • TryFrom and TryInto: Already proposed. Generic conversions happen often.
  • Hash: Used in generic code, usually when something would like to store values in a HashMap or HashSet. While this presumably was left out due to it making the hash and hash_slice methods available on a majority of types, I feel like this is outweighed by the usefulness of having the type available.
  • FusedIterator: Used in generic code, and the name is very unlikely to clash with anything.
  • RangeBounds: Same as above.
  • Duration: While this isn't used very often, any code which works with time will likely want this. A bit fuzzy on the inclusion, as it's more likely to cause name conflicts.
  • Debug and Display: These would be higher on the list if it weren't for the fact that both traits share the same method name: fmt. They're often used in generic code and I feel like not having to import them when using them would be a plus.

@eddyb
Copy link
Member

eddyb commented Jun 8, 2018

@clarcharr The advantage of having Debug and Display in the prelude is that now we can just use Debug::fmt and Display::fmt and it's not much worse than if we had debug_fmt & display_fmt.

@SimonSapin SimonSapin added the WG-epoch Working group: Epoch (2018) management label Jun 8, 2018
@SimonSapin SimonSapin changed the title Different (extended) prelude for the 2018 edition Tracking issue for the 2018 edition’s prelude Jun 8, 2018
@matklad
Copy link
Member

matklad commented Jun 11, 2018

Duration: While this isn't used very often, any code which works with time will likely want this.

Yes please! I often find myself using deprecated ::std::thread::sleap_ms(1000), because reaching for Duration is to long.

EDIT: alternative solution for this specific problem: #51610

as it's more likely to cause name conflicts.

IIRC, names in prelude are shadowed by anything, including * imports, so I think it is not possible to get a conflict by adding a struct to prelude.

The situation with traits specifically is more difficult: although traits themselves enjoy shadowing, trait methods do not, so ambiguous method call between explicitly and glob imported trait is a compile-time error (I haven't thought about it deeply, but looks like it should be possible, and even natural and consistent, to extend shadowing behavior to trait's methods? (EDIT: filed #51497)).

@jkordish jkordish added the C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. label Jun 13, 2018
@SimonSapin
Copy link
Contributor Author

@clarcharr Other than TryFrom and TryInto, was there suspected or observed compat risk with adding those to the 2015 prelude? If not, feel free to propose adding them regardless of this issue (which is about having a different prelude per-edition).

@matklad Exactly, the name collision was not with the traits themselves but with the methods that are in scope.

@SimonSapin
Copy link
Contributor Author

#51434 had a naïve implementation but was missing something required by https://rust-lang.github.io/rfcs/2052-epochs.html#a-broad-policy-on-epoch-changes: a warning for 2015-edition code that would break with the new prelude.

Unfortunately I don’t know how to go about implementing that warning, so any help here is appreciated.

Alternatively, tweaking the method resolution rules so that methods from traits that are only in scope through the prelude have “less priority” and do not collide with other methods would allow us to add TryFrom and TryInto to std::prelude::v1 and not have a separate 2018-edition prelude at all.

@SimonSapin SimonSapin added the E-help-wanted Call for participation: Help is requested to fix this issue. label Jun 18, 2018
@liigo
Copy link
Contributor

liigo commented Jun 26, 2018

FusedIterator: Used in generic code, and the name is very unlikely to clash with anything.
RangeBounds: Same as above.
Duration: While this isn't used very often, any code which works with time will likely want this. A bit fuzzy on the inclusion, as it's more likely to cause name conflicts.

"very unlikely to clash with anything" may applies to many many other types.

@Mark-Simulacrum Mark-Simulacrum added I-nominated T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Jul 24, 2018
@scottmcm
Copy link
Member

The lang team discussed this; here are my take at some notes:

  • The idea of preludes being per-edition was received positively.
  • There was a strong desire to limit the conversation for now to those things that must be edition-tied, and thus not add any concrete types at this time, as that can be done at any time.
  • Adding TryFrom & TryInto seemed like a good set.
  • So the question boiled down to how to get the linting right.

But there was an observation made that unstable_name_collisions already exists, and that ! (and thus TryFrom/Into) are not going to be stable in time for the edition. Thus, the prelude edition is non-breaking; it'll end up just being more like an idiom lint in that it turns on once you're in the edition. And then stabilizing is a de jure non-breaking change, since it's just to method resolution, but it'll hopefully be lower impact as everyone will have been heavily warned about it, and it won't break all the older crates the way that adding them to the 2015 prelude would have.

How do people feel about that approach?

@Mark-Simulacrum Mark-Simulacrum removed this from the Rust 2018 RC milestone Jul 31, 2018
@SimonSapin
Copy link
Contributor Author

I kinda dropped the ball here and nobody picked it up. The 2018 edition is stable in Rust 1.31 which is now in beta so it’s likely too late for this, closing.

@eddyb
Copy link
Member

eddyb commented Nov 14, 2018

We can still do the libcore/libstd organizational changes, right?
If only to provide a precedent for Rust 2021 to build upon.

@SimonSapin
Copy link
Contributor Author

Sorry, it’s been a while. What changes are those?

@eddyb
Copy link
Member

eddyb commented Nov 14, 2018

I just mean having e.g. std::prelude::{rust2015, rust2018} etc. instead of v1 (we can't remove v1, but we could deprecate it).

@oconnor663
Copy link
Contributor

Should we think about re-opening this for the 2021 edition? Or better to start a new thread?

@bstrie
Copy link
Contributor

bstrie commented Jan 21, 2020

@oconnor663 there appears to be a new thread at #65512 , I'd suggest anyone else interested in this should migrate there as well.

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Mar 9, 2021
…akis

Edition-specific preludes

This changes `{std,core}::prelude` to export edition-specific preludes under `rust_2015`, `rust_2018` and `rust_2021`. (As suggested in rust-lang#51418 (comment).) For now they all just re-export `v1::*`, but this allows us to add things to the 2021edition prelude soon.

This also changes the compiler to make the automatically injected prelude import dependent on the selected edition.

cc `@rust-lang/libs` `@djc`
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Mar 10, 2021
…akis

Edition-specific preludes

This changes `{std,core}::prelude` to export edition-specific preludes under `rust_2015`, `rust_2018` and `rust_2021`. (As suggested in rust-lang#51418 (comment).) For now they all just re-export `v1::*`, but this allows us to add things to the 2021edition prelude soon.

This also changes the compiler to make the automatically injected prelude import dependent on the selected edition.

cc `@rust-lang/libs` `@djc`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-rust-2018-preview Area: The 2018 edition preview C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. E-help-wanted Call for participation: Help is requested to fix this issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. WG-epoch Working group: Epoch (2018) management
Projects
None yet
Development

No branches or pull requests