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 ```
This commit is contained in:
parent
3e99055c40
commit
bbcf26fc33
5 changed files with 44 additions and 4 deletions
|
@ -1,4 +1,5 @@
|
||||||
privacy_field_is_private = field `{$field_name}` of {$variant_descr} `{$def_path_str}` is private
|
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_is_update_syntax_label = field `{$field_name}` is private
|
||||||
privacy_field_is_private_label = private field
|
privacy_field_is_private_label = private field
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ use rustc_span::{Span, Symbol};
|
||||||
pub(crate) struct FieldIsPrivate {
|
pub(crate) struct FieldIsPrivate {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
#[label]
|
||||||
|
pub struct_span: Option<Span>,
|
||||||
pub field_name: Symbol,
|
pub field_name: Symbol,
|
||||||
pub variant_descr: &'static str,
|
pub variant_descr: &'static str,
|
||||||
pub def_path_str: String,
|
pub def_path_str: String,
|
||||||
|
|
|
@ -925,6 +925,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
|
||||||
def: ty::AdtDef<'tcx>, // definition of the struct or enum
|
def: ty::AdtDef<'tcx>, // definition of the struct or enum
|
||||||
field: &'tcx ty::FieldDef,
|
field: &'tcx ty::FieldDef,
|
||||||
in_update_syntax: bool,
|
in_update_syntax: bool,
|
||||||
|
struct_span: Span,
|
||||||
) {
|
) {
|
||||||
if def.is_enum() {
|
if def.is_enum() {
|
||||||
return;
|
return;
|
||||||
|
@ -936,6 +937,11 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
|
||||||
if !field.vis.is_accessible_from(def_id, self.tcx) {
|
if !field.vis.is_accessible_from(def_id, self.tcx) {
|
||||||
self.tcx.dcx().emit_err(FieldIsPrivate {
|
self.tcx.dcx().emit_err(FieldIsPrivate {
|
||||||
span,
|
span,
|
||||||
|
struct_span: if self.tcx.sess.source_map().is_multiline(span.between(struct_span)) {
|
||||||
|
Some(struct_span)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
field_name: field.name,
|
field_name: field.name,
|
||||||
variant_descr: def.variant_descr(),
|
variant_descr: def.variant_descr(),
|
||||||
def_path_str: self.tcx.def_path_str(def.did()),
|
def_path_str: self.tcx.def_path_str(def.did()),
|
||||||
|
@ -955,6 +961,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
|
||||||
fields: &[hir::ExprField<'tcx>],
|
fields: &[hir::ExprField<'tcx>],
|
||||||
hir_id: hir::HirId,
|
hir_id: hir::HirId,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
struct_span: Span,
|
||||||
) {
|
) {
|
||||||
for (vf_index, variant_field) in variant.fields.iter_enumerated() {
|
for (vf_index, variant_field) in variant.fields.iter_enumerated() {
|
||||||
let field =
|
let field =
|
||||||
|
@ -963,7 +970,7 @@ impl<'tcx> NamePrivacyVisitor<'tcx> {
|
||||||
Some(field) => (field.hir_id, field.ident.span, field.span),
|
Some(field) => (field.hir_id, field.ident.span, field.span),
|
||||||
None => (hir_id, span, 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
// 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
|
// are checked for privacy (RFC 736). Rather than computing the set of
|
||||||
// unmentioned fields, just check them all.
|
// 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) => {
|
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 => {
|
hir::StructTailExpr::None => {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
|
@ -1006,6 +1027,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
|
||||||
adt,
|
adt,
|
||||||
&variant.fields[index],
|
&variant.fields[index],
|
||||||
false,
|
false,
|
||||||
|
qpath.span(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1023,7 +1045,15 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> {
|
||||||
for field in fields {
|
for field in fields {
|
||||||
let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span);
|
let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span);
|
||||||
let index = self.typeck_results().field_index(field.hir_id);
|
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(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -739,6 +739,9 @@ LL | _)
|
||||||
error[E0451]: field `i` of struct `this_crate::nested::DeprecatedStruct` is private
|
error[E0451]: field `i` of struct `this_crate::nested::DeprecatedStruct` is private
|
||||||
--> $DIR/deprecation-lint.rs:280:13
|
--> $DIR/deprecation-lint.rs:280:13
|
||||||
|
|
|
|
||||||
|
LL | let _ = nested::DeprecatedStruct {
|
||||||
|
| ------------------------ in this type
|
||||||
|
LL |
|
||||||
LL | i: 0
|
LL | i: 0
|
||||||
| ^^^^ private field
|
| ^^^^ private field
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
error[E0451]: field `x` of struct `S` is private
|
error[E0451]: field `x` of struct `S` is private
|
||||||
--> $DIR/visibility.rs:24:9
|
--> $DIR/visibility.rs:24:9
|
||||||
|
|
|
|
||||||
|
LL | let a = baz::S {
|
||||||
|
| ------ in this type
|
||||||
LL | ..
|
LL | ..
|
||||||
| ^^ field `x` is private
|
| ^^ field `x` is private
|
||||||
|
|
||||||
error[E0451]: field `x` of struct `S` is private
|
error[E0451]: field `x` of struct `S` is private
|
||||||
--> $DIR/visibility.rs:27:9
|
--> $DIR/visibility.rs:27:9
|
||||||
|
|
|
|
||||||
|
LL | let b = baz::S {
|
||||||
|
| ------ in this type
|
||||||
LL | x: 0,
|
LL | x: 0,
|
||||||
| ^^^^ private field
|
| ^^^^ private field
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue