Skip to content
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 supertraits are not callable on concrete types #83882

Open
MaikKlein opened this issue Apr 5, 2021 · 4 comments
Open

Private supertraits are not callable on concrete types #83882

MaikKlein opened this issue Apr 5, 2021 · 4 comments
Labels
A-traits Area: Trait system A-visibility Area: Visibility / privacy. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@MaikKlein
Copy link
Contributor

pub mod foo {
    pub trait Foo: sealed::Bar {
        fn foo(&self) {}
    }
    mod sealed {
        pub trait Bar {
            fn bar(&self) {}
        }
    }
    impl Foo for u32 {}
    impl sealed::Bar for u32 {}
}


fn meow_dyn(f: &dyn foo::Foo) {
    f.foo();
    f.bar();
}

fn meow_static(f: impl foo::Foo) {
    f.foo();
    f.bar();
}

fn meow_u32(f: u32) {
    use foo::Foo;
    // use crate::foo::sealed::Bar;
    // ^ doesn't work because it is private
    f.foo();
    f.bar(); // Why does this error now?
}


fn main() {
    meow_static(42);
    meow_dyn(&42);
}
error[E0599]: no method named `bar` found for type `u32` in the current scope
  --> src/main.rs:30:7
   |
30 |     f.bar(); // Why does this error now?
   |       ^^^ method not found in `u32`
   |
   = help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a `use` for it:
   |
1  | use crate::foo::sealed::Bar;
   |

playground

I am reporting this because I believe this is a bug.

Both meow_dyn and meow_static type check, but calling .bar() on a concrete type is currently not possible. Is there a reason for that?

I would expect any of those two cases:

  1. meow_u32 should actually type check, and .bar() should be callable if Foo is visible, because Bar is a supertrait.
  2. Bar should not be usable in any other context, because the trait is private.

I could not find any information about this in the reference.

@MaikKlein MaikKlein added the C-bug Category: This is a bug. label Apr 5, 2021
@jonas-schievink jonas-schievink added A-traits Area: Trait system A-visibility Area: Visibility / privacy. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Apr 5, 2021
@eggyal
Copy link
Contributor

eggyal commented Apr 6, 2021

#67105 seems related.

Bar should not be usable in any other context, because the trait is private.

This is the solution proposed by rust-lang/rfcs#2845

It strikes me that this is the correct solution, but I'm struggling to cite supporting evidence.

@lcdr
Copy link

lcdr commented Apr 7, 2021

rust-lang/rfcs#2845 actually is only concerned with the case of a subtrait having an item with the same name as one in a supertrait (i.e. both Foo and Bar defining a bar method), and is unrelated here.

The real issue here is that in generics/trait objects Bar is automatically brought into scope when Foo is used, even when Bar should not be visible (and thus usable) in that context.

@eggyal
Copy link
Contributor

eggyal commented Apr 7, 2021

rust-lang/rfcs#2845 actually is only concerned with the case of a subtrait having an item with the same name as one in a supertrait (i.e. both Foo and Bar defining a bar method), and is unrelated here.

Aye, that's why I had struck out that comment. ☺️

@steffahn
Copy link
Member

steffahn commented Aug 8, 2021

This discussion on URLO today demonstrates a practical case of a public-in-private supertrait with methods that are (most likely) not intended to be exposed/callable. In my opinion, the fact that such methods are ever callable is surprising and unnecessary and should be considered a bug. We should try to detect the cases where a supertrait cannot be named through any public path (taking re-exports into consideration, etc) and exclude the methods in this case; I wouldn’t be surprised if such a change doesn’t even break any crates in practice.

cc @dtolnay to give a definitive answer on whether the methods on the “Sealed” supertrait of ryu::Float are supposed user-callable or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-traits Area: Trait system A-visibility Area: Visibility / privacy. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants