-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
unreachable-pub
lint (as authorized by RFC 2126)
#45569
Conversation
src/libcore/fmt/builders.rs
Outdated
pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, | ||
name: &str) | ||
-> DebugStruct<'a, 'b> { | ||
pub(crate) fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, |
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'd avoid changing libcore until the crate
sugar for pub(crate)
is available in bootstrap compiler.
src/librustc_lint/builtin.rs
Outdated
|
||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnexportedPub { | ||
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { | ||
if !cx.access_levels.is_exported(item.id) && item.vis == hir::Visibility::Public { |
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.
As I mentioned on gitter, this should use is_reachable
instead of is_exported
.
With is_exported
this lint will give false positives on anything that is leaked through any other means than use
(type aliases, return types, field types). All these things still need to be pub
to be usable from other crates.
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.
Test to add:
mod m {
pub struct S; // The lint should not fire on this struct
}
pub fn f() -> m::S { m::S }
src/librustc_lint/builtin.rs
Outdated
pub struct UnexportedPub; | ||
|
||
declare_lint! { | ||
UNEXPORTED_PUB, |
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'd actually rename the lint into unreachable_pub
(+ update all the comments, etc).
src/librustc_lint/builtin.rs
Outdated
if !cx.access_levels.is_exported(item.id) && item.vis == hir::Visibility::Public { | ||
let mut err = cx.struct_span_lint(UNEXPORTED_PUB, item.span, "unexported `pub` item"); | ||
err.help("consider exporting it for use by other crates"); | ||
// `pub` is three chars at start of declaration |
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.
This is a bold claim!
pub
can be passed to an item through a $vis
matcher, for example.
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.
Could you add a test for this case? Something like
mod m {
macro_rules! m {
($visibility: vis) => { $visibility struct S; }
}
m!(pub);
}
src/librustc_lint/builtin.rs
Outdated
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { | ||
if !cx.access_levels.is_exported(item.id) && item.vis == hir::Visibility::Public { | ||
let mut err = cx.struct_span_lint(UNEXPORTED_PUB, item.span, "unexported `pub` item"); | ||
err.help("consider exporting it for use by other crates"); |
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.
Looking at the tests, "or consider exporting it for use by other crates" would look better.
src/librustc_lint/builtin.rs
Outdated
} | ||
|
||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnexportedPub { | ||
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { |
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.
check_item
doesn't cover pub
on impl items, foreign items and struct fields.
src/librustc_lint/builtin.rs
Outdated
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnexportedPub { | ||
fn check_item(&mut self, cx: &LateContext, item: &hir::Item) { | ||
if !cx.access_levels.is_exported(item.id) && item.vis == hir::Visibility::Public { | ||
let mut err = cx.struct_span_lint(UNEXPORTED_PUB, item.span, "unexported `pub` item"); |
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.
def_span
will probably look better here (see an example of use in #44847)
2e7a731
to
7edd04d
Compare
updated (force-push) |
unexported-pub
lint (as authorized by RFC 2126)unreachable-pub
lint (as authorized by RFC 2126)
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.
Could you do a squash of your commits while you're at it?
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
#![feature(crate_visibility_modifier)] |
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.
Could you add a test without this feature enabled to make sure there're no regressions going forward with the pub(crate)
suggestion?
r=me with @estebank's comment (#45569 (comment)) addressed |
This is with deepest thanks to Vadim Petrochenkov for thorough review, and resolves rust-lang#45521.
7edd04d
to
085ec6d
Compare
(added non- |
@bors r+ |
📌 Commit 085ec6d has been approved by |
⌛ Testing commit 085ec6d with merge 9140b5dc5dc016024470e9ab1139c8a86cfec4b8... |
💔 Test failed - status-travis |
@bors retry |
`unreachable-pub` lint (as authorized by RFC 2126) To whom it may concern: RFC 2126 commissions the creation of a lint for `pub` items that are not visible from crate root (#45521). We understand (but seek confirmation from more knowledgable compiler elders) that this can be implemented by linting HIR items that are _not_ ~~`cx.access_levels.is_exported`~~ `cx.access_levels.is_reachable` but have a `vis` (-ibility) field of `hir::Visibility::Public`. The lint, tentatively called ~~`unexported-pub`~~ `unreachable-pub` (with the understanding that much could be written on the merits of various names, as it is said of the colors of bicycle-sheds), suggests `crate` as a replacement for `pub` if the `crate_visibility_modifier` feature is enabled (see #45388), and `pub(crate)` otherwise. We also use help messaging to suggest the other potential fix of exporting the item; feedback is desired as to whether this may be confusing or could be worded better. As a preview of what respecting the proposed lint would look like (and to generate confirmatory evidence that this implementation doesn't issue false positives), ~~we take its suggestions for `libcore`~~ (save one, which is deferred to another pull request because it brings up an unrelated technical matter). I remain your obedient servant. ![unexported_pub](https://user-images.githubusercontent.com/1076988/32089794-fbd02420-baa0-11e7-87e5-3ec01f18924a.png) r? @petrochenkov
☀️ Test successful - status-appveyor, status-travis |
…hton regenerate libcore/char_private.rs (filed separately from the work in #45569, because of this matter of the updated Unicode data; see also #45567) char_private.rs is generated programmatically by char_private.py, using data retrieved from the Unicode Consortium's website. The motivation here was to make `is_printable` crate-visible (with `pub(crate)`), but it would seem that the Unicode data has changed slightly since char_private.rs was last generated.
To whom it may concern:
RFC 2126 commissions the creation of a lint for
pub
items that are not visible from crate root (#45521). We understand (but seek confirmation from more knowledgable compiler elders) that this can be implemented by linting HIR items that are notcx.access_levels.is_exported
cx.access_levels.is_reachable
but have avis
(-ibility) field ofhir::Visibility::Public
.The lint, tentatively called
unexported-pub
unreachable-pub
(with the understanding that much could be written on the merits of various names, as it is said of the colors of bicycle-sheds), suggestscrate
as a replacement forpub
if thecrate_visibility_modifier
feature is enabled (see #45388), andpub(crate)
otherwise. We also use help messaging to suggest the other potential fix of exporting the item; feedback is desired as to whether this may be confusing or could be worded better.As a preview of what respecting the proposed lint would look like (and to generate confirmatory evidence that this implementation doesn't issue false positives),
we take its suggestions for(save one, which is deferred to another pull request because it brings up an unrelated technical matter). I remain your obedient servant.libcore
r? @petrochenkov