diff options
| -rw-r--r-- | compiler/rustc_resolve/src/build_reduced_graph.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/diagnostics.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 5 | ||||
| -rw-r--r-- | tests/ui/privacy/issue-75906.stderr | 4 | ||||
| -rw-r--r-- | tests/ui/privacy/issue-75907.rs | 2 | ||||
| -rw-r--r-- | tests/ui/privacy/issue-75907.stderr | 8 | ||||
| -rw-r--r-- | tests/ui/resolve/issue-42944.rs | 2 | ||||
| -rw-r--r-- | 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 58f6fd2b006..928f372d948 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 74522f18542..a675a1fb78b 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 2182b736937..84d9794ccf2 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<DefId, Vec<Spanned<Symbol>>>, + /// 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<DefId, Vec<Span>>, + /// 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 4c6a68646ad..600dc7c876f 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 6da99cf6435..3bed841d13e 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 2f89e31a31a..f7cb874c2cc 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 a4404857a56..7e439c10b7b 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 0ee9fd391fe..4ffa9402c66 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 |
