Skip to content

Lint unused pub items in binary crates#149509

Open
mu001999 wants to merge 4 commits intorust-lang:mainfrom
mu001999-contrib:flag/pub-as-pub-crate
Open

Lint unused pub items in binary crates#149509
mu001999 wants to merge 4 commits intorust-lang:mainfrom
mu001999-contrib:flag/pub-as-pub-crate

Conversation

@mu001999
Copy link
Copy Markdown
Member

@mu001999 mu001999 commented Dec 1, 2025

View all comments

This PR adds a new unstable flag -Ztreat-pub-as-pub-crate as @Kobzol suggested.
When compiling binary crates with this flag, the seed worklist will only contain the entry fn and won't contain other reachable items. Then we can do the dead code analysis for pub items just like they are pub(crate).

Related zulip thread #general > pub/pub(crate) within a binary is a footgun.


Updated:

Adds a new lint unused_pub_items_in_binary (crate-level, default allow for now) instead of the previous unstable flag to lint unused pub items for binary crates.

See more in #149509 (comment).

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Dec 1, 2025
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Dec 1, 2025

r? @jdonszelmann

rustbot has assigned @jdonszelmann.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@mu001999 mu001999 changed the title Add new unstable flag -Ztreat-pub-as-pub-crate Add new unstable flag -Ztreat-pub-as-pub-crate Dec 1, 2025
@mu001999 mu001999 changed the title Add new unstable flag -Ztreat-pub-as-pub-crate Add a new unstable flag -Ztreat-pub-as-pub-crate Dec 1, 2025
@Noratrieb
Copy link
Copy Markdown
Member

Noratrieb commented Dec 1, 2025

What are the plans for this flag? Being made the default? As just a flag, it's essentially useless, because no one will know about it. So I'd be opposed to just adding it without any plan for making it useful for everyone.

@mu001999 mu001999 marked this pull request as draft December 2, 2025 01:13
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 2, 2025
@mu001999 mu001999 force-pushed the flag/pub-as-pub-crate branch 2 times, most recently from 6541f80 to 8ac52ba Compare December 2, 2025 02:12
@mu001999 mu001999 marked this pull request as ready for review December 2, 2025 02:13
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Dec 2, 2025
@mu001999
Copy link
Copy Markdown
Member Author

mu001999 commented Dec 2, 2025

Maybe this could be a separate lint, I haven't thought too clearly yet

@jdonszelmann
Copy link
Copy Markdown
Contributor

Yea I do agree with nora here, maybe open a (specific) zulip thread to make a proper plan for this?

@jdonszelmann
Copy link
Copy Markdown
Contributor

I guess I'd prefer this as a lint (attribute at the crate root) myself

@jdonszelmann
Copy link
Copy Markdown
Contributor

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Dec 3, 2025
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Dec 3, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@mu001999 mu001999 marked this pull request as draft December 3, 2025 14:34
@Kobzol
Copy link
Copy Markdown
Member

Kobzol commented Dec 3, 2025

I guess that the use-case that I'm envisioning is to have an opt-in way to treat pub stuff as pub(crate) in binary crates. If it was an allow-by-default lint, which could be manually denied, that would serve that use-case, I think.

@GrantGryczan
Copy link
Copy Markdown

Why would the end goal be for this to be opt-in? I and others want to see #74970 become a default. I wouldn't opt into this, because that would make my codebase less idiomatic, diverging from how everyone else who hasn't opted in uses pub.

The reason this is useful as a default is because it doesn't semantically make sense to distinguish between pub and pub(crate) in binary crates. This creates a footgun because, for example, pub items can't receive dead_code warnings. If it's just opt-in, then that doesn't remove the footgun for anyone who hasn't opted in, and I don't see a benefit to pub and pub(crate) being distinct in binary crates.

The only reason I can see that someone might not want to opt into this is that one might use pub to prevent dead_code warnings as opposed to pub(crate). But I think this intent might be better communicated using #[expect(dead_code)] rather than the implicit behavior of pub. Dead code detection is useful as a default. (The only downside to that is that you then have to remove the #[expect(dead_code)] if you later use it, but I'll leave it to others to decide if that coupling is an important consideration.)

@mu001999 mu001999 force-pushed the flag/pub-as-pub-crate branch from 8ac52ba to 923596e Compare December 28, 2025 15:22
@mu001999 mu001999 force-pushed the flag/pub-as-pub-crate branch from 923596e to 1d89354 Compare March 19, 2026 12:06
@rust-log-analyzer

This comment has been minimized.

@mu001999 mu001999 force-pushed the flag/pub-as-pub-crate branch from 1d89354 to e116866 Compare March 19, 2026 13:41
@mu001999 mu001999 force-pushed the flag/pub-as-pub-crate branch from ab9fe41 to 64d40ef Compare April 14, 2026 01:24
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Apr 14, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@mu001999
Copy link
Copy Markdown
Member Author

@rustbot label -S-blocked +S-waiting-on-t-lang

@rustbot rustbot added S-waiting-on-t-lang Status: Awaiting decision from T-lang and removed S-blocked Status: Blocked on something else such as an RFC or other implementation work. labels Apr 14, 2026
/// This lint only applies to executable crates. In library crates, public
/// items are considered part of the crate's API and are not reported by
/// this lint.
pub UNUSED_PUB_ITEMS_IN_BINARY,
Copy link
Copy Markdown
Contributor

@traviscross traviscross Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub UNUSED_PUB_ITEMS_IN_BINARY,
pub UNUSED_PUB_IN_BINARY,

In keeping with the RFC 0344 guidance, I might call this unused_pub_in_binary.

  • Lints that apply to arbitrary items (like the stability lints) should just mention what they check for: use deprecated rather than deprecated_items. This keeps lint names short. (Again, think "allow lint-name items".)

View changes since the review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming this is something like “dead_code but marking pub doesn’t count as usage”, I wonder if the name should be related to the name of the dead_code lint, like… public_dead_code_in_binary or something 🤔

Copy link
Copy Markdown

@GrantGryczan GrantGryczan Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name "unused pub" makes me think the pub keyword is unused, not the item it's on.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Apr 15, 2026
@traviscross
Copy link
Copy Markdown
Contributor

We talked about this in the lang meeting today. Let's do this under the name unused_pub_in_binary.

@rfcbot fcp merge lang

@rust-rfcbot
Copy link
Copy Markdown
Collaborator

rust-rfcbot commented Apr 15, 2026

Team member @traviscross has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Apr 15, 2026
@joshtriplett
Copy link
Copy Markdown
Member

@rfcbot reviewed

Looking forward to this, thank you @mu001999!

@nikomatsakis
Copy link
Copy Markdown
Contributor

@rfcbot reviewed

@rust-rfcbot rust-rfcbot added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. labels Apr 15, 2026
@rust-rfcbot
Copy link
Copy Markdown
Collaborator

🔔 This is now entering its final comment period, as per the review above. 🔔

@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. and removed I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-easy-decision Issue: The decision needed by the team is conjectured to be easy; this does not imply nomination P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang labels Apr 15, 2026
@tmandry
Copy link
Copy Markdown
Member

tmandry commented Apr 15, 2026

Can you add a test to verify that this doesn't activate on #[no_mangle] items? There are use cases for an a public #[no_mangle] function being called from a library, and the existing dead code lint doesn't activate on these functions.

@joshtriplett
Copy link
Copy Markdown
Member

Also, @mu001999, could you please confirm that this is in the unused group so that allow(unused) disables it?

@mu001999
Copy link
Copy Markdown
Member Author

mu001999 commented Apr 15, 2026

Can you add a test to verify that this doesn't activate on #[no_mangle] items? There are use cases for an a public #[no_mangle] function being called from a library, and the existing dead code lint doesn't activate on these functions.

@tmandry Sure, I will add tests for such cases. Thanks for the reminder :)

@mu001999
Copy link
Copy Markdown
Member Author

mu001999 commented Apr 15, 2026

Also, @mu001999, could you please confirm that this is in the unused group so that allow(unused) disables it?

@joshtriplett Nop, this lint is not in the unused group. This is crate_level_only for now, so this will be conflict with unused. And the default level is Allow right now.

If we add this into the unused group, we need to make it not crate_level_only at least. This change will require more work.

@GrantGryczan
Copy link
Copy Markdown

GrantGryczan commented Apr 15, 2026

If this isn't warn by default, my and Noratrieb's prior concerns remain unaddressed.

@mu001999
Copy link
Copy Markdown
Member Author

If this isn't warn by default, my and Noratrieb's prior concerns remain unaddressed.

Yes, but I hope we can add the implementation of this lint firstly. And then someone could use it, I believe this has been better than the unstable flag.

Making it warn-by-default will lead to a lot of noise for this PR (like bless many tests). So I'd like to make it warn-by-default in a separate PR in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. S-waiting-on-t-lang Status: Awaiting decision from T-lang T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.