Skip to content

Commit ad13d9f

Browse files
committed
Suggest making private tuple struct field public
Fix #52144.
1 parent b22c152 commit ad13d9f

File tree

8 files changed

+49
-6
lines changed

8 files changed

+49
-6
lines changed

compiler/rustc_resolve/src/build_reduced_graph.rs

+2
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
331331
.iter()
332332
.map(|field| respan(field.span, field.ident.map_or(kw::Empty, |ident| ident.name)))
333333
.collect();
334+
let field_vis = vdata.fields().iter().map(|field| field.vis.span).collect();
334335
self.r.field_names.insert(def_id, field_names);
336+
self.r.field_visibility_spans.insert(def_id, field_vis);
335337
}
336338

337339
fn insert_field_names_extern(&mut self, def_id: DefId) {

compiler/rustc_resolve/src/late/diagnostics.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,26 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
14511451
.collect();
14521452

14531453
if non_visible_spans.len() > 0 {
1454+
if let Some(visibility_spans) = self.r.field_visibility_spans.get(&def_id) {
1455+
err.multipart_suggestion_verbose(
1456+
&format!(
1457+
"consider making the field{} publicly accessible",
1458+
pluralize!(visibility_spans.len())
1459+
),
1460+
visibility_spans
1461+
.iter()
1462+
.map(|span| {
1463+
(
1464+
*span,
1465+
if span.lo() == span.hi() { "pub " } else { "pub" }
1466+
.to_string(),
1467+
)
1468+
})
1469+
.collect(),
1470+
Applicability::MaybeIncorrect,
1471+
);
1472+
}
1473+
14541474
let mut m: MultiSpan = non_visible_spans.clone().into();
14551475
non_visible_spans
14561476
.into_iter()

compiler/rustc_resolve/src/lib.rs

+5
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,10 @@ pub struct Resolver<'a> {
881881
/// Used for hints during error reporting.
882882
field_names: FxHashMap<DefId, Vec<Spanned<Symbol>>>,
883883

884+
/// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax.
885+
/// Used for hints during error reporting.
886+
field_visibility_spans: FxHashMap<DefId, Vec<Span>>,
887+
884888
/// All imports known to succeed or fail.
885889
determined_imports: Vec<&'a Import<'a>>,
886890

@@ -1268,6 +1272,7 @@ impl<'a> Resolver<'a> {
12681272

12691273
has_self: FxHashSet::default(),
12701274
field_names: FxHashMap::default(),
1275+
field_visibility_spans: FxHashMap::default(),
12711276

12721277
determined_imports: Vec::new(),
12731278
indeterminate_imports: Vec::new(),

tests/ui/privacy/issue-75906.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ note: constructor is not visible here due to private fields
99
|
1010
LL | pub struct Bar(u8);
1111
| ^^ private field
12+
help: consider making the field publicly accessible
13+
|
14+
LL | pub struct Bar(pub u8);
15+
| +++
1216

1317
error: aborting due to previous error
1418

tests/ui/privacy/issue-75907.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
mod foo {
44
pub(crate) struct Foo(u8);
5-
pub(crate) struct Bar(pub u8, u8, Foo);
5+
pub(crate) struct Bar(pub u8, pub(in crate::foo) u8, Foo);
66

77
pub(crate) fn make_bar() -> Bar {
88
Bar(1, 12, Foo(10))

tests/ui/privacy/issue-75907.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ LL | let Bar(x, y, Foo(z)) = make_bar();
1111
| ^ ^^^^^^ private field
1212
| |
1313
| private field
14+
help: consider making the fields publicly accessible
15+
|
16+
LL | pub(crate) struct Bar(pub u8, pub u8, pub Foo);
17+
| ~~~ ~~~ +++
1418

1519
error[E0532]: cannot match against a tuple struct which contains private fields
1620
--> $DIR/issue-75907.rs:15:19
@@ -23,6 +27,10 @@ note: constructor is not visible here due to private fields
2327
|
2428
LL | let Bar(x, y, Foo(z)) = make_bar();
2529
| ^ private field
30+
help: consider making the field publicly accessible
31+
|
32+
LL | pub(crate) struct Foo(pub u8);
33+
| +++
2634

2735
error: aborting due to 2 previous errors
2836

tests/ui/resolve/issue-42944.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
mod foo {
2-
pub struct Bx(());
2+
pub struct Bx(pub(in crate::foo) ());
33
}
44

55
mod bar {

tests/ui/resolve/issue-42944.stderr

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ LL | Bx(());
77
note: tuple struct `foo::Bx` exists but is inaccessible
88
--> $DIR/issue-42944.rs:2:5
99
|
10-
LL | pub struct Bx(());
11-
| ^^^^^^^^^^^^^^^^^^ not accessible
10+
LL | pub struct Bx(pub(in crate::foo) ());
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible
1212

1313
error[E0423]: cannot initialize a tuple struct which contains private fields
1414
--> $DIR/issue-42944.rs:9:9
@@ -19,8 +19,12 @@ LL | Bx(());
1919
note: constructor is not visible here due to private fields
2020
--> $DIR/issue-42944.rs:2:19
2121
|
22-
LL | pub struct Bx(());
23-
| ^^ private field
22+
LL | pub struct Bx(pub(in crate::foo) ());
23+
| ^^^^^^^^^^^^^^^^^^^^^ private field
24+
help: consider making the field publicly accessible
25+
|
26+
LL | pub struct Bx(pub ());
27+
| ~~~
2428

2529
error: aborting due to 2 previous errors
2630

0 commit comments

Comments
 (0)