Skip to content

"error: private type in public interface" in private module #30905

Closed
@SimonSapin

Description

@SimonSapin
Contributor

Reduced test case:

struct HostInternal;

mod parser {
    use super::HostInternal;
    pub fn parse() -> HostInternal {
        unimplemented!();
    }
}

Output with rustc 1.7.0-nightly (1447ce7 2016-01-13)

a.rs:5:23: 5:35 error: private type in public interface [E0446]
a.rs:5     pub fn parse() -> HostInternal {
                             ^~~~~~~~~~~~
a.rs:5:23: 5:35 help: run `rustc --explain E0446` to see a detailed explanation
error: aborting due to previous error

This is incorrect: the parse function is not visible anywhere HostInternal isn’t since the parser module is not public.

In my non-reduced crate I get a warning rather than an error but I haven’t managed to reproduce that in the reduced case. (Regardless, that warning is also incorrect.)

src/parser.rs:520:43: 520:55 warning: private type in public interface (error E0446), #[warn(private_in_public)] on by default
src/parser.rs:520                           -> ParseResult<(HostInternal, &'i str)> {
                                                            ^~~~~~~~~~~~
src/parser.rs:520:43: 520:55 note: this lint will become a HARD ERROR in a future release!
src/parser.rs:520                           -> ParseResult<(HostInternal, &'i str)> {

Activity

oli-obk

oli-obk commented on Jan 14, 2016

@oli-obk
Contributor

This is expected, because the outer module could re-export that function.

SimonSapin

SimonSapin commented on Jan 14, 2016

@SimonSapin
ContributorAuthor

I couldn’t but it doesn’t. And the compiler should know that. It’s all in the same crate, a re-export can not be added without recompiling that crate.

oli-obk

oli-obk commented on Jan 14, 2016

@oli-obk
Contributor

see #22261 for the discussion, the point is that the privacy checks don't need to reason about the entire crate, but just about the module

SimonSapin

SimonSapin commented on Jan 14, 2016

@SimonSapin
ContributorAuthor

I understand that fixing this bug may require doing a more complex analysis than is currently done, but i maintain that it's a bug. #22261 (comment) says the same.

SimonSapin

SimonSapin commented on Jan 14, 2016

@SimonSapin
ContributorAuthor

Conversely, this compile fine but should be an error:

pub fn parse() -> parser::HostInternal {
    unimplemented!();
}
mod parser {
    pub struct HostInternal;
}
petrochenkov

petrochenkov commented on Jan 14, 2016

@petrochenkov
Contributor

@SimonSapin

fixing this bug may require doing a more complex analysis than is currently done

Conversely, this compile fine but should be an error

More complex analysis (reachability by reexports, "nameability") was done before and the example with HostInternal was an error (based on rust-lang/rfcs#136), but the rules were changed by the newer edition of RFC 136 to be local, module-level and based exclusively on pub annotations and not reachability (it wasn't thoroughly implemented though until recently).

Edit: some reasons are outlined by @nikomatsakis in #28450 (comment)

SimonSapin

SimonSapin commented on Jan 14, 2016

@SimonSapin
ContributorAuthor

This sounds like a regression. Some git archaeology points to rust-lang/rfcs#200, I’ll read up on motivations.

retep998

retep998 commented on Jan 14, 2016

@retep998
Member

The new rules are not an improvement in any way except to make the code in rustc simpler. There's still a lot of false negatives, still a lot of false positives as well, and it will cause breaking changes to a huge amount of existing Rust code. If there's going to be breaking changes, the new system should at least have significant improvements to make the breakage worth it.

petrochenkov

petrochenkov commented on Jan 14, 2016

@petrochenkov
Contributor

except to make the code in rustc simpler

Nah, the compiler still tracks reachability through reexports for other purposes.

retep998

retep998 commented on Jan 14, 2016

@retep998
Member

@petrochenkov So you're saying it isn't even an improvement at all and we're just breaking the world to satisfy some RFC that has been sitting around for over a year?

petrochenkov

petrochenkov commented on Jan 14, 2016

@petrochenkov
Contributor

@retep998
The recent changes are an improvement because the implementation was a hardly predictable mix of the new rules (mostly), old rules (to less extent) and outright missing cases. Now it's at least consistent.

nikomatsakis

nikomatsakis commented on Jan 15, 2016

@nikomatsakis
Contributor

@retep998 Let me just say that I'm sorry your code stopped compiling -- I know that's always a pain, whatever the cause. In this case, as @petrochenkov said, there really aren't any new rules: it's just that rustc was (very) buggy and failed to enforce the rules consistently. But I know that doesn't make it any less annoying when you have to update your code.

retep998

retep998 commented on Jan 15, 2016

@retep998
Member

The changes are still only warnings for me so far, although the warnings claim they will become errors, so thankfully it isn't the end of the world yet.

nikomatsakis

nikomatsakis commented on Jan 16, 2016

@nikomatsakis
Contributor

@retep998 I'd actually be interested to see the specific cases that are failing for you. In particular, I'd like to know if they fall into the category of type aliases that appear in public interfaces, or something else?

16 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @seanmonstar@nikomatsakis@SimonSapin@oli-obk@retep998

        Issue actions

          "error: private type in public interface" in private module · Issue #30905 · rust-lang/rust