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

Non-exported type in exported type signature does not error #29668

Closed
jethrogb opened this Issue Nov 7, 2015 · 5 comments

Comments

Projects
None yet
4 participants
@jethrogb
Contributor

jethrogb commented Nov 7, 2015

mod m1 {
    struct A;
    pub fn x() -> A { A }
}

fn main() {
    let x=m1::x();
    println!("{:?}",&x as *const _ as *const u8);
}

This generates an error:

<anon>:3:16: 3:17 error: private type in exported type signature [E0446]
<anon>:3    pub fn x() -> A { A }
                          ^

Yet this compiles fine:

mod m1 {
    mod m2 { pub struct A; }
    use self::m2::A as A;
    pub fn x() -> A { A }
}

fn main() {
    let x=m1::x();
    println!("{:?}",&x as *const _ as *const u8);
}

However, one is unable to specify the return type of m1::x() outside of m1.

@jethrogb

This comment has been minimized.

Show comment
Hide comment
@jethrogb

jethrogb Nov 7, 2015

Contributor

Related/potential dupe of #28450, #28325, #18082

Contributor

jethrogb commented Nov 7, 2015

Related/potential dupe of #28450, #28325, #18082

@jethrogb

This comment has been minimized.

Show comment
Hide comment
@jethrogb

jethrogb Nov 7, 2015

Contributor

There was some discussion on IRC that since struct A is marked pub, it might be exported, which might make this not-a-bug. I think it should be possible to definitively prove whether the type is exported in an accessible way. In particular, one might require for exported functions that when traversing up the path, at some point there must be a valid exported path for the function and all types in the function type signature.

Contributor

jethrogb commented Nov 7, 2015

There was some discussion on IRC that since struct A is marked pub, it might be exported, which might make this not-a-bug. I think it should be possible to definitively prove whether the type is exported in an accessible way. In particular, one might require for exported functions that when traversing up the path, at some point there must be a valid exported path for the function and all types in the function type signature.

@jethrogb

This comment has been minimized.

Show comment
Hide comment
@jethrogb

jethrogb Nov 7, 2015

Contributor

Actually that can be circumvented by later re-exporting a module containing exporting a function but not a module exporting the appropriate type.

Contributor

jethrogb commented Nov 7, 2015

Actually that can be circumvented by later re-exporting a module containing exporting a function but not a module exporting the appropriate type.

@steveklabnik steveklabnik added the A-lang label Nov 7, 2015

@petrochenkov

This comment has been minimized.

Show comment
Hide comment
@petrochenkov

petrochenkov Nov 7, 2015

Contributor

According to RFC 136 a type is exported automatically if it's mentioned in any kind of public interface, with one minor sanity check - it should be marked as pub. It's not yet implemented though.
So, yeah, unnameable types is a thing. (But not necessarily a good one)

Contributor

petrochenkov commented Nov 7, 2015

According to RFC 136 a type is exported automatically if it's mentioned in any kind of public interface, with one minor sanity check - it should be marked as pub. It's not yet implemented though.
So, yeah, unnameable types is a thing. (But not necessarily a good one)

@DemiMarie

This comment has been minimized.

Show comment
Hide comment
@DemiMarie

DemiMarie Nov 8, 2015

Contributor

The D language has Voldemort types, which are types that cannot be named. In that language they are widely used. However, I don't know how useful they are in Rust, which uses generics instead of templates.

Contributor

DemiMarie commented Nov 8, 2015

The D language has Voldemort types, which are types that cannot be named. In that language they are widely used. However, I don't know how useful they are in Rust, which uses generics instead of templates.

bors added a commit that referenced this issue Dec 18, 2015

Auto merge of #29973 - petrochenkov:privinpub, r=nikomatsakis
Some notes:
This patch enforces the rules from [RFC 136](https://github.com/rust-lang/rfcs/blob/master/text/0136-no-privates-in-public.md) and makes "private in public" a module-level concept and not crate-level. Only `pub` annotations are used by the new algorithm, crate-level exported node set produced by `EmbargoVisitor` is not used. The error messages are tweaked accordingly and don't use the word "exported" to avoid confusing people (#29668).

The old algorithm tried to be extra smart with impls, but it mostly led to unpredictable behavior and bugs like #28325.
The new algorithm tries to be as simple as possible - an impl is considered public iff its type is public and its trait is public (if presents).
A type or trait is considered public if all its components are public, [complications](https://internals.rust-lang.org/t/limits-of-type-inference-smartness/2919) with private types leaking to other crates/modules through trait impls and type inference are deliberately ignored so far.

The new algorithm is not recursive and uses the nice new facility `Crate::visit_all_items`!

Obsolete pre-1.0 feature `visible_private_types` is removed.

This is a [breaking-change].
The two main vectors of breakage are type aliases (#28450) and impls (#28325).
I need some statistics from a crater run (cc @alexcrichton) to decide on the breakage mitigation strategy.
UPDATE: All the new errors are reported as warnings controlled by a lint `private_in_public` and lint group `future_incompatible`, but the intent is to make them hard errors eventually.

Closes #28325
Closes #28450
Closes #29524
Closes #29627
Closes #29668
Closes #30055

r? @nikomatsakis

@bors bors closed this in #29973 Dec 18, 2015

@steveklabnik steveklabnik added the T-lang label Mar 24, 2017

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