rust-lang / rust-lang/rust

Suboptimal error message when matching on a tuple struct using a private constructor

Open
#124,569 4 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-diagnostics T-compiler
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Code
pub mod foo {
    pub struct Foo(u8);
}

pub fn bar(foo: Option<foo::Foo>) {
    match foo {
        // Some(foo::Foo{..}) => println!("Foo"),
        Some(foo::Foo(..)) => println!("Foo"),
        None => println!("No Foo"),
    }
}
Current output
Compiling playground v0.0.1 (/playground)
error[E0603]: tuple struct constructor `Foo` is private
 --> src/lib.rs:8:19
  |
2 |     pub struct Foo(u8);
  |                    -- a constructor is private if any of the fields is private
...
8 |         Some(foo::Foo(..)) => println!("Foo"),
  |                   ^^^ private tuple struct constructor
  |
note: the tuple struct constructor `Foo` is defined here
 --> src/lib.rs:2:5
  |
2 |     pub struct Foo(u8);
  |     ^^^^^^^^^^^^^^^^^^^
help: consider making the field publicly accessible
  |
2 |     pub struct Foo(pub u8);
  |                    +++

For more information about this error, try `rustc --explain E0603`.
error: could not compile `playground` (lib) due to 1 previous error
Desired output
Compiling playground v0.0.1 (/playground)
error[E0603]: tuple struct constructor `Foo` is private
 --> src/lib.rs:8:19
  |
2 |     pub struct Foo(u8);
  |                    -- a constructor is private if any of the fields is private
...
8 |         Some(foo::Foo(..)) => println!("Foo"),
  |                   ^^^ private tuple struct constructor
  |
note: the tuple struct constructor `Foo` is defined here
 --> src/lib.rs:2:5
  |
2 |     pub struct Foo(u8);
  |     ^^^^^^^^^^^^^^^^^^^
help: consider making the field publicly accessible
  |
2 |     pub struct Foo(pub u8);
  |                    +++
help: consider matching via `{ .. }` braces instead of the constructor
  |
8 |         Some(foo::Foo { .. }) => println!("Foo")
  |                       ++++++

For more information about this error, try `rustc --explain E0603`.
error: could not compile `playground` (lib) due to 1 previous error
Rationale and extra context

I've used Rust for a while, and I just discovered that this is an option that lets you match on tuple structs with private fields. It would be great if the compiler could recommend this as a solution.

Other cases
If the `foo::Foo` comes from an external dependency, it does not suggest making the field publicly accessible (makes sense, since you likely can't change the dependency), but no suggestions are provided. I think it's more important to include my proposed new help text in that case, so a solution is provided, but still net beneficial in the above case.
Rust Version
Using [the Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021)'s current nightly release:

1.80.0-nightly (2024-04-29 a8a1d3a771850e1e364e)

(sorry, I don't know how to get the playground to show the full verbose version output)
Anything else?

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run the reported reproduction in src/lib.rs and compare the current and desired E0603 output. Trace the compiler diagnostic responsible for the private tuple-struct constructor error; done means it recommends matching with { .. }, including the external-dependency case described.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.