Skip to content

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

Closed
@huonw

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).

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