`private_interfaces` lint needs to perform type resolution to avoid false positives
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
The private_interfaces lint incorrectly fires for cases where a type is declared via a private interface but nevertheless fully resolves to an equally (or more) public type.
trait Service {
type Output;
fn process() -> Self::Output;
}
pub struct SomeService;
impl Service for SomeService {
type Output = ();
fn process() -> Self::Output {
todo!();
}
}
// False positive on return type here:
pub fn exposed_method() -> <SomeService as Service>::Output {
SomeService::process()
}
Currently produces the following error on both 1.91.1 stable and 1.93.0-nightly:
warning: associated type `Service::Output` is more private than the item `exposed_method`
--> src/lib.rs:16:1
|
16 | pub fn exposed_method() -> <SomeService as Service>::Output {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `exposed_method` is reachable at visibility `pub`
|
note: but associated type `Service::Output` is only usable at visibility `pub(crate)`
--> src/lib.rs:2:5
|
2 | type Output;
| ^^^^^^^^^^^
= note: `#[warn(private_interfaces)]` on by default
warning: trait `Service` is more private than the item `exposed_method`
--> src/lib.rs:16:1
|
16 | pub fn exposed_method() -> <SomeService as Service>::Output {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `exposed_method` is reachable at visibility `pub`
|
note: but trait `Service` is only usable at visibility `pub(crate)`
--> src/lib.rs:1:1
|
1 | trait Service {
| ^^^^^^^^^^^^^
Playground link: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2024&gist=4756e3d350f5f0bdd90086f76d043a89
As you can see, the private_interfaces lint is automatically fired when a less-public type is encountered in the type signature, but if type resolution were performed it would be obvious that this actually resolves to a very much public and accessible type (in this case, ()).
(This is a very much contrived example; in my actual code I have a trait that exposes blocking methods via a non-blocking async interface and the trait's associated type is the shortest and least error-prone method of expressing the type of a pub static)
@rustbot label +T-compiler +L-private_interfaces +L-false-positive +A-visibility +A-lints +C-bug
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the false positive from the linked Rust Playground example, then trace the compiler's private_interfaces lint and its type-resolution handling. The work is done when the shown () return type no longer triggers warnings for the private trait or associated type, with regression coverage for the example.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100