# The future of privacy and encapsulation

**URL:** <https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961>\
**Category:** language design\
**Created:** [December 4, 2015, 8:15pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961 "2015-12-04T20:15:36Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![bluss](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bluss/32/2264_2.png) [@bluss](https://internals.rust-lang.org/u/bluss)\
**Post date:** [December 4, 2015, 8:15pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/1 "2015-12-04T20:15:36Z")

</div>

This is related to a design question I have in the [user space.](https://users.rust-lang.org/t/hiding-implementation-details-for-a-type-with-switchable-strategy/3865)

Traits are great for open interfaces, but how to use them for a closed set of possibilities?

In current Rust, I can find only one model to hide implementation details in my scenario, abusing a Private supertrait. Rust is marching towards progress, and this bug [will be fixed](https://github.com/rust-lang/rust/pull/29973) eventually. _(Edit: See below, maybe this case is not a bug)_

Judging from the PR, lots of crates prefer to keep implementation details private, sometimes it’s really unfortunate when they have to be public.

- [cgmath keeps a private trait](https://github.com/bjz/cgmath-rs/blob/master/src/angle.rs#L57-L63)
- [peano keeps a private trait](https://github.com/paholg/peano/blob/8c20b992ec7309b7f0ac11bd3dbb4fec38317cac/src/lib.rs#L280-L301)
- [dbus](https://github.com/diwic/dbus-rs/blob/73a47eb0a979e413212aacf56c33619473fa33ea/src/methoddisp.rs#L91-L95)
- [rand-distributions](https://github.com/GrahamDennis/distributions-rs/blob/f418980949d920799d5b27f3b74fdc42cfc889d2/src/uniform_range.rs#L9-L15)

```rust
// Marker types A and B
pub enum A { }
pub enum B { }

pub trait Marker: PrivateMarker { }
impl Marker for A { }
impl Marker for B { }

// Problem: How to use only the bound M: Marker,
// but still use a private trait implemented by A and B?

mod internal {
    // The privatemarker trait is private --
    // we want full freedom in changing the implementation details.
    pub trait PrivateMarker {
        fn private();
    }
}

use internal::PrivateMarker;

```

[Rust Playground Link](https://play.rust-lang.org/?gist=9f597e13fcfa347c735d&version=nightly)

Is there a language feature on the horizon to help with this? I’m not sure specialization covers it; in this case we just want to close the trait to implementors `A` and `B`, and that’s it.

I don’t think there is a fundamental problem in a public trait that can’t be implemented by the user. Traits have many different roles, and this is a role I’d like them to fill better; API flexibility _without_ being open for extension.

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [December 4, 2015, 8:55pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/2 "2015-12-04T20:55:43Z")

</div>

Do you want the trait to be private for a crate or for a module?

In the first case private inner module solves the problem - the trait inside it will be unnameable and therefore unimplementable for other crates.

As for the second case, private traits without associated types (and without supertraits with associated types) potentially can be permitted in bounds in public interfaces. I’m pretty sure they can’t leak anything private, only cause dead links in rustdoc.

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [December 4, 2015, 9:15pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/3 "2015-12-04T21:15:39Z")

</div>

Currently, I believe the following works (until specialization, that is…):

```rust
pub trait PrivateMarker {}
trait NoImpl {}
impl<T> PrivateMarker for T where T: NoImpl {}

pub trait Test: PrivateMarker { }
impl Test for () {}
// Coherence guarantees that this can only be
// implemented in this crate.
impl PrivateMarker for () {}

```

Regardless, this is a hack. I’d like a way to mark a trait as closed (shared code only).

---

<div class="post-metadata">

**Author:** ![bluss](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bluss/32/2264_2.png) [@bluss](https://internals.rust-lang.org/u/bluss)\
**Post date:** [December 4, 2015, 10:01pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/4 "2015-12-04T22:01:04Z")

</div>

> [@petrochenkov](#):
>
> In the first case private inner module solves the problem - the trait inside it will be unnameable and therefore unimplementable for other crates.

Isn't this one of the cases that will be disallowed? If not, that's great news!

---

<div class="post-metadata">

**Author:** ![petrochenkov](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/petrochenkov/32/2784_2.png) [@petrochenkov](https://internals.rust-lang.org/u/petrochenkov)\
**Post date:** [December 4, 2015, 10:26pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/5 "2015-12-04T22:26:26Z")

</div>

```rust
mod inner { pub struct OtherCratesCantNameMe; }
pub fn f() -> inner::OtherCratesCantNameMe { ... }

```

is permitted, so errors from the private-in-public checker can always be easily worked around if necessary. The main purpose of this checker is to guarantee that non-`pub` things can’t escape their module, not to guarantee nameability.

---

<div class="post-metadata">

**Author:** ![bluss](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bluss/32/2264_2.png) [@bluss](https://internals.rust-lang.org/u/bluss)\
**Post date:** [December 4, 2015, 10:33pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/6 "2015-12-04T22:33:24Z")

</div>

Thanks for explaining! Given the range of things uncovered by the new checking, I wasn’t sure which quirks would remain as features. Please let’s commit to that this stays then?

---

<div class="post-metadata">

**Author:** ![stebalien](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/stebalien/32/228_2.png) [@stebalien](https://internals.rust-lang.org/u/stebalien)\
**Post date:** [December 4, 2015, 10:38pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/7 "2015-12-04T22:38:38Z")

</div>

> [@petrochenkov](#):
>
> pub fn f() -\> inner::OtherCratesCantNameMe { ... }

I assume that this will eventually be reachable through `f::Output`.

---

<div class="post-metadata">

**Author:** ![tomaka](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/tomaka/32/2842_2.png) [@tomaka](https://internals.rust-lang.org/u/tomaka)\
**Post date:** [December 5, 2015, 1:03pm UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/8 "2015-12-05T13:03:49Z")

</div>

Without exaggeration, one of the biggest challenges of writing glium is to handle privacy.

I’m using several techniques:

- [I have a lot of private traits at the crate root](https://github.com/tomaka/glium/blob/master/src/lib.rs#L194-L374).
- [In order to call functions from another module I end up implementing a trait with a static function on a public type](https://github.com/tomaka/glium/blob/master/src/ops/read.rs#L199), even when sometimes that static function has not much to do with type itself.
- [Functions marked as #[doc(hidden)]](https://github.com/tomaka/glium/search?utf8=%E2%9C%93&q=doc%28hidden%29)
- I put the code in a private module, then create a public module that acts as a facade (for example the `fbo` module (“fbo” means “framebuffer object”) is private, and the `framebuffer` module is public).

But all these are crappy, and I would love to get some language improvements.

---

<div class="post-metadata">

**Author:** ![bluss](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bluss/32/2264_2.png) [@bluss](https://internals.rust-lang.org/u/bluss)\
**Post date:** [March 25, 2019, 8:25am UTC](https://internals.rust-lang.org/t/the-future-of-privacy-and-encapsulation/2961/9 "2019-03-25T08:25:32Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
