Skip to content

Commit bbcf26f

Browse files
committed
Add context on private fields that are not on the same line as the struct name
``` error[E0451]: field `x` of struct `S` is private --> $DIR/visibility.rs:24:9 | LL | let a = baz::S { | ------ in this type LL | .. | ^^ field `x` is private ```
1 parent 3e99055 commit bbcf26f

File tree

5 files changed

+44
-4
lines changed

5 files changed

+44
-4
lines changed

compiler/rustc_privacy/messages.ftl

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
2+
.label = in this type
23
privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private
34
privacy_field_is_private_label = private field
45

compiler/rustc_privacy/src/errors.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use rustc_span::{Span, Symbol};
88
pub(crate) struct FieldIsPrivate {
99
#[primary_span]
1010
pub span: Span,
11+
#[label]
12+
pub struct_span: Option<Span>,
1113
pub field_name: Symbol,
1214
pub variant_descr: &'static str,
1315
pub def_path_str: String,

compiler/rustc_privacy/src/lib.rs

+34-4
Original file line numberDiff line numberDiff line change
@@ -925,6 +925,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
925925
def: ty::AdtDef<'tcx>, // definition of the struct or enum
926926
field: &'tcx ty::FieldDef,
927927
in_update_syntax: bool,
928+
struct_span: Span,
928929
) {
929930
if def.is_enum() {
930931
return;
@@ -936,6 +937,11 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
936937
if !field.vis.is_accessible_from(def_id, self.tcx) {
937938
self.tcx.dcx().emit_err(FieldIsPrivate {
938939
span,
940+
struct_span: if self.tcx.sess.source_map().is_multiline(span.between(struct_span)) {
941+
Some(struct_span)
942+
} else {
943+
None
944+
},
939945
field_name: field.name,
940946
variant_descr: def.variant_descr(),
941947
def_path_str: self.tcx.def_path_str(def.did()),
@@ -955,6 +961,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
955961
fields: &[hir::ExprField<'tcx>],
956962
hir_id: hir::HirId,
957963
span: Span,
964+
struct_span: Span,
958965
) {
959966
for (vf_index, variant_field) in variant.fields.iter_enumerated() {
960967
let field =
@@ -963,7 +970,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
963970
Some(field) => (field.hir_id, field.ident.span, field.span),
964971
None => (hir_id, span, span),
965972
};
966-
self.check_field(hir_id, use_ctxt, span, adt, variant_field, true);
973+
self.check_field(hir_id, use_ctxt, span, adt, variant_field, true, struct_span);
967974
}
968975
}
969976
}
@@ -990,10 +997,24 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
990997
// If the expression uses FRU we need to make sure all the unmentioned fields
991998
// are checked for privacy (RFC 736). Rather than computing the set of
992999
// unmentioned fields, just check them all.
993-
self.check_expanded_fields(adt, variant, fields, base.hir_id, base.span);
1000+
self.check_expanded_fields(
1001+
adt,
1002+
variant,
1003+
fields,
1004+
base.hir_id,
1005+
base.span,
1006+
qpath.span(),
1007+
);
9941008
}
9951009
hir::StructTailExpr::DefaultFields(span) => {
996-
self.check_expanded_fields(adt, variant, fields, expr.hir_id, span);
1010+
self.check_expanded_fields(
1011+
adt,
1012+
variant,
1013+
fields,
1014+
expr.hir_id,
1015+
span,
1016+
qpath.span(),
1017+
);
9971018
}
9981019
hir::StructTailExpr::None => {
9991020
for field in fields {
@@ -1006,6 +1027,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
10061027
adt,
10071028
&variant.fields[index],
10081029
false,
1030+
qpath.span(),
10091031
);
10101032
}
10111033
}
@@ -1023,7 +1045,15 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
10231045
for field in fields {
10241046
let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span);
10251047
let index = self.typeck_results().field_index(field.hir_id);
1026-
self.check_field(hir_id, use_ctxt, span, adt, &variant.fields[index], false);
1048+
self.check_field(
1049+
hir_id,
1050+
use_ctxt,
1051+
span,
1052+
adt,
1053+
&variant.fields[index],
1054+
false,
1055+
qpath.span(),
1056+
);
10271057
}
10281058
}
10291059

tests/ui/deprecation/deprecation-lint.stderr

+3
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,9 @@ LL | _)
739739
error[E0451]: field `i` of struct `this_crate::nested::DeprecatedStruct` is private
740740
--> $DIR/deprecation-lint.rs:280:13
741741
|
742+
LL | let _ = nested::DeprecatedStruct {
743+
| ------------------------ in this type
744+
LL |
742745
LL | i: 0
743746
| ^^^^ private field
744747

tests/ui/structs/default-field-values/visibility.stderr

+4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
error[E0451]: field `x` of struct `S` is private
22
--> $DIR/visibility.rs:24:9
33
|
4+
LL | let a = baz::S {
5+
| ------ in this type
46
LL | ..
57
| ^^ field `x` is private
68

79
error[E0451]: field `x` of struct `S` is private
810
--> $DIR/visibility.rs:27:9
911
|
12+
LL | let b = baz::S {
13+
| ------ in this type
1014
LL | x: 0,
1115
| ^^^^ private field
1216

0 commit comments

Comments
 (0)