Skip to content

[diagnostics] Attempting to initialize a private field in a public tuple struct yields confusing error message #75906

Closed
@yoshuawuyts

Description

@yoshuawuyts

This is a constructor counterpart to #75907

Overview

Errors for private fields in public non-tuple structs are pretty good. Given the following code:

mod foo {
    pub struct Bar { field: u8 }
}

use foo::Bar;

fn main() {
    let x = Bar { field: 12 };
}

The following error is returned:

error[E0451]: field `field` of struct `foo::Bar` is private
 --> src/main.rs:9:19
  |
9 |     let x = Bar { field: 12 };
  |                   ^^^^^^^^^ private field

A hint could be useful here, but overall this is good enough to understand. However when we convert this to a tuple struct the errors get more confusing:

mod foo {
    pub struct Bar(u8);
}

use foo::Bar;

fn main() {
    let x = Bar(12);
}

This yields the following error:

error[E0423]: expected function, tuple struct or tuple variant, found struct `Bar`
 --> src/main.rs:8:13
  |
8 |     let x = Bar(12);
  |             ^^^ constructor is not visible here due to private fields

The message of expected function, tuple struct or tuple variant, found struct Bar is not helpful here. It's a bit confusing what the fix is: how do we make the constructor visible? I had to look up how to declare visibility for inner fields in tuple structs.

Proposed solution

The error message could probably use some work. Something closer to the text of non-tuple structs would be clearer:

field `0` of struct `foo::Bar` is private

Or perhaps an even better direction would be:

cannot initialize a tuple struct which contains private fields

The main code block seems useful. But we could go even further and provide a hint on how to fix this if the struct is defined inside the same project:

error[E0423]: cannot initialize a tuple struct which contains private fields
 --> src/main.rs:8:13
  |
8 |     let x = Bar(12);
  |             ^^^ constructor is not visible here due to private fields
  |             |
  |             help: declare the struct's fields as public: `struct Bar(pub(crate) u8);`

Conclusion

I found a location where our errors aren't as good as they could be, and figured there may be a way we can use that to not just improve the error message -- but actually teach people about visibility modifiers in tuple structs.

I hope this is helpful. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-visibilityArea: Visibility / privacyD-confusingDiagnostics: Confusing error or lint that should be reworked.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions