diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl index 7785f1a7f81fb..5b5c10d448aa9 100644 --- a/compiler/rustc_privacy/messages.ftl +++ b/compiler/rustc_privacy/messages.ftl @@ -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 diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index f5e641eb64243..23181f63a286a 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -8,6 +8,8 @@ use rustc_span::{Span, Symbol}; pub(crate) struct FieldIsPrivate { #[primary_span] pub span: Span, + #[label] + pub struct_span: Option, pub field_name: Symbol, pub variant_descr: &'static str, pub def_path_str: String, diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index e484cfed06b33..6ec735990053b 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -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; @@ -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()), @@ -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 = @@ -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); } } } @@ -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 { @@ -1006,6 +1027,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { adt, &variant.fields[index], false, + qpath.span(), ); } } @@ -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(), + ); } } diff --git a/tests/ui/deprecation/deprecation-lint.stderr b/tests/ui/deprecation/deprecation-lint.stderr index 2098073409da5..075bb42fa9a7a 100644 --- a/tests/ui/deprecation/deprecation-lint.stderr +++ b/tests/ui/deprecation/deprecation-lint.stderr @@ -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 diff --git a/tests/ui/structs/default-field-values/visibility.stderr b/tests/ui/structs/default-field-values/visibility.stderr index 63721d79be5bb..666782933d3fd 100644 --- a/tests/ui/structs/default-field-values/visibility.stderr +++ b/tests/ui/structs/default-field-values/visibility.stderr @@ -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