Skip to content
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
Closed

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

jethrogb opened this issue Nov 7, 2015 · 5 comments
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@jethrogb
Copy link
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
Copy link
Contributor Author

jethrogb commented Nov 7, 2015

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

@jethrogb
Copy link
Contributor Author

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
Copy link
Contributor Author

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.

@petrochenkov
Copy link
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)

@DemiMarie
Copy link
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.

bors added a commit that referenced this issue Dec 18, 2015
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
@steveklabnik steveklabnik added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Mar 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants