Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 20 additions & 17 deletions compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2439,25 +2439,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
})
.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
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
}
}
20 changes: 20 additions & 0 deletions tests/ui/privacy/private-fields-diagnostic-issue-151408.rs
Original file line number Diff line number Diff line change
@@ -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
}
45 changes: 45 additions & 0 deletions tests/ui/privacy/private-fields-diagnostic-issue-151408.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 0 additions & 3 deletions tests/ui/privacy/suggest-box-new.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 {};
Expand Down Expand Up @@ -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 {};
Expand Down Expand Up @@ -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> {};
Expand Down
2 changes: 0 additions & 2 deletions tests/ui/suggestions/multi-suggestion.ascii.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 {};
Expand Down Expand Up @@ -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 {};
Expand Down
6 changes: 2 additions & 4 deletions tests/ui/suggestions/multi-suggestion.unicode.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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 {};
Expand All @@ -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 {};
Expand Down
Loading