Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upItems shadow glob-imported reexports #31337
Comments
jseyfried
changed the title
Items can be shadowed by glob-imported reexports
Items shadow glob-imported reexports
Feb 1, 2016
This comment has been minimized.
This comment has been minimized.
Seems like an unfinished sentence? |
This comment has been minimized.
This comment has been minimized.
|
I think there are two reasonable ways to fix this: |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I think it was intentional for non-glob items (whether declared there or via imports) to be able to override glob imports and I'd rather keep it that way. |
This comment has been minimized.
This comment has been minimized.
|
My opinion here is that we should allow local items to shadow glob imported items, otherwise adding an item to the upstream module can break the downstream one, and it is fairly clear that local declarations should have priority (I'm less sure about glob and non-glob imports, I like the idea that we can have multiple imports if they import the same item or the import is not used, but re-exports must count as 'used', so I'm not sure there). Anyway, this is basically arguing for option 2 - fix the docs. |
This comment has been minimized.
This comment has been minimized.
|
@nrc Ok, I agree that glob imported items should be shadowable. mod foo {
mod bar { pub struct Bar; }
pub use self::bar::Bar;
}
pub use foo::*; // This defines Bar in both namespaces
pub fn Bar() {} // This shadows the old definition in the value namespace
fn main() {
Bar; // This refers to the shadowing function
fn g(_b: Bar) {} // This refers to the struct, since it was not shadowed in the type namespace
}When generating the documentation for this example, would we list the struct Bar and the function Bar? That seems like it would cause confusion, since the constructor for the struct is not in fact exported. We could instead not list the struct at all and disallow use of the type Bar from outside of the crate but continue allowing it within the crate. Finally, we could disallow use of the type Bar inside and outside the crate, i.e. we could have the function shadow the struct in both namespaces, effectively "undefining" Bar in the type namespace. |
This comment has been minimized.
This comment has been minimized.
|
I think that we should at least lint against this, if not forbid it out right (i.e., make it an error to shadow one namespace but not the other, when the items in the same namespace are 'linked'). This means making a connection between the two |
This comment has been minimized.
This comment has been minimized.
|
This is unfortunate. |
This comment has been minimized.
This comment has been minimized.
|
I think we should revert the change, even though I prefer the shadowing semantics in the long term. Basically, I think we ought to do an RFC that describes this change, in addition to incorporating the more general work we've been planning on macro and name resolution. |
This comment has been minimized.
This comment has been minimized.
|
Also, the question of multiple namespaces is an important one. I think it came up in the revised name resolution algorithm I was planning -- though I didn't extend my latest prototype to cover multiple paths, so maybe I am remembering details from an older version. But I remember thinking that there are some somewhat subtle interactions arising there. Ah, I sort of remember now. The problem was I think specific to my older, monotonic variants, where we had to know whether (Sorry, these comments are kind of rambly, but for context, I am discussing the algorithm here https://github.com/nikomatsakis/rust-name-resolution-algorithm.) |
This comment has been minimized.
This comment has been minimized.
I'd prefer non-glob imports to behave exactly like other items, i.e. they cannot have name conflicts, are visible from other modules even when private, can shadow glob imports etc. This give us one simple scheme which is easy to teach and contains no surprises. (Yes, it could be useful sometimes to import the same thing twice in macros, but it's not a great loss IMO, we don't have it now and I haven't seem complaints so far.) |
steveklabnik
added
the
A-lang
label
Feb 2, 2016
This was referenced Feb 3, 2016
This comment has been minimized.
This comment has been minimized.
|
The above PRs are implementations of the two fixes I proposed earlier. |
This comment has been minimized.
This comment has been minimized.
|
@nrc Furthermore, to fix the lint, one would have to define an unused dummy item to shadow the other namespace (which would be tempting, but ugly), or one would have to rename the shadowing item or refactor the glob import into single imports, which would defeat the purpose of glob shadowing. |
This comment has been minimized.
This comment has been minimized.
|
@petrochenkov @nikomatsakis |
This comment has been minimized.
This comment has been minimized.
|
One of the larger things is actually |
This comment has been minimized.
This comment has been minimized.
|
@jseyfried sorry, I'm maybe a bit confused. I thought we DID forbid shadowing now? Are we just inconsistent about it? |
This comment has been minimized.
This comment has been minimized.
|
On Tue, Feb 02, 2016 at 08:22:44PM -0800, Peter Atashian wrote:
I think everyone agrees this is the semantics we eventually want. |
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis We have been allowing local items to shadow glob-imported re-exports for a long time. Before #30843, the shadowed glob-imported re-export was visible to users of the crate and the local item was not, so that from the perspective of users of the crate, the glob-imported re-export shadowed the local item. After #30843, the local item shadows the glob-imported re-export both inside and outside the crate. The issue here is that when documenting a crate, we include both the shadowed glob-imported re-export and the local item (provided they are both public, of course). This is easy to fix in the case of a function shadowing a function for example (just don't report the shadowed function). It's trickier, however, if (say) a tuple struct is shadowed by a function. I described some options of what to do in this case in this comment and advocated for my preferred solution in this comment. |
This comment has been minimized.
This comment has been minimized.
|
I see. I got confused. That does affect my opinion -- it's clear that On Wed, Feb 3, 2016 at 8:29 PM, Jeffrey Seyfried notifications@github.com
|
nikomatsakis
added
the
I-nominated
label
Feb 11, 2016
This comment has been minimized.
This comment has been minimized.
|
Nominating for discussion in the lang team meeting. |
nikomatsakis
added
the
T-lang
label
Feb 11, 2016
This comment has been minimized.
This comment has been minimized.
I strongly agree with this sentiment. Shadowing is what we want here in the long run, and it doesn't make sense to me to break code that's using it, only to more completely implement shadowing later on. |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
We discussed this in the @rust-lang/lang meeting. The conclusion was that we should adopt @jseyfried's "option 2":
Specifically, we do eventually want shadowing semantics, and therefore it doesn't make sense to regress crates that are taking advantage of it, even if the current support is a bug. |
This comment has been minimized.
This comment has been minimized.
|
Ok, sounds good. |
This comment has been minimized.
This comment has been minimized.
|
@jseyfried Are talking about Rustdoc? I think listing a struct when it is only exported in a single namespace is OK (better than not listing it, since it is in fact exported in some sense). Perhaps adding notes for such situations would be nice. |
This comment has been minimized.
This comment has been minimized.
|
By the way, what will happen with half-shadowed items in cross-crate scenarios? |
This comment has been minimized.
This comment has been minimized.
|
@nrc Yeah, I was talking about Rustdoc. Thinking about this some more, I agree that it is OK to list a partially shadowed struct -- it looks like it would be very uncommon in the wild and we already have far more common cases of unnameable paths in rustdoc thanks to the distinction between visibility and nameability. @petrochenkov Indeed, except they will be predictably ignored -- items are listed before re-exports in metadata so that when there is a conflict between an item and an import, the item will always win. This probably isn't the most elegant solution but it works for now. |
This comment has been minimized.
This comment has been minimized.
Well, at least it doesn't depend on the phase of the moon. |
nikomatsakis
removed
the
I-nominated
label
Mar 10, 2016
bors
added a commit
that referenced
this issue
Apr 13, 2016
Ryman
referenced this issue
Jul 16, 2016
Closed
rustdoc prioritises documenting reexports from the type namespace #34843
petrochenkov
referenced this issue
Sep 17, 2016
Merged
Refactor away RBML from rustc_metadata. #36551
petrochenkov
referenced this issue
Sep 29, 2016
Merged
Refactoring/bugfixing around definitions for struct/variant constructors #36814
bors
added a commit
that referenced
this issue
Oct 4, 2016
This comment has been minimized.
This comment has been minimized.
|
This was fixed by stabilizing RFC 1560. |
jseyfried commentedFeb 1, 2016
For example,
Also, considering the above example as a crate, the glob import used to shadow the item from the perspective of users of the crate before #30843. After #30843, the item shadows the glob import both inside and outside the crate. I can easily revert that breaking change if desired (crater found no breakage in practice).
Finally, in the generated documentation for the crate,
fis listed twice, both times as the glob imported version, i.e. the glob import still shadows the item in the crate documentation.