-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Check types for privacy #42125
Check types for privacy #42125
Conversation
src/librustc_privacy/lib.rs
Outdated
None | ||
} | ||
ty::TyAnon(..) => { | ||
// FIXME: How to visit `impl Trait` type? |
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 needs to be fixed.
IIRC, my attempts to visit it with TypeVisitor
either infinitely recursed or ICEd.
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.
Shouldn't impl Trait
be able to "export" private types? cc @rust-lang/lang
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.
Yes, in anonymized form, but I'm talking about preventing use of
impl PrivateTrait
^^^^^^^^^^^^
and
impl Trait<PrivateType>
^^^^^^^^^^^
here, not use of private underlying types.
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.
Oh. So using API that involves private types? The private types would show up elsewhere if they were involved. Like, using any method on Trait
would end up with that part in its Substs
.
src/librustc_privacy/lib.rs
Outdated
return true; | ||
} else if let ty::TyFnDef(..) = ty.sty { | ||
// Inherent static methods don't have self type in substs, | ||
// we have to check it additionally. |
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.
For some reason Self
for static inherent methods is not listed in substs.
IIRC, it's not the first time I see it requiring special treatment for this reason.
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.
It's not because Self
is a mere alias in them. The substitutions for impls (inherent or trait impls, but you never get the latter from type-checking, only e.g. trans or MIR inlining can see them) are literally for the <...>
in impl<...>
.
However, it's (AFAIK) impossible to access an inherent method without one of:
- method call, which means there is an expression containing the
Self
type T::method
which is sugar for<T>::method
, and the semantic version ofT
can be read (seerustdoc
andrustc_save_analysis
)
// ext::Z; // ERROR type `ext::Z` is private | ||
// ERROR type `fn(u8) -> ext::Z {ext::Z::{{constructor}}}` is private | ||
// ext::Z1; // ERROR type `fn(u8) -> ext::Z1 {ext::Z1::{{constructor}}}` is private | ||
// ext::Z1::k; // ERROR type `fn() {ext::Z1::k}` is private |
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.
Some of these cases cannot be tested until macros 2.0 are merged.
@petrochenkov I'm very excited to see this PR! I have a few questions. I think there are some key questions that we were wrestling with:
I'm sure I'll know the answers once I skim the code, but I thought it'd be helpful to try and summarize these key points so that people don't have to do so. |
Also, I think we should FCP this before we land it. I don't anticipate a lot of back-and-forth but this is basically an insta-stable language change, so I think it makes sense. |
I didn't relax the private-in-public checker yet, so these two are still errors. I'm going to send a separate PR with private-in-public changes later. That PR will certainly require an FCP, this one - I'm not so sure. My preliminary plan is that
This is a separate case unrelated to this PR and its successors, and it will continue being an error. |
Started builds for crater
|
I've started the crate builds for crater. |
Actual root regressions:
|
Analysis: Crates that have other crates dependent on them are marked with 🌳. I think it'll be okay to send PRs with fixes and/or version bumps, and then land this without additional warnings. |
what does "unfixed" mean? oh, unfixed in that crate, you mean? (i.e., not on rustc master) |
Yes |
PRs/issues are submitted to all affected crates. |
It's hard to offer a strong boundary using private types in macros anyway, because of inference leakages. Unreachable-but-public types can be used if you want to hide a type name. |
Cleanup checking of inherent static methods and fix checking of inherent associated constants Add more tests
Fix regressions after rebase
Rebased. |
📌 Commit a27f8cf has been approved by |
Check types for privacy This PR implements late post factum checking of type privacy, as opposed to early preventive "private-in-public" checking. This will allow to turn private-in-public checks into a lint and make them more heuristic-based, and more aligned with what people may expect (e.g. reachability-based behavior). Types are privacy-checked if they are written explicitly, and also if they are inferred as expression or pattern types. This PR checks "semantic" types and does it unhygienically, this significantly restricts what macros 2.0 (as implemented in #40847) can do (sorry @jseyfried) - they still can use private *names*, but can't use private *types*. This is the most conservative solution, but hopefully it's temporary and can be relaxed in the future, probably using macro contexts of expression/pattern spans. Traits are also checked in preparation for [trait aliases](#41517), which will be able to leak private traits, and macros 2.0 which will be able to leak pretty much anything. This is a [breaking-change], but the code that is not contrived and can be broken by this patch should be guarded by `private_in_public` lint. [Previous crater run](#34537 (comment)) discovered a few abandoned crates that weren't updated since `private_in_public` has been introduced in 2015. cc #34537 https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504 Fixes #30476 Fixes #33479 cc @nikomatsakis r? @eddyb
☀️ Test successful - status-appveyor, status-travis |
@rust-lang/compiler just FYI but there's 5 open regressions against beta for this PR, all linked above this comment. |
Record semantic types for all syntactic types in bodies ... and use recorded types in type privacy checking (types are recorded after inference, so there are no `_`s left). Also use `hir_ty_to_ty` for types in signatures in type privacy checking. This could also be potentially useful for save-analysis and diagnostics. Fixes #42125 (comment) r? @eddyb
Type privacy polishing Various preparations before implementing rust-lang/rfcs#2145 containing final minor breaking changes (mostly for unstable code or code using `allow(private_in_public)`). (Continuation of #42125, #44633 and #41332.) It would be good to run crater on this. r? @eddyb
This PR implements late post factum checking of type privacy, as opposed to early preventive "private-in-public" checking.
This will allow to turn private-in-public checks into a lint and make them more heuristic-based, and more aligned with what people may expect (e.g. reachability-based behavior).
Types are privacy-checked if they are written explicitly, and also if they are inferred as expression or pattern types.
This PR checks "semantic" types and does it unhygienically, this significantly restricts what macros 2.0 (as implemented in #40847) can do (sorry @jseyfried) - they still can use private names, but can't use private types.
This is the most conservative solution, but hopefully it's temporary and can be relaxed in the future, probably using macro contexts of expression/pattern spans.
Traits are also checked in preparation for trait aliases, which will be able to leak private traits, and macros 2.0 which will be able to leak pretty much anything.
This is a [breaking-change], but the code that is not contrived and can be broken by this patch should be guarded by
private_in_public
lint. Previous crater run discovered a few abandoned crates that weren't updated sinceprivate_in_public
has been introduced in 2015.cc #34537 https://internals.rust-lang.org/t/lang-team-minutes-private-in-public-rules/4504
Fixes #30476
Fixes #33479
cc @nikomatsakis
r? @eddyb