-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
resolve: Minimize hacks in name resolution of primitive types #32131
Conversation
LGTM, but I'd like to see a decision from @rust-lang/lang. |
Looks good to me, +1 for this change. I'm having trouble seeing why this isn't backwards compatible -- @petrochenkov can you come up with an example that breaks? |
// use std::u8; // bring module u8 in scope | ||
// fn f() -> u8 { // OK, resolves to primitive u8, not to std::u8 | ||
// u8::MAX // OK, resolves to associated constant <u8>::MAX, | ||
// // not to non-existent std::u8::MAX |
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 believe this resolves to ::std::u8::MAX
; MAX
is not an associated const of <u8>
.
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'll fix the example
For some reason I thought extern crates have their own (The changes to prelude will require a crater run though, but I've not included them in this PR) |
Excellent. I can't think of any other reason to continue disallowing types that would shadow primitive types.
The prelude is shadowable by everything else, so I think it would be backwards compatible to add to the prelude for all code that doesn't manually import the prelude. |
@petrochenkov What would you think about moving to disallow modules that shadow primitive types? Then, once associated consts stabilize, we could make Without modules that shadow primitive types, I believe this change would be backwards compatible (except for |
"Numeric" modules are more or less fixable if associated constants are improved, but we also have http://doc.rust-lang.org/nightly/std/str/... |
Ok, but
|
Nominated for discussion at next lang team meeting. |
On Wed, Mar 09, 2016 at 12:51:41AM -0800, Jeffrey Seyfried wrote:
I do hope we will do this eventually; I think making imports of associated items work would be a pre-req to doing such a change. |
Is another way to view "no implicit prelude" as actually giving you a smaller prelude, that just contains the builtin numeric types? Also, I think we could get away with retroactively feature-gating no-implicit-prelude, which seems like something we did not mean to stabilize. |
Sorry, I haven't answered to this.
should give an error message "S is a module and not a type" and not "type name |
+1
With prelude changes from #32167 the fallback implemented in this PR starts looking like kind of a small lower priority prelude hardcoded in the resolve (except for "legacy" module shadowing) :) |
@nikomatsakis yeah, I think that is a good way to view
I really like this idea! I think we could take this further by including the primitive type modules in the prelude, only allowing primitive types to be used via a
|
Finally, we could avoid any immediate breakage with a warning cycle, something like: mod u8 {}
fn f(_: u8) {}
//~^ WARN the type `u8` is shadowed by the user-defined module `::u8`, use `::std::u8` instead |
I'm not sure removing primitive types together with the main prelude is practical. I need to experiment with
I suspect this will turn out to be much larger hack, then the current fallback. |
I think of it as less of a hack if the semantics are cleaner (which I believe they would be). Also, the current implementation can be so simple only because |
@jseyfried |
Completely agree. In the mean time, perhaps we could leverage the existing prelude injection by adding a private module mod std {
pub use prelude; // i.e. `libcore`'s prelude
} and enabling ordinary prelude injection in |
☔ The latest upstream changes (presumably #32182) made this pull request unmergeable. Please resolve the merge conflicts. |
I've implemented Primitive types are bound to items in cc @eddyb, you wanted to do this looong time ago |
Nice! I definitely like the result. |
How about |
For documentation purpose only (the item body is ignored) or rust-lang/rfcs#348?
Ok, I'll fix the |
⌛ Testing commit b418cd2 with merge ab13e5a... |
⛄ The build was interrupted to prioritize another pull request. |
⌛ Testing commit b418cd2 with merge 1ab7b62... |
⛄ The build was interrupted to prioritize another pull request. |
⌛ Testing commit b418cd2 with merge 5b39678... |
⛄ The build was interrupted to prioritize another pull request. |
⌛ Testing commit b418cd2 with merge c10b1e9... |
⛄ The build was interrupted to prioritize another pull request. |
Module experiments: Add one more prelude layer for extern crate names passed with `--extern` Implements one item from https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678/183 When some name is looked up in lexical scope (`name`, i.e. not module-relative scope `some_mod::name` or `::name`), it's searched roughly in the next order: - local variables - items in unnamed blocks - items in the current module - ✨ NEW! ✨ crate names passed with `--extern` ("extern prelude") - standard library prelude (`Vec`, `drop`) - language prelude (built-in types like `u8`, `str`, etc) The last two layers contain a limited set of names controlled by us and not arbitrary user-defined names like upper layers. We want to be able to add new names into these two layers without breaking user code, so "extern prelude" names have higher priority than std prelude and built-in types. This is a one-time breaking change, that's why it would be nice to run this through crater. Practical impact is expected to be minimal though due to stylistic reasons (there are not many `Uppercase` crates) and due to the way how primitive types are resolved (#32131).
Module experiments: Add one more prelude layer for extern crate names passed with `--extern` Implements one item from https://internals.rust-lang.org/t/the-great-module-adventure-continues/6678/183 When some name is looked up in lexical scope (`name`, i.e. not module-relative scope `some_mod::name` or `::name`), it's searched roughly in the next order: - local variables - items in unnamed blocks - items in the current module - ✨ NEW! ✨ crate names passed with `--extern` ("extern prelude") - standard library prelude (`Vec`, `drop`) - language prelude (built-in types like `u8`, `str`, etc) The last two layers contain a limited set of names controlled by us and not arbitrary user-defined names like upper layers. We want to be able to add new names into these two layers without breaking user code, so "extern prelude" names have higher priority than std prelude and built-in types. This is a one-time breaking change, that's why it would be nice to run this through crater. Practical impact is expected to be minimal though due to stylistic reasons (there are not many `Uppercase` crates) and due to the way how primitive types are resolved (#32131).
When resolving the first unqualified segment in a path with
n
segments andn - 1
associated item segments, e.g. (a
ora::assoc
ora::assoc::assoc
etc) try to resolvea
without considering primitive types first. If the "normal" lookup fails or results in a module, then try to resolvea
as a primitive type as a fallback.This way backward compatibility is respected, but the restriction from E0317 can be lifted, i.e. primitive names mostly can be shadowed like any other names.
Furthermore, if names of primitive types are put into prelude (now it's possible to do), then most of names will be resolved in conventional way and amount of code relying on this fallback will be greatly reduced. Although, it's not entirely convenient to put them into prelude right now due to temporary conflicts like
use prelude::v1::*; use usize;
in libcore/libstd, I'd better wait for proper glob shadowing before doing it.I wish the
no_prelude
attribute were unstable as intended :(cc @jseyfried @arielb1
r? @eddyb