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

Possible to put/expose private type in exported/public type signature #18082

Closed
japaric opened this issue Oct 16, 2014 · 6 comments
Closed

Possible to put/expose private type in exported/public type signature #18082

japaric opened this issue Oct 16, 2014 · 6 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries

Comments

@japaric
Copy link
Member

japaric commented Oct 16, 2014

STR

mod private {
    pub struct Struct;
}

pub mod public {
    pub struct Struct;
}

struct PrivateStruct;

pub struct Triplet {
    pub left: public::Struct,  // OK public type in exported signature
    //pub middle: PrivateStruct,  // OK private in exported signature is rejected
    //~^ error: private type in exported type signature
    pub right: private::Struct,  // BAD private type in exported signature is accepted
}

rustc --crate-type=lib lib.rs successfully compiles, but it should error with error: private type in exported type signature with span on pub right: private::Struct.

Sanity check that private::Struct is actually private:

extern crate lib;

fn main() {
    let _ = lib::PrivateStruct;  //~ error: struct `PrivateStruct` is private
    let _ = lib::private::Struct;  //~ error: struct `Struct` is private
    let _ = lib::public::Struct;
}

Errors (as expected) with:

sanity-check.rs:4:13: 4:31 error: struct `PrivateStruct` is private
sanity-check.rs:4     let _ = lib::PrivateStruct;  //~ error: struct `PrivateStruct` is private
                              ^~~~~~~~~~~~~~~~~~
sanity-check.rs:5:13: 5:33 error: struct `Struct` is private
sanity-check.rs:5     let _ = lib::private::Struct;  //~ error: struct `Struct` is private
                              ^~~~~~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors

Version

rustc 0.13.0-dev (e4761c85b 2014-10-15 09:57:18 +0000)

This is supposed to be banned by RFC #136

cc @pcwalton

@alexcrichton
Copy link
Member

The definition of public items according to the RFC is simply "something marked pub", so it looks like this is actually working as intended.

@japaric
Copy link
Member Author

japaric commented Oct 16, 2014

Hmm, who about this:

// opaque.rs
mod inaccessible {
    pub struct Struct;

    impl Struct {
        pub fn kaboom(self) {
            unimplemented!();
        }
    }
}

pub fn new_thing() -> inaccessible::Struct {
    inaccessible::Struct
}

According to the RFC, inaccessible::Struct is a public item (although not reachable by an outer crate), therefore new_thing is a valid exported function.

Let's see the consequences:

// app.rs
extern crate opaque;

fn main() {
    let he_who_can_not_be_typed: _ = opaque::new_thing();  // what's the type of this?
    he_who_can_not_be_typed.kaboom();
}
$ rustc --crate-type=lib opaque.rs
$ rustc -L . app.rs
error: linking with `cc` failed: exit code: 1
note: cc '-m64' '-L' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib' '-o' 'app' 'app.o' '-Wl,--whole-archive' '-lmorestack' '-Wl,--no-whole-archive' '-nodefaultlibs' '-fno-lto' '-Wl,--gc-sections' '-pie' '-Wl,--as-needed' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/libnative-4e7c5e5c.rlib' '/home/japaric/tmp/libopaque.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/libstd-4e7c5e5c.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/librand-4e7c5e5c.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/libsync-4e7c5e5c.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/librustrt-4e7c5e5c.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/libcollections-4e7c5e5c.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-4e7c5e5c.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/libunicode-4e7c5e5c.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-4e7c5e5c.rlib' '/usr/lib64/rustlib/x86_64-unknown-linux-gnu/lib/libcore-4e7c5e5c.rlib' '-L' '.' '-L' '/home/japaric/tmp/.rust' '-L' '/home/japaric/tmp' '-Wl,--whole-archive' '-Wl,-Bstatic' '-Wl,--no-whole-archive' '-Wl,-Bdynamic' '-ldl' '-lpthread' '-lgcc_s' '-lpthread' '-lc' '-lm' '-lcompiler-rt'
note: app.o: In function `main::h7437927d0a861856faa':
app.0.rs:(.text._ZN4main20h7437927d0a861856faaE+0x2c): undefined reference to `inaccessible::Struct::kaboom::hbaedc25ee8398ba6jaa'
collect2: error: ld returned 1 exit status

error: aborting due to previous error

EDIT Fix variable name in method call

@alexcrichton
Copy link
Member

Aha! I would indeed classify that link error as a bug.

@kmcallister kmcallister added the A-linkage Area: linking into static, shared libraries and binaries label Oct 16, 2014
@steveklabnik
Copy link
Member

Triage: linking error still occurs

@bluss
Copy link
Member

bluss commented Sep 9, 2015

The "private mod trick" makes this private type/trait in public signature check very optional.

mod private {
    pub struct Foo;
}
pub fn take_foo(_: private::Foo) { }

@steveklabnik
Copy link
Member

Triage: linking error now goes away, and the program successfully executes.

Given the age of this issue, and that that seems to be the only bug here, I"m going to give this one a close. There has been a lot of discussion around the public-in-private lint, but this isn't the issue tracking any of that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries
Projects
None yet
Development

No branches or pull requests

5 participants