Skip to content

Inconsistent privacy of methods of orphan non-trait impls #16398

Description

@huonw
mod foo {
    pub struct Foo;
    impl Foo {
        pub fn normal(&self) {
            self.private();
            self.public();
        }
    }
    mod bar {
        impl super::Foo {
            fn private(&self) {}
            pub fn public(&self) { self.private() }
        }
    }
}

fn main() {
    foo::Foo.normal();
    foo::Foo.private();
    foo::Foo.public();
}

Compilation fails with

<anon>:5:13: 5:27 error: method `private` is private
<anon>:5             self.private();
                     ^~~~~~~~~~~~~~
<anon>:19:5: 19:23 error: method `private` is private
<anon>:19     foo::Foo.private();
              ^~~~~~~~~~~~~~~~~~

(Removing those two .private calls compiles fine.)

This is inconsistent because:

  • private is only accessible inside bar, i.e. being private means it is being scoped with the module
  • public is accessible everywhere despite bar being private (if it were a freestanding function, one could only call foo::bar::public inside foo, not inside main); i.e. it appears to be being scoped with the type

I would expect both pub and non-pub methods to have the same scoping either both with the type (so foo and any descendants can call private, as well as main calling public), or both with the module (so main cannot call public).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-visibilityArea: Visibility / privacy

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions