diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index e625cf1f48841..d87c6032bd915 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -30,7 +30,7 @@ use rustc::hir::def::{self, DefKind, PartialRes, CtorKind, CtorOf, NonMacroAttrK use rustc::hir::def::Namespace::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::hir::{TraitMap, GlobMap}; -use rustc::ty; +use rustc::ty::{self, DefIdTree}; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; use rustc::span_bug; @@ -1006,7 +1006,7 @@ impl<'a> AsMut> for Resolver<'a> { fn as_mut(&mut self) -> &mut Resolver<'a> { self } } -impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> { +impl<'a, 'b> DefIdTree for &'a Resolver<'b> { fn parent(self, id: DefId) -> Option { match id.krate { LOCAL_CRATE => self.definitions.def_key(id.index).parent, @@ -2391,23 +2391,17 @@ impl<'a> Resolver<'a> { binding.res().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"); + if let NameBindingKind::Res( + Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id), _ + ) = binding.kind { + let def_id = (&*self).parent(ctor_def_id).expect("no parent for a constructor"); + if let Some(fields) = self.field_names.get(&def_id) { + let first_field = fields.first().expect("empty field list in the map"); + err.span_label( + fields.iter().fold(first_field.span, |acc, field| acc.to(field.span)), + "a tuple struct 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 532d1ac1e2fb8..c1b90d7c6bf23 100644 --- a/src/test/ui/privacy/privacy5.stderr +++ b/src/test/ui/privacy/privacy5.stderr @@ -1,386 +1,482 @@ error[E0603]: tuple struct `A` is private --> $DIR/privacy5.rs:51:16 | +LL | pub struct A(()); + | -- a tuple struct constructor is private if any of its fields 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 | pub struct B(isize); + | ----- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct A(()); + | -- a tuple struct constructor is private if any of its fields 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 `A` is private --> $DIR/privacy5.rs:57:12 | +LL | pub struct A(()); + | -- a tuple struct constructor is private if any of its fields 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 `A` is private --> $DIR/privacy5.rs:58:18 | +LL | pub struct A(()); + | -- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct A(()); + | -- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct B(isize); + | ----- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct B(isize); + | ----- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct B(isize); + | ----- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct B(isize); + | ----- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct B(isize); + | ----- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct B(isize); + | ----- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct A(()); + | -- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct B(isize); + | ----- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct C(pub isize, isize); + | ---------------- a tuple struct constructor is private if any of its fields is private +... 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(()); | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct A(()); + | -- 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); | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct B(isize); + | ----- 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); | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct A(()); + | -- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct A(()); + | -- 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(()) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct A(()); + | -- 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(_) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct A(()); + | -- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct B(isize); + | ----- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct B(isize); + | ----- 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(_) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct B(isize); + | ----- 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) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct B(isize); + | ----- 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(_) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct B(isize); + | ----- 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(_) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct B(isize); + | ----- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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(_, _) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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, _) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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) => {} } | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct A(()); + | -- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct B(isize); + | ----- 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; | ^ + | + ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct C(pub isize, isize); + | ---------------- 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 979367bc623fd..d5311fde2e79e 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -37,50 +37,60 @@ LL | use m::S; error[E0603]: tuple struct `Z` is private --> $DIR/privacy-struct-ctor.rs:18:12 | +LL | pub(in m) struct Z(pub(in m::n) u8); + | --------------- a tuple struct constructor is private if any of its fields 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 | pub struct S(u8); + | -- a tuple struct constructor is private if any of its fields is private +... 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 | pub struct S(u8); + | -- a tuple struct constructor is private if any of its fields is private +... 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 | pub(in m) struct Z(pub(in m::n) u8); + | --------------- a tuple struct constructor is private if any of its fields is private +... 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; | ^ + | + ::: $DIR/auxiliary/privacy-struct-ctor.rs:2:18 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct S(u8); + | -- 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; | ^ + | + ::: $DIR/auxiliary/privacy-struct-ctor.rs:5:28 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub(in m) struct Z(pub(in m::n) u8); + | --------------- 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 d75a376286fcc..15f97f7e1d6f8 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr @@ -15,8 +15,11 @@ error[E0603]: tuple struct `TupleStruct` is private | LL | let ts_explicit = structs::TupleStruct(640, 480); | ^^^^^^^^^^^ + | + ::: $DIR/auxiliary/structs.rs:13:24 | - = note: a tuple struct constructor is private if any of its fields is private +LL | pub struct TupleStruct(pub u16, pub u16); + | ---------------- 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 ac0025ec75807..d9d6ea21b8bd4 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr @@ -3,8 +3,6 @@ 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 @@ -23,16 +21,12 @@ 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