-
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
Private trait's methods reachable through a public subtrait #28514
Comments
cc @alexcrichton, because you've weighed in on other privacy issues |
I would personally expect a privacy error to be generated. I'm also a little surprised about how resolution allows using a method without importing the trait as well, but that may perhaps be intended behavior. cc @rust-lang/lang, @nrc triage: I-nominated |
|
I think the error here is that |
public or accessible from all the places |
I'd be fine so long as it was limited to "marked |
I am somewhat surprised, but this test case passes too. The difference here is that the type mod inner {
struct I32;
trait A {
fn a(&self) { }
}
pub trait B {
fn b(&self) { }
}
pub trait C: A + B {
fn c(&self) { }
}
impl A for I32 {}
impl B for I32 {}
impl C for I32 {} // <-- I expected an error here and on the impl of B
}
fn main() {
} |
(I'm inclined to think that the invocation |
(namely, if one changes @nikomatsakis example so that it says |
The heart of this question is what a private trait means. After some discussion in the language team, we came to the following conclusions:
There is definitely concern that people are going to be relying on this kind of setup, though also concern that they may not be getting the guarantees that they think they are. |
triage: P-high |
This variation shows how using a trait bound with fn use_c<T: C>(x: &T) {
// A is private
// B is pub, not reexported
// C : A + B is pub, reexported
x.a(); // can call
x.b(); // can call
x.c(); // ok
C::a(x); // can call
C::b(x); // can call
C::c(x); // ok
}
|
The last comment shows a regression in nightly. |
Unfortunately, the current assignee (@aturon) is out for a while, so someone else will have to look into this. |
Is this on beta/stable yet? |
The regression mentioned in this comment seems to be fixed in nightly (and never reached beta). I think it was fixed in #29325 |
@petrochenkov Are you interested in taking this on? |
@aturon |
Triage: Moving this to P-medium since nobody is working on it. cc @rust-lang/lang @petrochenkov |
also ping @jseyfried, if this is no longer an issue, could you provide a summary as to why as well? It'd be great to close out! |
@alexcrichton I believe this issue can only happen if a public trait has a private parent, which is already a |
Awesome! I @rust-lang/lang, thoughts about closing? (also applying a nomination for bringing it up) |
Switching to needstest! |
Reopening this since |
Visibility of a trait item is inherited from its trait, so the fix is to check this trait visibility every time a trait item is named. C::a(x); // ERROR, trait A is private / not accessible from here |
C::b(&0); is an orthogonal problem. C::b(&0); // ERROR no method b in the current scope EDIT: This interpretation incorrect, I didn't realize this is about |
Check privacy of trait items in all contexts Fixes rust-lang#28514 This is a sufficiently rare scenario and it's currently guarded by `private_in_public` lint, so it shouldn't be a [breaking-change] in practice.
Check privacy of trait items in all contexts Fixes #28514 This is a sufficiently rare scenario and it's currently guarded by `private_in_public` lint, so it shouldn't be a [breaking-change] in practice.
I'm not 100% sure how the privacy rules should work.
A's methods should not be callable because the trait is private, but it's reachable though the trait C that inherits A, by calling
C::a()
.B's methods are reachable the same way, even if it's marked pub but not publically reachable.
Playpen
The text was updated successfully, but these errors were encountered: