Fix private fields diagnostics and improve error messages

This commit is contained in:
yukang
2026-04-06 12:33:42 +08:00
parent e73c56abd0
commit 8f0bd63075
7 changed files with 111 additions and 26 deletions
+20 -17
View File
@@ -2439,25 +2439,28 @@ fn report_private_fields(
})
.partition(|field| field.2);
err.span_labels(used_private_fields.iter().map(|(_, span, _)| *span), "private field");
if !remaining_private_fields.is_empty() {
let names = if remaining_private_fields.len() > 6 {
String::new()
} else {
format!(
"{} ",
listify(&remaining_private_fields, |(name, _, _)| format!("`{name}`"))
.expect("expected at least one private field to report")
)
};
err.note(format!(
"{}private field{s} {names}that {were} not provided",
if used_fields.is_empty() { "" } else { "...and other " },
s = pluralize!(remaining_private_fields.len()),
were = pluralize!("was", remaining_private_fields.len()),
));
}
if let ty::Adt(def, _) = adt_ty.kind() {
if (def.did().is_local() || !used_fields.is_empty())
&& !remaining_private_fields.is_empty()
{
let names = if remaining_private_fields.len() > 6 {
String::new()
} else {
format!(
"{} ",
listify(&remaining_private_fields, |(name, _, _)| format!("`{name}`"))
.expect("expected at least one private field to report")
)
};
err.note(format!(
"{}private field{s} {names}that {were} not provided",
if used_fields.is_empty() { "" } else { "...and other " },
s = pluralize!(remaining_private_fields.len()),
were = pluralize!("was", remaining_private_fields.len()),
));
}
let def_id = def.did();
let mut items = self
.tcx
@@ -0,0 +1,24 @@
pub struct Named {
hidden: u8,
}
impl Named {
pub fn new() -> Self {
Self { hidden: 0 }
}
}
pub struct NamedWithMultipleFields {
hidden: u8,
pub visible: u8,
}
struct PrivateInner;
pub struct PublicTuple(PrivateInner);
impl PublicTuple {
pub fn new() -> Self {
Self(PrivateInner)
}
}
@@ -0,0 +1,20 @@
//@ aux-build:private-fields-diagnostic-aux-issue-151408.rs
extern crate private_fields_diagnostic_aux_issue_151408 as aux;
use aux::{Named, NamedWithMultipleFields, PublicTuple};
fn main() {
let _ = Named {};
//~^ ERROR cannot construct `aux::Named` with struct literal syntax due to private fields
let _ = PublicTuple();
//~^ ERROR cannot initialize a tuple struct which contains private fields [E0423]
// Keep the private-field note when the user already wrote part of the struct literal.
let _ = NamedWithMultipleFields { visible: 1 };
//~^ ERROR cannot construct `NamedWithMultipleFields` with struct literal syntax due to private fields
let _ = NamedWithMultipleFields {};
//~^ ERROR cannot construct `NamedWithMultipleFields` with struct literal syntax due to private fields
}
@@ -0,0 +1,45 @@
error: cannot construct `aux::Named` with struct literal syntax due to private fields
--> $DIR/private-fields-diagnostic-issue-151408.rs:8:13
|
LL | let _ = Named {};
| ^^^^^
|
help: you might have meant to use the `new` associated function
|
LL - let _ = Named {};
LL + let _ = Named::new();
|
error[E0423]: cannot initialize a tuple struct which contains private fields
--> $DIR/private-fields-diagnostic-issue-151408.rs:11:13
|
LL | let _ = PublicTuple();
| ^^^^^^^^^^^
|
note: constructor is not visible here due to private fields
--> $DIR/auxiliary/private-fields-diagnostic-aux-issue-151408.rs:18:24
|
LL | pub struct PublicTuple(PrivateInner);
| ^^^^^^^^^^^^ private field
help: you might have meant to use the `new` associated function
|
LL | let _ = PublicTuple::new();
| +++++
error: cannot construct `NamedWithMultipleFields` with struct literal syntax due to private fields
--> $DIR/private-fields-diagnostic-issue-151408.rs:15:13
|
LL | let _ = NamedWithMultipleFields { visible: 1 };
| ^^^^^^^^^^^^^^^^^^^^^^^
|
= note: ...and other private field `hidden` that was not provided
error: cannot construct `NamedWithMultipleFields` with struct literal syntax due to private fields
--> $DIR/private-fields-diagnostic-issue-151408.rs:18:13
|
LL | let _ = NamedWithMultipleFields {};
| ^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 4 previous errors
For more information about this error, try `rustc --explain E0423`.
-3
View File
@@ -81,7 +81,6 @@ error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to
LL | let _ = std::collections::HashMap {};
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: private field `base` that was not provided
help: you might have meant to use an associated function to build this type
|
LL - let _ = std::collections::HashMap {};
@@ -109,7 +108,6 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi
LL | let _ = Box {};
| ^^^
|
= note: private fields `0` and `1` that were not provided
help: you might have meant to use an associated function to build this type
|
LL - let _ = Box {};
@@ -137,7 +135,6 @@ error: cannot construct `Box<i32>` with struct literal syntax due to private fie
LL | let _ = Box::<i32> {};
| ^^^^^^^^^^
|
= note: private fields `0` and `1` that were not provided
help: you might have meant to use an associated function to build this type
|
LL - let _ = Box::<i32> {};
@@ -81,7 +81,6 @@ error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to
LL | let _ = std::collections::HashMap {};
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: private field `base` that was not provided
help: you might have meant to use an associated function to build this type
|
LL - let _ = std::collections::HashMap {};
@@ -109,7 +108,6 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi
LL | let _ = Box {};
| ^^^
|
= note: private fields `0` and `1` that were not provided
help: you might have meant to use an associated function to build this type
|
LL - let _ = Box {};
@@ -80,8 +80,7 @@ error: cannot construct `HashMap<_, _, _, _>` with struct literal syntax due to
LL │ let _ = std::collections::HashMap {};
│ ━━━━━━━━━━━━━━━━━━━━━━━━━
╰ note: private field `base` that was not provided
╰╴
help: you might have meant to use an associated function to build this type
╭╴
LL - let _ = std::collections::HashMap {};
@@ -108,8 +107,7 @@ error: cannot construct `Box<_, _>` with struct literal syntax due to private fi
LL │ let _ = Box {};
│ ━━━
╰ note: private fields `0` and `1` that were not provided
╰╴
help: you might have meant to use an associated function to build this type
╭╴
LL - let _ = Box {};