rust

Why is returning a private type a warning, but not returning a public type of a private module?


Consider this code

struct Error;

mod private {
    pub struct Error;
}

pub fn do1() -> Result<(), Error> {
    Ok(())
}

pub fn do2() -> Result<(), private::Error> {
    Ok(())
}

This produces the following warning

   Compiling playground v0.0.1 (/playground)
warning: type `Error` is more private than the item `do1`
 --> src/lib.rs:7:1
  |
7 | pub fn do1() -> Result<(), Error> {
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `do1` is reachable at visibility `pub`
  |
note: but type `Error` is only usable at visibility `pub(crate)`
 --> src/lib.rs:1:1
  |
1 | struct Error;
  | ^^^^^^^^^^^^
  = note: `#[warn(private_interfaces)]` on by default

(playground link)

This warning makes sense to me, as the error type will not be usable by callers of this crate. However, as far as I'm aware, the same is true of private::Error, yet do2 does not produce such a warning. Is this a limitation of the compiler, or is there a subtle difference between these two cases that means only one case deserves warning?


Solution

  • This is tracked as a bug at https://github.com/rust-lang/rust/issues/85883.

    The pattern is sometimes used to implement sealed traits, where a public trait depends on a private trait (meaning only the original crate can implement the trait).