diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 797371001d8..ee18968ff35 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -31,7 +31,7 @@ use rustc::hir::{self, PatKind}; use rustc::hir::def::{self, Def, CtorKind}; use rustc::hir::def_id::DefId; use rustc::hir::intravisit::{self, Visitor}; -use rustc::hir::itemlikevisit::ItemLikeVisitor; +use rustc::hir::itemlikevisit::DeepVisitor; use rustc::hir::pat_util::EnumerateAndAdjustIterator; use rustc::lint; use rustc::middle::privacy::{AccessLevel, AccessLevels}; @@ -899,126 +899,96 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_def_id: DefId, + span: Span, /// The visitor checks that each component type is at least this visible required_visibility: ty::Visibility, /// The visibility of the least visible component that has been visited min_visibility: ty::Visibility, - old_error_set: &'a NodeSet, + has_old_errors: bool, } impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { - fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, old_error_set: &'a NodeSet) -> Self { - SearchInterfaceForPrivateItemsVisitor { - tcx: tcx, - min_visibility: ty::Visibility::Public, - required_visibility: ty::Visibility::PrivateExternal, - old_error_set: old_error_set, - } + fn generics(&mut self) -> &mut Self { + self.tcx.item_generics(self.item_def_id).visit_with(self); + self + } + + fn predicates(&mut self) -> &mut Self { + self.tcx.item_predicates(self.item_def_id).visit_with(self); + self + } + + fn item_type(&mut self) -> &mut Self { + self.tcx.item_type(self.item_def_id).visit_with(self); + self + } + + fn impl_trait_ref(&mut self) -> &mut Self { + self.tcx.impl_trait_ref(self.item_def_id).visit_with(self); + self } } -impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { - // Return the visibility of the type alias's least visible component type when substituted - fn substituted_alias_visibility(&self, item: &hir::Item, segment: &hir::PathSegment) - -> Option { - // Type alias is considered public if the aliased type is - // public, even if the type alias itself is private. So, something - // like `type A = u8; pub fn f() -> A {...}` doesn't cause an error. - if let hir::ItemTy(ref ty, ref generics) = item.node { - let mut check = SearchInterfaceForPrivateItemsVisitor::new(self.tcx, - self.old_error_set); - check.visit_ty(ty); - // If a private type alias with default type parameters is used in public - // interface we must ensure, that the defaults are public if they are actually used. - // ``` - // type Alias = T; - // pub fn f() -> Alias {...} // `Private` is implicitly used here, so it must be public - // ``` - let provided_params = segment.parameters.types().len(); - for ty_param in &generics.ty_params[provided_params..] { - if let Some(ref default_ty) = ty_param.default { - check.visit_ty(default_ty); - } - } - Some(check.min_visibility) - } else { - None - } - } -} - -impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { - fn visit_ty(&mut self, ty: &hir::Ty) { - let def_and_segment = match ty.node { - hir::TyPath(hir::QPath::Resolved(_, ref path)) => { - Some((path.def, path.segments.last().unwrap())) - } - hir::TyPath(hir::QPath::TypeRelative(_, ref segment)) => { - Some((self.tcx.tables().type_relative_path_defs[&ty.id], &**segment)) - } - _ => None - }; - if let Some((def, segment)) = def_and_segment { - match def { - Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) => { - // Public - } - Def::AssociatedTy(..) - if self.required_visibility == ty::Visibility::PrivateExternal => { +impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { + fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool { + let ty_def_id = match ty.sty { + ty::TyAdt(adt, _) => Some(adt.did), + ty::TyTrait(ref obj) => Some(obj.principal.def_id()), + ty::TyProjection(ref proj) => { + if self.required_visibility == ty::Visibility::PrivateExternal { // Conservatively approximate the whole type alias as public without // recursing into its components when determining impl publicity. // For example, `impl ::Alias {...}` may be a public impl // even if both `Type` and `Trait` are private. // Ideally, associated types should be substituted in the same way as // free type aliases, but this isn't done yet. - return + return false; } - Def::Struct(def_id) | Def::Union(def_id) | Def::Enum(def_id) | - Def::TyAlias(def_id) | Def::Trait(def_id) | Def::AssociatedTy(def_id) => { - // Non-local means public (private items can't leave their crate, modulo bugs) - if let Some(mut node_id) = self.tcx.map.as_local_node_id(def_id) { - // Check the trait for associated types. - if let hir::map::NodeTraitItem(_) = self.tcx.map.get(node_id) { - node_id = self.tcx.map.get_parent(node_id); - } - let item = self.tcx.map.expect_item(node_id); - let vis = match self.substituted_alias_visibility(item, segment) { - Some(vis) => vis, - None => ty::Visibility::from_hir(&item.vis, node_id, self.tcx), - }; + Some(proj.trait_ref.def_id) + } + _ => None + }; - if !vis.is_at_least(self.min_visibility, &self.tcx.map) { - self.min_visibility = vis; - } - if !vis.is_at_least(self.required_visibility, &self.tcx.map) { - if self.tcx.sess.features.borrow().pub_restricted || - self.old_error_set.contains(&ty.id) { - let mut err = struct_span_err!(self.tcx.sess, ty.span, E0446, - "private type in public interface"); - err.span_label(ty.span, &format!("can't leak private type")); - err.emit(); - } else { - self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC, - node_id, - ty.span, - format!("private type in public \ - interface (error E0446)")); - } - } + if let Some(def_id) = ty_def_id { + // Non-local means public (private items can't leave their crate, modulo bugs) + if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { + let item = self.tcx.map.expect_item(node_id); + let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx); + + if !vis.is_at_least(self.min_visibility, &self.tcx.map) { + self.min_visibility = vis; + } + if !vis.is_at_least(self.required_visibility, &self.tcx.map) { + if self.tcx.sess.features.borrow().pub_restricted || self.has_old_errors { + let mut err = struct_span_err!(self.tcx.sess, self.span, E0446, + "private type `{}` in public interface", ty); + err.span_label(self.span, &format!("can't leak private type")); + err.emit(); + } else { + self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC, + node_id, + self.span, + format!("private type `{}` in public \ + interface (error E0446)", ty)); } } - _ => {} } } - intravisit::walk_ty(self, ty); + if let ty::TyProjection(ref proj) = ty.sty { + // Avoid calling `visit_trait_ref` below on the trait, + // as we have already checked the trait itself above. + proj.trait_ref.super_visit_with(self) + } else { + ty.super_visit_with(self) + } } - fn visit_trait_ref(&mut self, trait_ref: &hir::TraitRef) { + fn visit_trait_ref(&mut self, trait_ref: ty::TraitRef<'tcx>) -> bool { // Non-local means public (private items can't leave their crate, modulo bugs) - let def_id = trait_ref.path.def.def_id(); - if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { + if let Some(node_id) = self.tcx.map.as_local_node_id(trait_ref.def_id) { let item = self.tcx.map.expect_item(node_id); let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx); @@ -1026,63 +996,77 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, self.min_visibility = vis; } if !vis.is_at_least(self.required_visibility, &self.tcx.map) { - if self.tcx.sess.features.borrow().pub_restricted || - self.old_error_set.contains(&trait_ref.ref_id) { - struct_span_err!(self.tcx.sess, trait_ref.path.span, E0445, - "private trait in public interface") - .span_label(trait_ref.path.span, &format!( + if self.tcx.sess.features.borrow().pub_restricted || self.has_old_errors { + struct_span_err!(self.tcx.sess, self.span, E0445, + "private trait `{}` in public interface", trait_ref) + .span_label(self.span, &format!( "private trait can't be public")) .emit(); } else { self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC, node_id, - trait_ref.path.span, - "private trait in public interface (error E0445)" - .to_string()); + self.span, + format!("private trait `{}` in public \ + interface (error E0445)", trait_ref)); } } } - intravisit::walk_trait_ref(self, trait_ref); + trait_ref.super_visit_with(self) } - - // Don't recurse into function bodies - fn visit_block(&mut self, _: &hir::Block) {} - // Don't recurse into expressions in array sizes or const initializers - fn visit_expr(&mut self, _: &hir::Expr) {} - // Don't recurse into patterns in function arguments - fn visit_pat(&mut self, _: &hir::Pat) {} } struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, old_error_set: &'a NodeSet, + inner_visibility: ty::Visibility, } impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { - // A type is considered public if it doesn't contain any private components - fn ty_visibility(&self, ty: &hir::Ty) -> ty::Visibility { - let mut check = SearchInterfaceForPrivateItemsVisitor::new(self.tcx, self.old_error_set); - check.visit_ty(ty); - check.min_visibility - } + fn check(&self, item_id: ast::NodeId, required_visibility: ty::Visibility) + -> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { + let mut has_old_errors = false; - // A trait reference is considered public if it doesn't contain any private components - fn trait_ref_visibility(&self, trait_ref: &hir::TraitRef) -> ty::Visibility { - let mut check = SearchInterfaceForPrivateItemsVisitor::new(self.tcx, self.old_error_set); - check.visit_trait_ref(trait_ref); - check.min_visibility + // Slow path taken only if there any errors in the crate. + for &id in self.old_error_set { + // Walk up the nodes until we find `item_id` (or we hit a root). + let mut id = id; + loop { + if id == item_id { + has_old_errors = true; + break; + } + let parent = self.tcx.map.get_parent_node(id); + if parent == id { + break; + } + id = parent; + } + + if has_old_errors { + break; + } + } + + SearchInterfaceForPrivateItemsVisitor { + tcx: self.tcx, + item_def_id: self.tcx.map.local_def_id(item_id), + span: self.tcx.map.span(item_id), + min_visibility: ty::Visibility::Public, + required_visibility: required_visibility, + has_old_errors: has_old_errors, + } } } -impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { +impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> { fn visit_item(&mut self, item: &hir::Item) { + let tcx = self.tcx; let min = |vis1: ty::Visibility, vis2| { - if vis1.is_at_least(vis2, &self.tcx.map) { vis2 } else { vis1 } + if vis1.is_at_least(vis2, &tcx.map) { vis2 } else { vis1 } }; - let mut check = SearchInterfaceForPrivateItemsVisitor::new(self.tcx, self.old_error_set); - let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, self.tcx); + let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, tcx); match item.node { // Crates are always public @@ -1093,56 +1077,87 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for PrivateItemsInPublicInterfacesVisitor hir::ItemUse(..) => {} // Subitems of these items have inherited publicity hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) | - hir::ItemEnum(..) | hir::ItemTrait(..) | hir::ItemTy(..) => { - check.required_visibility = item_visibility; - check.visit_item(item); + hir::ItemTy(..) => { + self.check(item.id, item_visibility).generics().predicates().item_type(); + + // Recurse for e.g. `impl Trait` (see `visit_ty`). + self.inner_visibility = item_visibility; + intravisit::walk_item(self, item); + } + hir::ItemTrait(.., ref trait_items) => { + self.check(item.id, item_visibility).generics().predicates(); + + for trait_item in trait_items { + let mut check = self.check(trait_item.id, item_visibility); + check.generics().predicates(); + + if let hir::TypeTraitItem(_, None) = trait_item.node { + // No type to visit. + } else { + check.item_type(); + } + } + } + hir::ItemEnum(ref def, _) => { + self.check(item.id, item_visibility).generics().predicates(); + + for variant in &def.variants { + for field in variant.node.data.fields() { + self.check(field.id, item_visibility).item_type(); + } + } } // Subitems of foreign modules have their own publicity hir::ItemForeignMod(ref foreign_mod) => { for foreign_item in &foreign_mod.items { - check.required_visibility = - ty::Visibility::from_hir(&foreign_item.vis, item.id, self.tcx); - check.visit_foreign_item(foreign_item); + let vis = ty::Visibility::from_hir(&foreign_item.vis, item.id, tcx); + self.check(foreign_item.id, vis).generics().predicates().item_type(); } } // Subitems of structs and unions have their own publicity - hir::ItemStruct(ref struct_def, ref generics) | - hir::ItemUnion(ref struct_def, ref generics) => { - check.required_visibility = item_visibility; - check.visit_generics(generics); + hir::ItemStruct(ref struct_def, _) | + hir::ItemUnion(ref struct_def, _) => { + self.check(item.id, item_visibility).generics().predicates(); for field in struct_def.fields() { - let field_visibility = ty::Visibility::from_hir(&field.vis, item.id, self.tcx); - check.required_visibility = min(item_visibility, field_visibility); - check.visit_struct_field(field); + let field_visibility = ty::Visibility::from_hir(&field.vis, item.id, tcx); + self.check(field.id, min(item_visibility, field_visibility)).item_type(); } } // The interface is empty hir::ItemDefaultImpl(..) => {} // An inherent impl is public when its type is public // Subitems of inherent impls have their own publicity - hir::ItemImpl(.., ref generics, None, ref ty, ref impl_item_refs) => { - let ty_vis = self.ty_visibility(ty); - check.required_visibility = ty_vis; - check.visit_generics(generics); + hir::ItemImpl(.., None, _, ref impl_item_refs) => { + let ty_vis = self.check(item.id, ty::Visibility::PrivateExternal) + .item_type().min_visibility; + self.check(item.id, ty_vis).generics().predicates(); for impl_item_ref in impl_item_refs { let impl_item = self.tcx.map.impl_item(impl_item_ref.id); let impl_item_vis = - ty::Visibility::from_hir(&impl_item.vis, item.id, self.tcx); - check.required_visibility = min(impl_item_vis, ty_vis); - check.visit_impl_item(impl_item); + ty::Visibility::from_hir(&impl_item.vis, item.id, tcx); + self.check(impl_item.id, min(impl_item_vis, ty_vis)) + .generics().predicates().item_type(); + + // Recurse for e.g. `impl Trait` (see `visit_ty`). + self.inner_visibility = impl_item_vis; + intravisit::walk_impl_item(self, impl_item); } } // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity - hir::ItemImpl(.., ref generics, Some(ref trait_ref), ref ty, ref impl_item_refs) => { - let vis = min(self.ty_visibility(ty), self.trait_ref_visibility(trait_ref)); - check.required_visibility = vis; - check.visit_generics(generics); + hir::ItemImpl(.., Some(_), _, ref impl_item_refs) => { + let vis = self.check(item.id, ty::Visibility::PrivateExternal) + .item_type().impl_trait_ref().min_visibility; + self.check(item.id, vis).generics().predicates(); for impl_item_ref in impl_item_refs { let impl_item = self.tcx.map.impl_item(impl_item_ref.id); - check.visit_impl_item(impl_item); + self.check(impl_item.id, vis).generics().predicates().item_type(); + + // Recurse for e.g. `impl Trait` (see `visit_ty`). + self.inner_visibility = vis; + intravisit::walk_impl_item(self, impl_item); } } } @@ -1151,6 +1166,24 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for PrivateItemsInPublicInterfacesVisitor fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem) { // handled in `visit_item` above } + + fn visit_ty(&mut self, ty: &hir::Ty) { + if let hir::TyImplTrait(..) = ty.node { + // Check the traits being exposed, as they're separate, + // e.g. `impl Iterator` has two predicates, + // `X: Iterator` and `::Item == T`, + // where `X` is the `impl Iterator` itself, + // stored in `item_predicates`, not in the `Ty` itself. + self.check(ty.id, self.inner_visibility).predicates(); + } + + intravisit::walk_ty(self, ty); + } + + // Don't recurse into expressions in array sizes or const initializers + fn visit_expr(&mut self, _: &hir::Expr) {} + // Don't recurse into patterns in function arguments + fn visit_pat(&mut self, _: &hir::Pat) {} } pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1202,8 +1235,9 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut visitor = PrivateItemsInPublicInterfacesVisitor { tcx: tcx, old_error_set: &visitor.old_error_set, + inner_visibility: ty::Visibility::Public, }; - krate.visit_all_item_likes(&mut visitor); + krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor)); } visitor.access_levels diff --git a/src/test/compile-fail/E0445.rs b/src/test/compile-fail/E0445.rs index 7c5c862a6f8..efef8305e53 100644 --- a/src/test/compile-fail/E0445.rs +++ b/src/test/compile-fail/E0445.rs @@ -13,13 +13,13 @@ trait Foo { } pub trait Bar : Foo {} -//~^ ERROR private trait in public interface [E0445] +//~^ ERROR private trait `Foo` in public interface [E0445] //~| NOTE private trait can't be public pub struct Bar2(pub T); -//~^ ERROR private trait in public interface [E0445] +//~^ ERROR private trait `Foo` in public interface [E0445] //~| NOTE private trait can't be public pub fn foo (t: T) {} -//~^ ERROR private trait in public interface [E0445] +//~^ ERROR private trait `Foo` in public interface [E0445] //~| NOTE private trait can't be public fn main() {} diff --git a/src/test/compile-fail/issue-18389.rs b/src/test/compile-fail/issue-18389.rs index 300fc5a6ef7..aad3d52153a 100644 --- a/src/test/compile-fail/issue-18389.rs +++ b/src/test/compile-fail/issue-18389.rs @@ -14,7 +14,8 @@ use std::any::TypeId; trait Private { fn call(&self, p: P, r: R); } -pub trait Public: Private< //~ ERROR private trait in public interface +pub trait Public: Private< +//~^ ERROR private trait `Private<::P, ::R>` in public interface ::P, ::R > { diff --git a/src/test/compile-fail/issue-28514.rs b/src/test/compile-fail/issue-28514.rs index fb25166531d..3488310b128 100644 --- a/src/test/compile-fail/issue-28514.rs +++ b/src/test/compile-fail/issue-28514.rs @@ -21,7 +21,7 @@ mod inner { fn b(&self) { } } - pub trait C: A + B { //~ ERROR private trait in public interface + pub trait C: A + B { //~ ERROR private trait `inner::A` in public interface //~^ WARN will become a hard error fn c(&self) { } } diff --git a/src/test/compile-fail/issue-30079.rs b/src/test/compile-fail/issue-30079.rs index 6a54e53f146..15b7edb32d4 100644 --- a/src/test/compile-fail/issue-30079.rs +++ b/src/test/compile-fail/issue-30079.rs @@ -16,7 +16,7 @@ struct SemiPriv; mod m1 { struct Priv; impl ::SemiPriv { - pub fn f(_: Priv) {} //~ ERROR private type in public interface + pub fn f(_: Priv) {} //~ ERROR private type `m1::Priv` in public interface //~^ WARNING hard error } @@ -28,7 +28,7 @@ mod m1 { mod m2 { struct Priv; impl ::std::ops::Deref for ::SemiPriv { - type Target = Priv; //~ ERROR private type in public interface + type Target = Priv; //~ ERROR private type `m2::Priv` in public interface //~^ WARNING hard error fn deref(&self) -> &Self::Target { unimplemented!() } } @@ -46,7 +46,7 @@ trait SemiPrivTrait { mod m3 { struct Priv; impl ::SemiPrivTrait for () { - type Assoc = Priv; //~ ERROR private type in public interface + type Assoc = Priv; //~ ERROR private type `m3::Priv` in public interface //~^ WARNING hard error } } diff --git a/src/test/compile-fail/private-in-public-lint.rs b/src/test/compile-fail/private-in-public-lint.rs index 4796548112d..030fbfc4914 100644 --- a/src/test/compile-fail/private-in-public-lint.rs +++ b/src/test/compile-fail/private-in-public-lint.rs @@ -13,7 +13,7 @@ mod m1 { struct Priv; impl Pub { - pub fn f() -> Priv {Priv} //~ ERROR private type in public interface + pub fn f() -> Priv {Priv} //~ ERROR private type `m1::Priv` in public interface } } @@ -24,7 +24,7 @@ mod m2 { struct Priv; impl Pub { - pub fn f() -> Priv {Priv} //~ ERROR private type in public interface + pub fn f() -> Priv {Priv} //~ ERROR private type `m2::Priv` in public interface } } diff --git a/src/test/compile-fail/private-in-public-warn.rs b/src/test/compile-fail/private-in-public-warn.rs index 455de37aee9..3496348985d 100644 --- a/src/test/compile-fail/private-in-public-warn.rs +++ b/src/test/compile-fail/private-in-public-warn.rs @@ -24,34 +24,34 @@ mod types { type Alias; } - pub type Alias = Priv; //~ ERROR private type in public interface + pub type Alias = Priv; //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error pub enum E { - V1(Priv), //~ ERROR private type in public interface + V1(Priv), //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error - V2 { field: Priv }, //~ ERROR private type in public interface + V2 { field: Priv }, //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error } pub trait Tr { - const C: Priv = Priv; //~ ERROR private type in public interface + const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error - type Alias = Priv; //~ ERROR private type in public interface + type Alias = Priv; //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error - fn f1(arg: Priv) {} //~ ERROR private type in public interface + fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error - fn f2() -> Priv { panic!() } //~ ERROR private type in public interface + fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error } extern { - pub static ES: Priv; //~ ERROR private type in public interface + pub static ES: Priv; //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error - pub fn ef1(arg: Priv); //~ ERROR private type in public interface + pub fn ef1(arg: Priv); //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error - pub fn ef2() -> Priv; //~ ERROR private type in public interface + pub fn ef2() -> Priv; //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error } impl PubTr for Pub { - type Alias = Priv; //~ ERROR private type in public interface + type Alias = Priv; //~ ERROR private type `types::Priv` in public interface //~^ WARNING hard error } } @@ -61,22 +61,23 @@ mod traits { pub struct Pub(T); pub trait PubTr {} - pub type Alias = T; //~ ERROR private trait in public interface + pub type Alias = T; //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARN trait bounds are not (yet) enforced in type definitions //~| WARNING hard error - pub trait Tr1: PrivTr {} //~ ERROR private trait in public interface + pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error - pub trait Tr2 {} //~ ERROR private trait in public interface + pub trait Tr2 {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error pub trait Tr3 { - type Alias: PrivTr; //~ ERROR private trait in public interface - //~^ WARNING hard error - fn f(arg: T) {} //~ ERROR private trait in public interface + //~^ ERROR private trait `traits::PrivTr` in public interface + //~| WARNING hard error + type Alias: PrivTr; + fn f(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error } - impl Pub {} //~ ERROR private trait in public interface + impl Pub {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error - impl PubTr for Pub {} //~ ERROR private trait in public interface + impl PubTr for Pub {} //~ ERROR private trait `traits::PrivTr` in public interface //~^ WARNING hard error } @@ -85,18 +86,23 @@ mod traits_where { pub struct Pub(T); pub trait PubTr {} - pub type Alias where T: PrivTr = T; //~ ERROR private trait in public interface - //~^ WARNING hard error - pub trait Tr2 where T: PrivTr {} //~ ERROR private trait in public interface - //~^ WARNING hard error + pub type Alias where T: PrivTr = T; + //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~| WARNING hard error + pub trait Tr2 where T: PrivTr {} + //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~| WARNING hard error pub trait Tr3 { - fn f(arg: T) where T: PrivTr {} //~ ERROR private trait in public interface - //~^ WARNING hard error + fn f(arg: T) where T: PrivTr {} + //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~| WARNING hard error } - impl Pub where T: PrivTr {} //~ ERROR private trait in public interface - //~^ WARNING hard error - impl PubTr for Pub where T: PrivTr {} //~ ERROR private trait in public interface - //~^ WARNING hard error + impl Pub where T: PrivTr {} + //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~| WARNING hard error + impl PubTr for Pub where T: PrivTr {} + //~^ ERROR private trait `traits_where::PrivTr` in public interface + //~| WARNING hard error } mod generics { @@ -105,13 +111,14 @@ mod generics { trait PrivTr {} pub trait PubTr {} - pub trait Tr1: PrivTr {} //~ ERROR private trait in public interface + pub trait Tr1: PrivTr {} + //~^ ERROR private trait `generics::PrivTr` in public interface + //~| WARNING hard error + pub trait Tr2: PubTr {} //~ ERROR private type `generics::Priv` in public interface //~^ WARNING hard error - pub trait Tr2: PubTr {} //~ ERROR private type in public interface + pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type `generics::Priv` in public interface //~^ WARNING hard error - pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type in public interface - //~^ WARNING hard error - pub trait Tr4: PubTr> {} //~ ERROR private type in public interface + pub trait Tr4: PubTr> {} //~ ERROR private type `generics::Priv` in public interface //~^ WARNING hard error } @@ -138,7 +145,7 @@ mod impls { type Alias = Priv; // OK } impl PubTr for Pub { - type Alias = Priv; //~ ERROR private type in public interface + type Alias = Priv; //~ ERROR private type `impls::Priv` in public interface //~^ WARNING hard error } } @@ -210,23 +217,23 @@ mod aliases_pub { pub trait Tr2: PrivUseAliasTr {} // OK impl PrivAlias { - pub fn f(arg: Priv) {} //~ ERROR private type in public interface + pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface //~^ WARNING hard error } // This doesn't even parse // impl ::AssocAlias { - // pub fn f(arg: Priv) {} // ERROR private type in public interface + // pub fn f(arg: Priv) {} // ERROR private type `aliases_pub::Priv` in public interface // } impl PrivUseAliasTr for PrivUseAlias { - type Check = Priv; //~ ERROR private type in public interface + type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface //~^ WARNING hard error } impl PrivUseAliasTr for PrivAlias { - type Check = Priv; //~ ERROR private type in public interface + type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface //~^ WARNING hard error } impl PrivUseAliasTr for ::AssocAlias { - type Check = Priv; //~ ERROR private type in public interface + type Check = Priv; //~ ERROR private type `aliases_pub::Priv` in public interface //~^ WARNING hard error } } @@ -251,11 +258,13 @@ mod aliases_priv { type AssocAlias = Priv3; } - pub trait Tr1: PrivUseAliasTr {} //~ ERROR private trait in public interface - //~^ WARNING hard error - pub trait Tr2: PrivUseAliasTr {} //~ ERROR private trait in public interface - //~^ ERROR private type in public interface + pub trait Tr1: PrivUseAliasTr {} + //~^ ERROR private trait `aliases_priv::PrivTr1` in public interface //~| WARNING hard error + pub trait Tr2: PrivUseAliasTr {} + //~^ ERROR private trait `aliases_priv::PrivTr1` in public interface + //~| WARNING hard error + //~| ERROR private type `aliases_priv::Priv2` in public interface //~| WARNING hard error impl PrivUseAlias { diff --git a/src/test/compile-fail/private-in-public.rs b/src/test/compile-fail/private-in-public.rs index 7d4dcfd3145..b819ef116ef 100644 --- a/src/test/compile-fail/private-in-public.rs +++ b/src/test/compile-fail/private-in-public.rs @@ -21,16 +21,16 @@ mod types { type Alias; } - pub const C: Priv = Priv; //~ ERROR private type in public interface - pub static S: Priv = Priv; //~ ERROR private type in public interface - pub fn f1(arg: Priv) {} //~ ERROR private type in public interface - pub fn f2() -> Priv { panic!() } //~ ERROR private type in public interface - pub struct S1(pub Priv); //~ ERROR private type in public interface - pub struct S2 { pub field: Priv } //~ ERROR private type in public interface + pub const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface + pub static S: Priv = Priv; //~ ERROR private type `types::Priv` in public interface + pub fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface + pub fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface + pub struct S1(pub Priv); //~ ERROR private type `types::Priv` in public interface + pub struct S2 { pub field: Priv } //~ ERROR private type `types::Priv` in public interface impl Pub { - pub const C: Priv = Priv; //~ ERROR private type in public interface - pub fn f1(arg: Priv) {} //~ ERROR private type in public interface - pub fn f2() -> Priv { panic!() } //~ ERROR private type in public interface + pub const C: Priv = Priv; //~ ERROR private type `types::Priv` in public interface + pub fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface + pub fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface } } @@ -39,11 +39,11 @@ mod traits { pub struct Pub(T); pub trait PubTr {} - pub enum E { V(T) } //~ ERROR private trait in public interface - pub fn f(arg: T) {} //~ ERROR private trait in public interface - pub struct S1(T); //~ ERROR private trait in public interface - impl Pub { - pub fn f(arg: U) {} //~ ERROR private trait in public interface + pub enum E { V(T) } //~ ERROR private trait `traits::PrivTr` in public interface + pub fn f(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface + pub struct S1(T); //~ ERROR private trait `traits::PrivTr` in public interface + impl Pub { //~ ERROR private trait `traits::PrivTr` in public interface + pub fn f(arg: U) {} //~ ERROR private trait `traits::PrivTr` in public interface } } @@ -52,11 +52,16 @@ mod traits_where { pub struct Pub(T); pub trait PubTr {} - pub enum E where T: PrivTr { V(T) } //~ ERROR private trait in public interface - pub fn f(arg: T) where T: PrivTr {} //~ ERROR private trait in public interface - pub struct S1(T) where T: PrivTr; //~ ERROR private trait in public interface + pub enum E where T: PrivTr { V(T) } + //~^ ERROR private trait `traits_where::PrivTr` in public interface + pub fn f(arg: T) where T: PrivTr {} + //~^ ERROR private trait `traits_where::PrivTr` in public interface + pub struct S1(T) where T: PrivTr; + //~^ ERROR private trait `traits_where::PrivTr` in public interface impl Pub where T: PrivTr { - pub fn f(arg: U) where U: PrivTr {} //~ ERROR private trait in public interface + //~^ ERROR private trait `traits_where::PrivTr` in public interface + pub fn f(arg: U) where U: PrivTr {} + //~^ ERROR private trait `traits_where::PrivTr` in public interface } } @@ -66,9 +71,10 @@ mod generics { trait PrivTr {} pub trait PubTr {} - pub fn f1(arg: [Priv; 1]) {} //~ ERROR private type in public interface - pub fn f2(arg: Pub) {} //~ ERROR private type in public interface - pub fn f3(arg: Priv) {} //~ ERROR private type in public interface + pub fn f1(arg: [Priv; 1]) {} //~ ERROR private type `generics::Priv` in public interface + pub fn f2(arg: Pub) {} //~ ERROR private type `generics::Priv` in public interface + pub fn f3(arg: Priv) {} + //~^ ERROR private type `generics::Priv` in public interface } mod impls { @@ -82,7 +88,7 @@ mod impls { } impl Pub { - pub fn f(arg: Priv) {} //~ ERROR private type in public interface + pub fn f(arg: Priv) {} //~ ERROR private type `impls::Priv` in public interface } } @@ -101,15 +107,17 @@ mod aliases_pub { use self::m::PubTr as PrivUseAliasTr; type PrivAlias = m::Pub2; trait PrivTr { - type AssocAlias = m::Pub3; + type Assoc = m::Pub3; } impl PrivTr for Priv {} // This should be OK, but associated type aliases are not substituted yet - pub fn f3(arg: ::AssocAlias) {} //~ ERROR private type in public interface + pub fn f3(arg: ::Assoc) {} + //~^ ERROR private type `::Assoc` in public interface + //~| ERROR private type `aliases_pub::Priv` in public interface impl PrivUseAlias { - pub fn f(arg: Priv) {} //~ ERROR private type in public interface + pub fn f(arg: Priv) {} //~ ERROR private type `aliases_pub::Priv` in public interface } } @@ -127,13 +135,15 @@ mod aliases_priv { use self::PrivTr1 as PrivUseAliasTr; type PrivAlias = Priv2; trait PrivTr { - type AssocAlias = Priv3; + type Assoc = Priv3; } impl PrivTr for Priv {} - pub fn f1(arg: PrivUseAlias) {} //~ ERROR private type in public interface - pub fn f2(arg: PrivAlias) {} //~ ERROR private type in public interface - pub fn f3(arg: ::AssocAlias) {} //~ ERROR private type in public interface + pub fn f1(arg: PrivUseAlias) {} //~ ERROR private type `aliases_priv::Priv1` in public interface + pub fn f2(arg: PrivAlias) {} //~ ERROR private type `aliases_priv::Priv2` in public interface + pub fn f3(arg: ::Assoc) {} + //~^ ERROR private type `::Assoc` in public + //~| ERROR private type `aliases_priv::Priv` in public interface } mod aliases_params { @@ -141,8 +151,9 @@ mod aliases_params { type PrivAliasGeneric = T; type Result = ::std::result::Result; - pub fn f2(arg: PrivAliasGeneric) {} //~ ERROR private type in public interface - pub fn f3(arg: Result) {} //~ ERROR private type in public interface + pub fn f2(arg: PrivAliasGeneric) {} + //~^ ERROR private type `aliases_params::Priv` in public interface + pub fn f3(arg: Result) {} //~ ERROR private type `aliases_params::Priv` in public interface } fn main() {}