Description
This is the destructure counterpart of #75906
Overview
Attempting to destructure a private field in a public tuple struct yields a confusing error message. Given the following code:
mod foo {
pub(crate) struct Bar{inner: u8}
pub(crate) fn make_bar() -> Bar {
Bar{ inner: 12 }
}
}
use foo::{Bar, make_bar};
fn main() {
let Bar{ inner } = make_bar();
dbg!(inner);
}
The following error is generated:
error[E0451]: field `inner` of struct `foo::Bar` is private
--> src/main.rs:12:14
|
12 | let Bar{ inner } = make_bar();
| ^^^^^ private field
This seems quite helpful: some field is private, so we can infer we probably should make it public instead. However when we convert the code to a tuple struct things become more confusing:
mod foo {
pub(crate) struct Bar(u8);
pub(crate) fn make_bar() -> Bar {
Bar(12)
}
}
use foo::{Bar, make_bar};
fn main() {
let Bar(y) = make_bar();
}
The following error is generated:
error[E0532]: expected tuple struct or tuple variant, found struct `Bar`
--> src/main.rs:12:9
|
12 | let Bar(y) = make_bar();
| ^^^ constructor is not visible here due to private fields
The error message itself doesn't point us to the problem (expected tuple struct or tuple variant, found struct Bar
), and mentioning a constructor in the code block isn't helpful either. After all we're not trying to construct anything; we're trying to destruct.
Proposed solution
When accessing a private field in a tuple struct rustc already generates pretty good errors:
let x = make_bar();
dbg!(x.0);
error[E0616]: field `0` of struct `foo::Bar` is private
--> src/main.rs:13:12
|
13 | dbg!(x.0);
| ^ private field
When destructuring tuple structs these errors would be accurate as well:
error[E0616]: field `0` of struct `foo::Bar` is private
--> src/main.rs:12:9
|
12 | let Bar(y) = make_bar();
| ^ private field
We could take it even further and suggest a fix for this as well:
error[E0616]: field `0` of struct `foo::Bar` is private
--> src/main.rs:12:9
|
12 | let Bar(y) = make_bar();
| ^ private field
| |
| help: declare the struct's fields as public: `struct Bar(pub(crate) u8);`
Conclusion
In this issue I've shown an incorrect error message that occurs when attempting to destructure a private field in a tuple-struct, and made suggestions on how we can improve this.
I hope this is helpful. Thanks!