-
Notifications
You must be signed in to change notification settings - Fork 14k
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 fieldThis 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 fieldsThe 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 fieldWhen 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 fieldWe 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!