From ad13d9fbbe7d7a3bc5e59ad1f829e132d6cb1b0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 8 Jan 2023 01:15:28 +0000 Subject: [PATCH 1/3] Suggest making private tuple struct field public Fix #52144. --- .../rustc_resolve/src/build_reduced_graph.rs | 2 ++ .../rustc_resolve/src/late/diagnostics.rs | 20 +++++++++++++++++++ compiler/rustc_resolve/src/lib.rs | 5 +++++ tests/ui/privacy/issue-75906.stderr | 4 ++++ tests/ui/privacy/issue-75907.rs | 2 +- tests/ui/privacy/issue-75907.stderr | 8 ++++++++ tests/ui/resolve/issue-42944.rs | 2 +- tests/ui/resolve/issue-42944.stderr | 12 +++++++---- 8 files changed, 49 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 58f6fd2b006ff..928f372d948dd 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -331,7 +331,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .iter() .map(|field| respan(field.span, field.ident.map_or(kw::Empty, |ident| ident.name))) .collect(); + let field_vis = vdata.fields().iter().map(|field| field.vis.span).collect(); self.r.field_names.insert(def_id, field_names); + self.r.field_visibility_spans.insert(def_id, field_vis); } fn insert_field_names_extern(&mut self, def_id: DefId) { diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 74522f185422d..a675a1fb78bbc 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1451,6 +1451,26 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .collect(); if non_visible_spans.len() > 0 { + if let Some(visibility_spans) = self.r.field_visibility_spans.get(&def_id) { + err.multipart_suggestion_verbose( + &format!( + "consider making the field{} publicly accessible", + pluralize!(visibility_spans.len()) + ), + visibility_spans + .iter() + .map(|span| { + ( + *span, + if span.lo() == span.hi() { "pub " } else { "pub" } + .to_string(), + ) + }) + .collect(), + Applicability::MaybeIncorrect, + ); + } + let mut m: MultiSpan = non_visible_spans.clone().into(); non_visible_spans .into_iter() diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2182b73693774..84d9794ccf266 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -881,6 +881,10 @@ pub struct Resolver<'a> { /// Used for hints during error reporting. field_names: FxHashMap>>, + /// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax. + /// Used for hints during error reporting. + field_visibility_spans: FxHashMap>, + /// All imports known to succeed or fail. determined_imports: Vec<&'a Import<'a>>, @@ -1268,6 +1272,7 @@ impl<'a> Resolver<'a> { has_self: FxHashSet::default(), field_names: FxHashMap::default(), + field_visibility_spans: FxHashMap::default(), determined_imports: Vec::new(), indeterminate_imports: Vec::new(), diff --git a/tests/ui/privacy/issue-75906.stderr b/tests/ui/privacy/issue-75906.stderr index 4c6a68646adc8..600dc7c876ff3 100644 --- a/tests/ui/privacy/issue-75906.stderr +++ b/tests/ui/privacy/issue-75906.stderr @@ -9,6 +9,10 @@ note: constructor is not visible here due to private fields | LL | pub struct Bar(u8); | ^^ private field +help: consider making the field publicly accessible + | +LL | pub struct Bar(pub u8); + | +++ error: aborting due to previous error diff --git a/tests/ui/privacy/issue-75907.rs b/tests/ui/privacy/issue-75907.rs index 6da99cf6435cf..3bed841d13ea2 100644 --- a/tests/ui/privacy/issue-75907.rs +++ b/tests/ui/privacy/issue-75907.rs @@ -2,7 +2,7 @@ mod foo { pub(crate) struct Foo(u8); - pub(crate) struct Bar(pub u8, u8, Foo); + pub(crate) struct Bar(pub u8, pub(in crate::foo) u8, Foo); pub(crate) fn make_bar() -> Bar { Bar(1, 12, Foo(10)) diff --git a/tests/ui/privacy/issue-75907.stderr b/tests/ui/privacy/issue-75907.stderr index 2f89e31a31a1e..f7cb874c2cc0d 100644 --- a/tests/ui/privacy/issue-75907.stderr +++ b/tests/ui/privacy/issue-75907.stderr @@ -11,6 +11,10 @@ LL | let Bar(x, y, Foo(z)) = make_bar(); | ^ ^^^^^^ private field | | | private field +help: consider making the fields publicly accessible + | +LL | pub(crate) struct Bar(pub u8, pub u8, pub Foo); + | ~~~ ~~~ +++ error[E0532]: cannot match against a tuple struct which contains private fields --> $DIR/issue-75907.rs:15:19 @@ -23,6 +27,10 @@ note: constructor is not visible here due to private fields | LL | let Bar(x, y, Foo(z)) = make_bar(); | ^ private field +help: consider making the field publicly accessible + | +LL | pub(crate) struct Foo(pub u8); + | +++ error: aborting due to 2 previous errors diff --git a/tests/ui/resolve/issue-42944.rs b/tests/ui/resolve/issue-42944.rs index a4404857a56af..7e439c10b7b84 100644 --- a/tests/ui/resolve/issue-42944.rs +++ b/tests/ui/resolve/issue-42944.rs @@ -1,5 +1,5 @@ mod foo { - pub struct Bx(()); + pub struct Bx(pub(in crate::foo) ()); } mod bar { diff --git a/tests/ui/resolve/issue-42944.stderr b/tests/ui/resolve/issue-42944.stderr index 0ee9fd391fe12..4ffa9402c667e 100644 --- a/tests/ui/resolve/issue-42944.stderr +++ b/tests/ui/resolve/issue-42944.stderr @@ -7,8 +7,8 @@ LL | Bx(()); note: tuple struct `foo::Bx` exists but is inaccessible --> $DIR/issue-42944.rs:2:5 | -LL | pub struct Bx(()); - | ^^^^^^^^^^^^^^^^^^ not accessible +LL | pub struct Bx(pub(in crate::foo) ()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible error[E0423]: cannot initialize a tuple struct which contains private fields --> $DIR/issue-42944.rs:9:9 @@ -19,8 +19,12 @@ LL | Bx(()); note: constructor is not visible here due to private fields --> $DIR/issue-42944.rs:2:19 | -LL | pub struct Bx(()); - | ^^ private field +LL | pub struct Bx(pub(in crate::foo) ()); + | ^^^^^^^^^^^^^^^^^^^^^ private field +help: consider making the field publicly accessible + | +LL | pub struct Bx(pub ()); + | ~~~ error: aborting due to 2 previous errors From eb835093a3bc4dc571c1a612cc2efde85906e63e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 8 Jan 2023 07:18:07 +0000 Subject: [PATCH 2/3] review comment --- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a675a1fb78bbc..6923ca7ef1bf4 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1462,7 +1462,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .map(|span| { ( *span, - if span.lo() == span.hi() { "pub " } else { "pub" } + if span.is_empty() { "pub " } else { "pub" } .to_string(), ) }) From 41e66d902589964cda32a5a89c34023a9f78398b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 10 Jan 2023 20:57:02 +0000 Subject: [PATCH 3/3] review comments: Tweak output * Account for `struct S(pub(super)Ty);` in suggestion * Suggest changing field visibility in E0603 too --- .../rustc_resolve/src/build_reduced_graph.rs | 14 ++- compiler/rustc_resolve/src/diagnostics.rs | 14 ++- .../rustc_resolve/src/late/diagnostics.rs | 15 +-- tests/ui/privacy/privacy5.stderr | 96 +++++++++++++++++++ .../privacy/suggest-making-field-public.fixed | 15 +++ .../ui/privacy/suggest-making-field-public.rs | 15 +++ .../suggest-making-field-public.stderr | 39 ++++++++ tests/ui/resolve/privacy-struct-ctor.stderr | 16 ++++ 8 files changed, 210 insertions(+), 14 deletions(-) create mode 100644 tests/ui/privacy/suggest-making-field-public.fixed create mode 100644 tests/ui/privacy/suggest-making-field-public.rs create mode 100644 tests/ui/privacy/suggest-making-field-public.stderr diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 928f372d948dd..b1b04c92a7504 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -331,8 +331,15 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .iter() .map(|field| respan(field.span, field.ident.map_or(kw::Empty, |ident| ident.name))) .collect(); - let field_vis = vdata.fields().iter().map(|field| field.vis.span).collect(); self.r.field_names.insert(def_id, field_names); + } + + fn insert_field_visibilities_local(&mut self, def_id: DefId, vdata: &ast::VariantData) { + let field_vis = vdata + .fields() + .iter() + .map(|field| field.vis.span.until(field.ident.map_or(field.ty.span, |i| i.span))) + .collect(); self.r.field_visibility_spans.insert(def_id, field_vis); } @@ -739,6 +746,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // Record field names for error reporting. self.insert_field_names_local(def_id, vdata); + self.insert_field_visibilities_local(def_id, vdata); // If this is a tuple or unit struct, define a name // in the value namespace as well. @@ -772,6 +780,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { Res::Def(DefKind::Ctor(CtorOf::Struct, ctor_kind), ctor_def_id.to_def_id()); self.r.define(parent, ident, ValueNS, (ctor_res, ctor_vis, sp, expansion)); self.r.visibilities.insert(ctor_def_id, ctor_vis); + // We need the field visibility spans also for the constructor for E0603. + self.insert_field_visibilities_local(ctor_def_id.to_def_id(), vdata); self.r .struct_constructors @@ -785,6 +795,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { // Record field names for error reporting. self.insert_field_names_local(def_id, vdata); + self.insert_field_visibilities_local(def_id, vdata); } ItemKind::Trait(..) => { @@ -1512,6 +1523,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { // Record field names for error reporting. self.insert_field_names_local(def_id.to_def_id(), &variant.data); + self.insert_field_visibilities_local(def_id.to_def_id(), &variant.data); visit::walk_variant(self, variant); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7d62d67d64f07..1a852de8eed69 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -6,7 +6,9 @@ use rustc_ast::{self as ast, Crate, ItemKind, ModKind, NodeId, Path, CRATE_NODE_ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{ + pluralize, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, +}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PerNS}; @@ -1604,6 +1606,16 @@ impl<'a> Resolver<'a> { err.span_label(ident.span, &format!("private {}", descr)); if let Some(span) = ctor_fields_span { err.span_label(span, "a constructor is private if any of the fields is private"); + if let Res::Def(_, d) = res && let Some(fields) = self.field_visibility_spans.get(&d) { + err.multipart_suggestion_verbose( + &format!( + "consider making the field{} publicly accessible", + pluralize!(fields.len()) + ), + fields.iter().map(|span| (*span, "pub ".to_string())).collect(), + Applicability::MaybeIncorrect, + ); + } } // Print the whole import chain to make it easier to see what happens. diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6923ca7ef1bf4..d92f5a7c05e6d 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -1451,22 +1451,13 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { .collect(); if non_visible_spans.len() > 0 { - if let Some(visibility_spans) = self.r.field_visibility_spans.get(&def_id) { + if let Some(fields) = self.r.field_visibility_spans.get(&def_id) { err.multipart_suggestion_verbose( &format!( "consider making the field{} publicly accessible", - pluralize!(visibility_spans.len()) + pluralize!(fields.len()) ), - visibility_spans - .iter() - .map(|span| { - ( - *span, - if span.is_empty() { "pub " } else { "pub" } - .to_string(), - ) - }) - .collect(), + fields.iter().map(|span| (*span, "pub ".to_string())).collect(), Applicability::MaybeIncorrect, ); } diff --git a/tests/ui/privacy/privacy5.stderr b/tests/ui/privacy/privacy5.stderr index 680161272cefb..615b0af2762d3 100644 --- a/tests/ui/privacy/privacy5.stderr +++ b/tests/ui/privacy/privacy5.stderr @@ -12,6 +12,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:52:16 @@ -27,6 +31,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:53:16 @@ -42,6 +50,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:56:12 @@ -57,6 +69,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:57:12 @@ -72,6 +88,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:58:18 @@ -87,6 +107,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:59:18 @@ -102,6 +126,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:61:12 @@ -117,6 +145,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:62:12 @@ -132,6 +164,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:63:18 @@ -147,6 +183,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:64:18 @@ -162,6 +202,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:18 @@ -177,6 +221,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:32 @@ -192,6 +240,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:68:12 @@ -207,6 +259,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:69:12 @@ -222,6 +278,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:70:12 @@ -237,6 +297,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:71:12 @@ -252,6 +316,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:72:18 @@ -267,6 +335,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:73:18 @@ -282,6 +354,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:74:18 @@ -297,6 +373,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:75:18 @@ -312,6 +392,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:83:17 @@ -327,6 +411,10 @@ note: the tuple struct constructor `A` is defined here | LL | pub struct A(()); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub ()); + | +++ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:84:17 @@ -342,6 +430,10 @@ note: the tuple struct constructor `B` is defined here | LL | pub struct B(isize); | ^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct B(pub isize); + | +++ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:85:17 @@ -357,6 +449,10 @@ note: the tuple struct constructor `C` is defined here | LL | pub struct C(pub isize, isize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the fields publicly accessible + | +LL | pub struct C(pub isize, pub isize); + | ~~~ +++ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:90:20 diff --git a/tests/ui/privacy/suggest-making-field-public.fixed b/tests/ui/privacy/suggest-making-field-public.fixed new file mode 100644 index 0000000000000..78e335b3db1cb --- /dev/null +++ b/tests/ui/privacy/suggest-making-field-public.fixed @@ -0,0 +1,15 @@ +// run-rustfix +mod a { + pub struct A(pub String); +} + +mod b { + use crate::a::A; + pub fn x() { + A("".into()); //~ ERROR cannot initialize a tuple struct which contains private fields + } +} +fn main() { + a::A("a".into()); //~ ERROR tuple struct constructor `A` is private + b::x(); +} diff --git a/tests/ui/privacy/suggest-making-field-public.rs b/tests/ui/privacy/suggest-making-field-public.rs new file mode 100644 index 0000000000000..b65c801d10e6a --- /dev/null +++ b/tests/ui/privacy/suggest-making-field-public.rs @@ -0,0 +1,15 @@ +// run-rustfix +mod a { + pub struct A(pub(self)String); +} + +mod b { + use crate::a::A; + pub fn x() { + A("".into()); //~ ERROR cannot initialize a tuple struct which contains private fields + } +} +fn main() { + a::A("a".into()); //~ ERROR tuple struct constructor `A` is private + b::x(); +} diff --git a/tests/ui/privacy/suggest-making-field-public.stderr b/tests/ui/privacy/suggest-making-field-public.stderr new file mode 100644 index 0000000000000..e92e9aae310e3 --- /dev/null +++ b/tests/ui/privacy/suggest-making-field-public.stderr @@ -0,0 +1,39 @@ +error[E0603]: tuple struct constructor `A` is private + --> $DIR/suggest-making-field-public.rs:13:8 + | +LL | pub struct A(pub(self)String); + | --------------- a constructor is private if any of the fields is private +... +LL | a::A("a".into()); + | ^ private tuple struct constructor + | +note: the tuple struct constructor `A` is defined here + --> $DIR/suggest-making-field-public.rs:3:5 + | +LL | pub struct A(pub(self)String); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct A(pub String); + | ~~~ + +error[E0423]: cannot initialize a tuple struct which contains private fields + --> $DIR/suggest-making-field-public.rs:9:9 + | +LL | A("".into()); + | ^ + | +note: constructor is not visible here due to private fields + --> $DIR/suggest-making-field-public.rs:3:18 + | +LL | pub struct A(pub(self)String); + | ^^^^^^^^^^^^^^^ private field +help: consider making the field publicly accessible + | +LL | pub struct A(pub String); + | ~~~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0423, E0603. +For more information about an error, try `rustc --explain E0423`. diff --git a/tests/ui/resolve/privacy-struct-ctor.stderr b/tests/ui/resolve/privacy-struct-ctor.stderr index 17a666a401ce8..c1fcaaf05738f 100644 --- a/tests/ui/resolve/privacy-struct-ctor.stderr +++ b/tests/ui/resolve/privacy-struct-ctor.stderr @@ -53,6 +53,10 @@ note: the tuple struct constructor `Z` is defined here | LL | pub(in m) struct Z(pub(in m::n) u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub(in m) struct Z(pub u8); + | ~~~ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:29:8 @@ -68,6 +72,10 @@ note: the tuple struct constructor `S` is defined here | LL | pub struct S(u8); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct S(pub u8); + | +++ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:31:19 @@ -83,6 +91,10 @@ note: the tuple struct constructor `S` is defined here | LL | pub struct S(u8); | ^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub struct S(pub u8); + | +++ error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:35:11 @@ -98,6 +110,10 @@ note: the tuple struct constructor `Z` is defined here | LL | pub(in m) struct Z(pub(in m::n) u8); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: consider making the field publicly accessible + | +LL | pub(in m) struct Z(pub u8); + | ~~~ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:41:16