From b9865d9e3fdd87a5b7e45153effef3055d85f70e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 9 Aug 2019 12:52:02 -0700 Subject: [PATCH] Mention that tuple structs are private if their fields are --- src/librustc_resolve/lib.rs | 31 +++++- src/test/ui/privacy/privacy5.stderr | 96 +++++++++++++++++++ .../ui/resolve/privacy-struct-ctor.stderr | 12 +++ .../ui/rfc-2008-non-exhaustive/struct.stderr | 2 + .../ui/rfc-2008-non-exhaustive/variant.stderr | 6 ++ 5 files changed, 144 insertions(+), 3 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e7feccf506957..ce2bc79ff6034 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -50,7 +50,7 @@ use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind}; use syntax::ast::{Label, Local, Mutability, Pat, PatKind, Path}; use syntax::ast::{QSelf, TraitItem, TraitItemKind, TraitRef, Ty, TyKind}; use syntax::ptr::P; -use syntax::{span_err, struct_span_err, unwrap_or, walk_list}; +use syntax::{struct_span_err, unwrap_or, walk_list}; use syntax_pos::{Span, DUMMY_SP, MultiSpan}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; @@ -4789,8 +4789,33 @@ impl<'a> Resolver<'a> { let mut reported_spans = FxHashSet::default(); for &PrivacyError(dedup_span, ident, binding) in &self.privacy_errors { if reported_spans.insert(dedup_span) { - span_err!(self.session, ident.span, E0603, "{} `{}` is private", - binding.descr(), ident.name); + let mut err = struct_span_err!( + self.session, + ident.span, + E0603, + "{} `{}` is private", + binding.descr(), + ident.name, + ); + // FIXME: use the ctor's `def_id` to check wether any of the fields is not visible + match binding.kind { + NameBindingKind::Res(Res::Def(DefKind::Ctor( + CtorOf::Struct, + CtorKind::Fn, + ), _def_id), _) => { + err.note("a tuple struct constructor is private if any of its fields \ + is private"); + } + NameBindingKind::Res(Res::Def(DefKind::Ctor( + CtorOf::Variant, + CtorKind::Fn, + ), _def_id), _) => { + err.note("a tuple variant constructor is private if any of its fields \ + is private"); + } + _ => {} + } + err.emit(); } } } diff --git a/src/test/ui/privacy/privacy5.stderr b/src/test/ui/privacy/privacy5.stderr index 7568c346b2489..532d1ac1e2fb8 100644 --- a/src/test/ui/privacy/privacy5.stderr +++ b/src/test/ui/privacy/privacy5.stderr @@ -3,288 +3,384 @@ error[E0603]: tuple struct `A` is private | LL | let a = a::A(()); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:52:16 | LL | let b = a::B(2); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:53:16 | LL | let c = a::C(2, 3); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:56:12 | LL | let a::A(()) = a; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:57:12 | LL | let a::A(_) = a; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:58:18 | LL | match a { a::A(()) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:59:18 | LL | match a { a::A(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:61:12 | LL | let a::B(_) = b; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:62:12 | LL | let a::B(_b) = b; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:63:18 | LL | match b { a::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:64:18 | LL | match b { a::B(_b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:65:18 | LL | match b { a::B(1) => {} a::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:65:32 | LL | match b { a::B(1) => {} a::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:68:12 | LL | let a::C(_, _) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:69:12 | LL | let a::C(_a, _) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:70:12 | LL | let a::C(_, _b) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:71:12 | LL | let a::C(_a, _b) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:72:18 | LL | match c { a::C(_, _) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:73:18 | LL | match c { a::C(_a, _) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:74:18 | LL | match c { a::C(_, _b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:75:18 | LL | match c { a::C(_a, _b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:83:17 | LL | let a2 = a::A; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:84:17 | LL | let b2 = a::B; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:85:17 | LL | let c2 = a::C; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:90:20 | LL | let a = other::A(()); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:91:20 | LL | let b = other::B(2); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:92:20 | LL | let c = other::C(2, 3); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:95:16 | LL | let other::A(()) = a; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:96:16 | LL | let other::A(_) = a; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:97:22 | LL | match a { other::A(()) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:98:22 | LL | match a { other::A(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:100:16 | LL | let other::B(_) = b; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:101:16 | LL | let other::B(_b) = b; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:102:22 | LL | match b { other::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:103:22 | LL | match b { other::B(_b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:104:22 | LL | match b { other::B(1) => {} other::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:104:40 | LL | match b { other::B(1) => {} other::B(_) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:107:16 | LL | let other::C(_, _) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:108:16 | LL | let other::C(_a, _) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:109:16 | LL | let other::C(_, _b) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:110:16 | LL | let other::C(_a, _b) = c; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:111:22 | LL | match c { other::C(_, _) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:112:22 | LL | match c { other::C(_a, _) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:113:22 | LL | match c { other::C(_, _b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:114:22 | LL | match c { other::C(_a, _b) => {} } | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:122:21 | LL | let a2 = other::A; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `B` is private --> $DIR/privacy5.rs:123:21 | LL | let b2 = other::B; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `C` is private --> $DIR/privacy5.rs:124:21 | LL | let c2 = other::C; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error: aborting due to 48 previous errors diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index 9bf7d19117448..72d62fe45ce74 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -34,36 +34,48 @@ error[E0603]: tuple struct `Z` is private | LL | n::Z; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `S` is private --> $DIR/privacy-struct-ctor.rs:29:8 | LL | m::S; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `S` is private --> $DIR/privacy-struct-ctor.rs:31:19 | LL | let _: S = m::S(2); | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `Z` is private --> $DIR/privacy-struct-ctor.rs:35:11 | LL | m::n::Z; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `S` is private --> $DIR/privacy-struct-ctor.rs:41:16 | LL | xcrate::m::S; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: tuple struct `Z` is private --> $DIR/privacy-struct-ctor.rs:45:19 | LL | xcrate::m::n::Z; | ^ + | + = note: a tuple struct constructor is private if any of its fields is private error: aborting due to 10 previous errors diff --git a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr index 96040f11b525f..d75a376286fcc 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr @@ -15,6 +15,8 @@ error[E0603]: tuple struct `TupleStruct` is private | LL | let ts_explicit = structs::TupleStruct(640, 480); | ^^^^^^^^^^^ + | + = note: a tuple struct constructor is private if any of its fields is private error[E0603]: unit struct `UnitStruct` is private --> $DIR/struct.rs:32:32 diff --git a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr index d9d6ea21b8bd4..ac0025ec75807 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr @@ -3,6 +3,8 @@ error[E0603]: tuple variant `Tuple` is private | LL | let variant_tuple = NonExhaustiveVariants::Tuple(640); | ^^^^^ + | + = note: a tuple variant constructor is private if any of its fields is private error[E0603]: unit variant `Unit` is private --> $DIR/variant.rs:14:47 @@ -21,12 +23,16 @@ error[E0603]: tuple variant `Tuple` is private | LL | NonExhaustiveVariants::Tuple(fe_tpl) => "", | ^^^^^ + | + = note: a tuple variant constructor is private if any of its fields is private error[E0603]: tuple variant `Tuple` is private --> $DIR/variant.rs:26:35 | LL | if let NonExhaustiveVariants::Tuple(fe_tpl) = variant_struct { | ^^^^^ + | + = note: a tuple variant constructor is private if any of its fields is private error[E0639]: cannot create non-exhaustive variant using struct expression --> $DIR/variant.rs:8:26