Skip to content

Commit

Permalink
Add context on private fields that are not on the same line as the st…
Browse files Browse the repository at this point in the history
…ruct 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
```
  • Loading branch information
estebank committed Jan 18, 2025
1 parent 3e99055 commit bbcf26f
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 4 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_privacy/messages.ftl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
.label = in this type
privacy_field_is_private_is_update_syntax_label = field `{$field_name}` is private
privacy_field_is_private_label = private field
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_privacy/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use rustc_span::{Span, Symbol};
pub(crate) struct FieldIsPrivate {
#[primary_span]
pub span: Span,
#[label]
pub struct_span: Option<Span>,
pub field_name: Symbol,
pub variant_descr: &'static str,
pub def_path_str: String,
Expand Down
38 changes: 34 additions & 4 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
def: ty::AdtDef<'tcx>, // definition of the struct or enum
field: &'tcx ty::FieldDef,
in_update_syntax: bool,
struct_span: Span,
) {
if def.is_enum() {
return;
Expand All @@ -936,6 +937,11 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
if !field.vis.is_accessible_from(def_id, self.tcx) {
self.tcx.dcx().emit_err(FieldIsPrivate {
span,
struct_span: if self.tcx.sess.source_map().is_multiline(span.between(struct_span)) {
Some(struct_span)
} else {
None
},
field_name: field.name,
variant_descr: def.variant_descr(),
def_path_str: self.tcx.def_path_str(def.did()),
Expand All @@ -955,6 +961,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
fields: &[hir::ExprField<'tcx>],
hir_id: hir::HirId,
span: Span,
struct_span: Span,
) {
for (vf_index, variant_field) in variant.fields.iter_enumerated() {
let field =
Expand All @@ -963,7 +970,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
Some(field) => (field.hir_id, field.ident.span, field.span),
None => (hir_id, span, span),
};
self.check_field(hir_id, use_ctxt, span, adt, variant_field, true);
self.check_field(hir_id, use_ctxt, span, adt, variant_field, true, struct_span);
}
}
}
Expand All @@ -990,10 +997,24 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
// If the expression uses FRU we need to make sure all the unmentioned fields
// are checked for privacy (RFC 736). Rather than computing the set of
// unmentioned fields, just check them all.
self.check_expanded_fields(adt, variant, fields, base.hir_id, base.span);
self.check_expanded_fields(
adt,
variant,
fields,
base.hir_id,
base.span,
qpath.span(),
);
}
hir::StructTailExpr::DefaultFields(span) => {
self.check_expanded_fields(adt, variant, fields, expr.hir_id, span);
self.check_expanded_fields(
adt,
variant,
fields,
expr.hir_id,
span,
qpath.span(),
);
}
hir::StructTailExpr::None => {
for field in fields {
Expand All @@ -1006,6 +1027,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
adt,
&variant.fields[index],
false,
qpath.span(),
);
}
}
Expand All @@ -1023,7 +1045,15 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
for field in fields {
let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span);
let index = self.typeck_results().field_index(field.hir_id);
self.check_field(hir_id, use_ctxt, span, adt, &variant.fields[index], false);
self.check_field(
hir_id,
use_ctxt,
span,
adt,
&variant.fields[index],
false,
qpath.span(),
);
}
}

Expand Down
3 changes: 3 additions & 0 deletions tests/ui/deprecation/deprecation-lint.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,9 @@ LL | _)
error[E0451]: field `i` of struct `this_crate::nested::DeprecatedStruct` is private
--> $DIR/deprecation-lint.rs:280:13
|
LL | let _ = nested::DeprecatedStruct {
| ------------------------ in this type
LL |
LL | i: 0
| ^^^^ private field

Expand Down
4 changes: 4 additions & 0 deletions tests/ui/structs/default-field-values/visibility.stderr
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
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

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

Expand Down

0 comments on commit bbcf26f

Please sign in to comment.