You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
pub use can reference private items in a an enclosing module #23266
pub use should not be able to make a private item public, e.g., this is illegal:
mod a {
pub use self::b::Bar; // error: type `Bar` is private
mod b {
struct Bar;
}
}
However, if the private item is in an enclosing module then this is allowed. That is wrong (I think). However, it gets more complicated depending on if the enclosing module is itself public, because there is a useful pattern where the submodule pub uses an item in the enclosing module and that does not increase its visibility. Here are the possibilities:
mod a {
struct Foo;
mod b {
pub use super::Foo; // ok - only already visible in a and sub-mods
}
}
mod c {
struct Foo;
pub mod d {
pub use super::Foo; // not ok - increases visibility to a sibling of c
}
}
pub mod e {
struct Foo;
mod f {
pub use super::Foo; // ok, but only if e does not pub use f
}
}
pub mod g {
struct Foo;
pub mod h {
pub use super::Foo; // not ok, increases visibility to the whole world
}
}
I'm not sure if we can check the third case easily (or at all). It might only be worth allowing the first case (this would break some code in the Rust repo and probably others though).
Note also that this interacts with the ban on private types in public items - this hole in visibility makes that work some times (I need to think more about that though)
Being able to access a parent's private items is an intentional part of the privacy system (you can access any private item in your ancestry). Although being able to reexport those private items may not necessarily be intended...
I think actually it is not as bad as I thought, in particular the third case is always Ok. Even if e does pub use f::Foo, then it is Ok, because Foo 'belongs' to e and e is still in control of its visibility.
So that suggests that a fairly simple rule is that it should only be allowed to pub use an enclosing module's private items from a private module.
Hmm, and now I'm not sure of the intended behaviour here. You can use pub use to expose a private item in your own module, so why not in an enclosing module? I don't think we prevent pub use anywhere more strongly than we prevent other access to private items.
I think that per RFC 136 a pub use should require that the referenced items be public.
Does that include the whole path? If so then that sounds wrong. Having to make every submodule you reexport an item from public makes it harder to hide the private interface.
I was thinking about cases with > 2 modules and I believe the rule that must hold is the same one I outline here. That is a pub use can only mention a private item if there is a private module between the item and the pub use.
In this case, there is also a simpler (and more conservative) model, which is that pub use can only mention public items.
Activity
nrc commentedon Mar 10, 2015
triage: I-nominated (1.0 beta)
back-compat issue
alexcrichton commentedon Mar 11, 2015
Being able to access a parent's private items is an intentional part of the privacy system (you can access any private item in your ancestry). Although being able to reexport those private items may not necessarily be intended...
nrc commentedon Mar 11, 2015
Yeah, the title is not very clear, sorry, but it is the re-export part that I think is the bug, not the access.
nrc commentedon Mar 11, 2015
I think actually it is not as bad as I thought, in particular the third case is always Ok. Even if
edoespub use f::Foo, then it is Ok, becauseFoo'belongs' toeandeis still in control of its visibility.So that suggests that a fairly simple rule is that it should only be allowed to pub use an enclosing module's private items from a private module.
nrc commentedon Mar 11, 2015
Hmm, and now I'm not sure of the intended behaviour here. You can use
pub useto expose a private item in your own module, so why not in an enclosing module? I don't think we preventpub useanywhere more strongly than we prevent other access to private items.nrc commentedon Mar 11, 2015
Note that this issue is consistent with RFC 136 (i.e., under that RFC, the current implementation is wrong).
pnkfelix commentedon Mar 11, 2015
cc me
nrc commentedon Mar 11, 2015
Note that currently you can
pub useyour own private members, that might be a bug too. E.g.,nikomatsakis commentedon Mar 11, 2015
I think that per RFC 136 a pub use should require that the referenced items be public.
nikomatsakis commentedon Mar 11, 2015
(Whether or not they are in your module, a parent's module, etc)
nikomatsakis commentedon Mar 11, 2015
At least that was the intended semantics.
mahkoh commentedon Mar 12, 2015
Does that include the whole path? If so then that sounds wrong. Having to make every submodule you reexport an item from public makes it harder to hide the private interface.
nrc commentedon Mar 12, 2015
@mahkoh No, it means literally just that the item must be public
nrc commentedon Mar 12, 2015
I was thinking about cases with > 2 modules and I believe the rule that must hold is the same one I outline here. That is a
pub usecan only mention a private item if there is a private module between the item and thepub use.In this case, there is also a simpler (and more conservative) model, which is that
pub usecan only mention public items.Merge pull request rust-lang#23266 from BenjaminBrienen/const-label-d…