diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index aca8e1200ea9..86a5c55f443f 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -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 diff --git a/tests/ui/privacy/auxiliary/private-fields-diagnostic-aux-issue-151408.rs b/tests/ui/privacy/auxiliary/private-fields-diagnostic-aux-issue-151408.rs new file mode 100644 index 000000000000..399d45205c6a --- /dev/null +++ b/tests/ui/privacy/auxiliary/private-fields-diagnostic-aux-issue-151408.rs @@ -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) + } +} diff --git a/tests/ui/privacy/private-fields-diagnostic-issue-151408.rs b/tests/ui/privacy/private-fields-diagnostic-issue-151408.rs new file mode 100644 index 000000000000..456e2d418e2d --- /dev/null +++ b/tests/ui/privacy/private-fields-diagnostic-issue-151408.rs @@ -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 +} diff --git a/tests/ui/privacy/private-fields-diagnostic-issue-151408.stderr b/tests/ui/privacy/private-fields-diagnostic-issue-151408.stderr new file mode 100644 index 000000000000..1a49a21d6b79 --- /dev/null +++ b/tests/ui/privacy/private-fields-diagnostic-issue-151408.stderr @@ -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`. diff --git a/tests/ui/privacy/suggest-box-new.stderr b/tests/ui/privacy/suggest-box-new.stderr index 7367672351d6..0ba4ba97cd1a 100644 --- a/tests/ui/privacy/suggest-box-new.stderr +++ b/tests/ui/privacy/suggest-box-new.stderr @@ -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` with struct literal syntax due to private fie 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:: {}; diff --git a/tests/ui/suggestions/multi-suggestion.ascii.stderr b/tests/ui/suggestions/multi-suggestion.ascii.stderr index 2da0f9bd12c2..9c3669a30939 100644 --- a/tests/ui/suggestions/multi-suggestion.ascii.stderr +++ b/tests/ui/suggestions/multi-suggestion.ascii.stderr @@ -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 {}; diff --git a/tests/ui/suggestions/multi-suggestion.unicode.stderr b/tests/ui/suggestions/multi-suggestion.unicode.stderr index 69529b67b775..50316f7e90b4 100644 --- a/tests/ui/suggestions/multi-suggestion.unicode.stderr +++ b/tests/ui/suggestions/multi-suggestion.unicode.stderr @@ -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 {};