-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Open
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-visibilityArea: Visibility / privacyArea: Visibility / privacyC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint that should be reworked.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.Diagnostics: A diagnostic that is giving misleading or incorrect information.D-papercutDiagnostics: An error or lint that needs small tweaks.Diagnostics: An error or lint that needs small tweaks.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
If a public tuple struct with private fields is declared in a public module, then instantiated elsewhere, the error message is helpful. For example, the code
// src/lib.rs
pub mod a {
pub struct Triplet(usize, usize, f64);
}
// src/main.rs
use triplets::a::Triplet;
fn main() {
let mut triplets = Vec::new();
triplets.push(Triplet(0, 0, 1.0));
}
causes the compiler to give the following useful error message:
error[E0423]: expected function, tuple struct or tuple variant, found struct `Triplet`
--> src/main.rs:5:19
|
5 | triplets.push(Triplet(0, 0, 1.0));
| ^^^^^^^
| |
| constructor is not visible here due to private fields
| help: a local variable with a similar name exists: `triplets`
error: aborting due to previous error
This tells us exactly what the problem is - that we cannot construct Triplet
because its fields are private.
However, if the tuple struct is in a private module, but re-exported as public, the error message isn't helpful (it's even confusing). For example,
// src/lib.rs
mod a {
pub struct Triplet(usize, usize, f64);
}
pub use a::Triplet;
// src/main.rs
use triplets::Triplet;
fn main() {
let mut triplets = Vec::new();
triplets.push(Triplet(0, 0, 1.0));
}
gives the compiler error
error[E0423]: expected function, tuple struct or tuple variant, found struct `Triplet`
--> src/main.rs:5:19
|
5 | triplets.push(Triplet(0, 0, 1.0));
| ^^^^^^^
| |
| did you mean `Triplet { /* fields */ }`?
| help: a local variable with a similar name exists: `triplets`
error: aborting due to previous error
which confusingly suggests initialising the tuple with braces, instead of reporting that the fields are private.
Unsurprisingly, both versions work fine if the fields of Triplet
are made public.
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-visibilityArea: Visibility / privacyArea: Visibility / privacyC-enhancementCategory: An issue proposing an enhancement or a PR with one.Category: An issue proposing an enhancement or a PR with one.D-confusingDiagnostics: Confusing error or lint that should be reworked.Diagnostics: Confusing error or lint that should be reworked.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.Diagnostics: A diagnostic that is giving misleading or incorrect information.D-papercutDiagnostics: An error or lint that needs small tweaks.Diagnostics: An error or lint that needs small tweaks.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.