-
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
RFC: Custom preludes #890
Closed
Closed
RFC: Custom preludes #890
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
- Feature Name: custom_prelude | ||
- Start Date: 2015-02-19 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
|
||
Add a `#[prelude]` attribute that can be applied to a single module at | ||
crate root to serve as a custom prelude for that crate. | ||
|
||
# Motivation | ||
|
||
There are a variety of motivations for allowing prelude customization: | ||
|
||
* Applications and libraries are often domain-specific, and end up | ||
using the same set of APIs from other libraries over and over | ||
again. Allowing a custom prelude would drastically improve | ||
ergonomics in such cases, setting up an ambient namespace that is | ||
specialized for their domain. | ||
|
||
* The lack of prelude customization ends up discouraging certain API | ||
designs that would otherwise be fine, e.g. not using extension | ||
traits, or not modularizing code in order to cut down on import | ||
work. | ||
|
||
* Rust has long been moving away from special treatment of built-in | ||
types or of `std`, but today the `std` prelude is still a bit of | ||
magic. That means that non-`std` libraries are at a significant | ||
ergonomic disadvantage -- they always feel a bit "second class". | ||
|
||
* Some libraries are already following a "prelude pattern", in which | ||
they export a `prelude` module which is glob-imported by clients -- | ||
but these clients must do the import in *each* of their modules, | ||
making it not a true prelude. | ||
|
||
# Detailed design | ||
|
||
The design is a quite simple extension of the current prelude injector: | ||
|
||
* Add a `#[prelude]` attribute that can be applied to a single module | ||
at crate root to serve as a custom prelude for that crate. | ||
|
||
* Inject the public contents of the `#[prelude]` the given module as a | ||
glob in all modules defined in the crate (except for the prelude | ||
module itself). This should work via the injector that is already in place. | ||
|
||
* If the `#[prelude]` attribute does not appear, and the crate does | ||
not otherwise opt out of the standard prelude, act as if | ||
`#[prelude]` had been applied to `std::prelude::vX` where `X` is the | ||
current prelude version. | ||
|
||
By restricting the `#[prelude]` attribute to crate root, this RFC | ||
ensures that it is still straightforward to determine which names are | ||
in scope in a given source location. In particular, this determination | ||
only involves the file defining a module and the file defining the | ||
crate itself. | ||
|
||
## Library exmaple | ||
|
||
```rust | ||
// Export a prelude for clients, includes only things defined in this crate | ||
pub mod prelude { | ||
pub use my_module::{MyType, MyOtherType}; | ||
pub use my_other_module::SomeExtensionTrait; | ||
} | ||
|
||
#[prelude] | ||
mod local_prelude { | ||
pub use std::prelude::v1::*; | ||
pub use prelude::*; // use our own prelude | ||
pub use upstream_lib::prelude::* // use preludes from upstream libraries | ||
} | ||
``` | ||
|
||
## Application example | ||
|
||
```rust | ||
#[prelude] | ||
mod prelude { | ||
// std actually provides multiple preludes now | ||
pub use std::prelude::v1::*; | ||
pub use std::io::prelude:*; | ||
|
||
// use some upstream library preludes | ||
pub use my_favorite_crate::prelude::*; | ||
|
||
// ad hoc imports from upstream libs | ||
pub use another_upstream::SomeType; | ||
|
||
// local definitions | ||
pub use my_module::MyType; | ||
} | ||
``` | ||
|
||
# Drawbacks | ||
|
||
Adds a bit more complexity around name binding in Rust, in particular | ||
making it mildly less local. | ||
|
||
In an extreme case, a very large custom prelude could make it | ||
substantially harder to reason about names in practice, but that | ||
choice is made per-crate and does not affect downstream code. | ||
|
||
# Alternatives | ||
|
||
None currently proposed. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
So to use this, I have to figure out what the current "default" prelude is, somehow? I think in the absence of
no_std
, the default prelude should still be included, with this prelude being added.