Rust: Existential type complains about private type in public interface if concrete type is not pub

Created on 21 Aug 2018  路  9Comments  路  Source: rust-lang/rust

#![feature(existential_type)]

pub mod foo {
    pub existential type Foo: ::std::fmt::Debug;
    pub fn foo() -> Foo {
        S
    }

    #[derive(Debug)] struct S;
}

gives

warning: private type `foo::S` in public interface (error E0446)
 --> src/lib.rs:4:5
  |
4 |     pub existential type Foo: ::std::fmt::Debug;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(private_in_public)] on by default
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>

Returning impl ::std::fmt::Debug does not have this restriction.

A-impl-trait A-visibility

Most helpful comment

All 9 comments

This also happens with closures:

#![feature(existential_type)]
pub existential type X: FnOnce();
pub fn foo() -> X {
    || ()
}

gives

warning: private type `[closure@src/lib.rs:5:5: 5:10]` in public interface (error E0446)
 --> src/lib.rs:3:1
  |
3 | pub existential type X: FnOnce();
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: #[warn(private_in_public)] on by default
  = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>

    Finished dev [unoptimized + debuginfo] target(s) in 0.36s

And as far as I can tell, there isn't a way to work around this?

This should probably be tagged T-compiler, A-impl-trait, and A-lint.

I'll look what happens.
The underlying type should not be revealed during privacy checking of impl Trait types.

For some weird reason, I'm getting a hard error instead of a warning for this when it's happening in a much larger crate of mine on nightly-2019-01-09. I'm not using deny(private_in_public). Not sure whether that's related:

error[E0446]: private type `[closure@noria/src/table.rs:295:31: 295:44]` in public interface
   --> noria/src/table.rs:219:5
    |
219 |     existential type Future: Future<Item = Tagged<()>, Error = TableError>;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
...
295 |                     .fold((), |_, _| Ok(()))
    |                               ------------- `[closure@noria/src/table.rs:295:31: 295:44]` declared as private

Ouch, when this is an error, it's _really_ hard to work around. @petrochenkov any luck trying to figure out the cause of this?

I still get the warning for this example:

#![feature(existential_type)]

pub trait Test {
    type Foo;
    fn foo() -> Self::Foo;
}

struct FooImpl;

impl Test for () {
    existential type Foo: ;
    fn foo() -> Self::Foo {
        FooImpl
    }
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=944fd033d23b9698f766485ec9e452c8

Was this page helpful?
0 / 5 - 0 ratings