-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Tracking issue for private_in_public compatibility lint. #34537
Copy link
Copy link
Closed
Labels
A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.A-type-systemArea: Type systemArea: Type systemB-unstableBlocker: Implemented in the nightly compiler and unstable.Blocker: Implemented in the nightly compiler and unstable.C-future-incompatibilityCategory: Future-incompatibility lintsCategory: Future-incompatibility lintsT-langRelevant to the language teamRelevant to the language team
Metadata
Metadata
Assignees
Labels
A-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.A-type-systemArea: Type systemArea: Type systemB-unstableBlocker: Implemented in the nightly compiler and unstable.Blocker: Implemented in the nightly compiler and unstable.C-future-incompatibilityCategory: Future-incompatibility lintsCategory: Future-incompatibility lintsT-langRelevant to the language teamRelevant to the language team
Type
Fields
Give feedbackNo fields configured for issues without a type.
Projects
Status
Idea
What is this lint about
RFC 136 describes rules for using private types and traits in interfaces of public items. The main idea is that an entity restricted to some module cannot be used outside of that module. Private items are considered restricted to the module they are defined in,
pubitems are considered unrestricted and being accessible for all the universe of crates, RFC 1422 describes some more fine-grained restrictions. Note that the restrictions are determined entirely by item's declarations and don't require any reexport traversal and reachability analysis. "Used" means different things for different entities, for example private modules simply can't be named outside of their module, private types can't be named and additionally values of their type cannot be obtained outside of their module, etc. To enforce these rules more visible entities cannot contain less visible entities in their interfaces. Consider, for example, this function:If this were allowed, then values of private type
Scould leave its module.Despite the RFC being accepted these rules were not completely enforced until #29973 fixed most of the missing cases. Some more missing cases were covered later by PRs #32674 and #31362. For backward compatibility the new errors were reported as warnings (lints). Now it's time to retire these warnings and turn them into hard errors, which they are supposed to be.
This issue also tracks another very similar lint,
pub_use_of_private_extern_crate, checking for a specific "private-in-public" situation.How to fix this warning/error
If you really want to use some private unnameable type or trait in a public interface, for example to emulate sealed traits, then there's a universal workaround - make the item public, but put it into a private inner module.
The trait
Floatis public from the private-in-public checker's point of view, because it uses only local reasoning, howeverFloatis unnameable from outside ofmand effectively private, because it isn't actually reexported frommdespite being potentially reexportable.You'll also have to manually document what kind of mystery set of arguments your public function
multiply_by_2accepts, because unnameable traits are effectively private for rustdoc.Current status
private_in_publiclint as warn-by-defaultprivate_in_publiccompatibility lint deny-by-default #34206 makes theprivate_in_publiclint deny-by-defaultprivate_in_publiccompatibility lint warn-by-default again #36270 makes theprivate_in_publiclint warn-by-default again due to relatively large amount of breakageprivate_in_publiclint deny-by-defaultprivate_in_publiclint a hard error