rustc_privacy: switch private-in-public checking to Ty.
This commit is contained in:
parent
fcdb4def83
commit
548e681f2f
@ -31,7 +31,7 @@ use rustc::hir::{self, PatKind};
|
|||||||
use rustc::hir::def::{self, Def, CtorKind};
|
use rustc::hir::def::{self, Def, CtorKind};
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::DefId;
|
||||||
use rustc::hir::intravisit::{self, Visitor};
|
use rustc::hir::intravisit::{self, Visitor};
|
||||||
use rustc::hir::itemlikevisit::ItemLikeVisitor;
|
use rustc::hir::itemlikevisit::DeepVisitor;
|
||||||
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
|
||||||
use rustc::lint;
|
use rustc::lint;
|
||||||
use rustc::middle::privacy::{AccessLevel, AccessLevels};
|
use rustc::middle::privacy::{AccessLevel, AccessLevels};
|
||||||
@ -899,126 +899,96 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
|
|||||||
|
|
||||||
struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
|
struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
item_def_id: DefId,
|
||||||
|
span: Span,
|
||||||
/// The visitor checks that each component type is at least this visible
|
/// The visitor checks that each component type is at least this visible
|
||||||
required_visibility: ty::Visibility,
|
required_visibility: ty::Visibility,
|
||||||
/// The visibility of the least visible component that has been visited
|
/// The visibility of the least visible component that has been visited
|
||||||
min_visibility: ty::Visibility,
|
min_visibility: ty::Visibility,
|
||||||
old_error_set: &'a NodeSet,
|
has_old_errors: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||||
fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, old_error_set: &'a NodeSet) -> Self {
|
fn generics(&mut self) -> &mut Self {
|
||||||
SearchInterfaceForPrivateItemsVisitor {
|
self.tcx.item_generics(self.item_def_id).visit_with(self);
|
||||||
tcx: tcx,
|
self
|
||||||
min_visibility: ty::Visibility::Public,
|
}
|
||||||
required_visibility: ty::Visibility::PrivateExternal,
|
|
||||||
old_error_set: old_error_set,
|
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> {
|
impl<'a, 'tcx: 'a> TypeVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||||
// Return the visibility of the type alias's least visible component type when substituted
|
fn visit_ty(&mut self, ty: Ty<'tcx>) -> bool {
|
||||||
fn substituted_alias_visibility(&self, item: &hir::Item, segment: &hir::PathSegment)
|
let ty_def_id = match ty.sty {
|
||||||
-> Option<ty::Visibility> {
|
ty::TyAdt(adt, _) => Some(adt.did),
|
||||||
// Type alias is considered public if the aliased type is
|
ty::TyTrait(ref obj) => Some(obj.principal.def_id()),
|
||||||
// public, even if the type alias itself is private. So, something
|
ty::TyProjection(ref proj) => {
|
||||||
// like `type A = u8; pub fn f() -> A {...}` doesn't cause an error.
|
if self.required_visibility == ty::Visibility::PrivateExternal {
|
||||||
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 = Private> = 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 => {
|
|
||||||
// Conservatively approximate the whole type alias as public without
|
// Conservatively approximate the whole type alias as public without
|
||||||
// recursing into its components when determining impl publicity.
|
// recursing into its components when determining impl publicity.
|
||||||
// For example, `impl <Type as Trait>::Alias {...}` may be a public impl
|
// For example, `impl <Type as Trait>::Alias {...}` may be a public impl
|
||||||
// even if both `Type` and `Trait` are private.
|
// even if both `Type` and `Trait` are private.
|
||||||
// Ideally, associated types should be substituted in the same way as
|
// Ideally, associated types should be substituted in the same way as
|
||||||
// free type aliases, but this isn't done yet.
|
// 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);
|
Some(proj.trait_ref.def_id)
|
||||||
let vis = match self.substituted_alias_visibility(item, segment) {
|
}
|
||||||
Some(vis) => vis,
|
_ => None
|
||||||
None => ty::Visibility::from_hir(&item.vis, node_id, self.tcx),
|
};
|
||||||
};
|
|
||||||
|
|
||||||
if !vis.is_at_least(self.min_visibility, &self.tcx.map) {
|
if let Some(def_id) = ty_def_id {
|
||||||
self.min_visibility = vis;
|
// 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) {
|
||||||
if !vis.is_at_least(self.required_visibility, &self.tcx.map) {
|
let item = self.tcx.map.expect_item(node_id);
|
||||||
if self.tcx.sess.features.borrow().pub_restricted ||
|
let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx);
|
||||||
self.old_error_set.contains(&ty.id) {
|
|
||||||
let mut err = struct_span_err!(self.tcx.sess, ty.span, E0446,
|
if !vis.is_at_least(self.min_visibility, &self.tcx.map) {
|
||||||
"private type in public interface");
|
self.min_visibility = vis;
|
||||||
err.span_label(ty.span, &format!("can't leak private type"));
|
}
|
||||||
err.emit();
|
if !vis.is_at_least(self.required_visibility, &self.tcx.map) {
|
||||||
} else {
|
if self.tcx.sess.features.borrow().pub_restricted || self.has_old_errors {
|
||||||
self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
|
let mut err = struct_span_err!(self.tcx.sess, self.span, E0446,
|
||||||
node_id,
|
"private type `{}` in public interface", ty);
|
||||||
ty.span,
|
err.span_label(self.span, &format!("can't leak private type"));
|
||||||
format!("private type in public \
|
err.emit();
|
||||||
interface (error E0446)"));
|
} 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)
|
// 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(trait_ref.def_id) {
|
||||||
if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
|
|
||||||
let item = self.tcx.map.expect_item(node_id);
|
let item = self.tcx.map.expect_item(node_id);
|
||||||
let vis = ty::Visibility::from_hir(&item.vis, node_id, self.tcx);
|
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;
|
self.min_visibility = vis;
|
||||||
}
|
}
|
||||||
if !vis.is_at_least(self.required_visibility, &self.tcx.map) {
|
if !vis.is_at_least(self.required_visibility, &self.tcx.map) {
|
||||||
if self.tcx.sess.features.borrow().pub_restricted ||
|
if self.tcx.sess.features.borrow().pub_restricted || self.has_old_errors {
|
||||||
self.old_error_set.contains(&trait_ref.ref_id) {
|
struct_span_err!(self.tcx.sess, self.span, E0445,
|
||||||
struct_span_err!(self.tcx.sess, trait_ref.path.span, E0445,
|
"private trait `{}` in public interface", trait_ref)
|
||||||
"private trait in public interface")
|
.span_label(self.span, &format!(
|
||||||
.span_label(trait_ref.path.span, &format!(
|
|
||||||
"private trait can't be public"))
|
"private trait can't be public"))
|
||||||
.emit();
|
.emit();
|
||||||
} else {
|
} else {
|
||||||
self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
|
self.tcx.sess.add_lint(lint::builtin::PRIVATE_IN_PUBLIC,
|
||||||
node_id,
|
node_id,
|
||||||
trait_ref.path.span,
|
self.span,
|
||||||
"private trait in public interface (error E0445)"
|
format!("private trait `{}` in public \
|
||||||
.to_string());
|
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> {
|
struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx: 'a> {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
old_error_set: &'a NodeSet,
|
old_error_set: &'a NodeSet,
|
||||||
|
inner_visibility: ty::Visibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
|
||||||
// A type is considered public if it doesn't contain any private components
|
fn check(&self, item_id: ast::NodeId, required_visibility: ty::Visibility)
|
||||||
fn ty_visibility(&self, ty: &hir::Ty) -> ty::Visibility {
|
-> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
|
||||||
let mut check = SearchInterfaceForPrivateItemsVisitor::new(self.tcx, self.old_error_set);
|
let mut has_old_errors = false;
|
||||||
check.visit_ty(ty);
|
|
||||||
check.min_visibility
|
|
||||||
}
|
|
||||||
|
|
||||||
// A trait reference is considered public if it doesn't contain any private components
|
// Slow path taken only if there any errors in the crate.
|
||||||
fn trait_ref_visibility(&self, trait_ref: &hir::TraitRef) -> ty::Visibility {
|
for &id in self.old_error_set {
|
||||||
let mut check = SearchInterfaceForPrivateItemsVisitor::new(self.tcx, self.old_error_set);
|
// Walk up the nodes until we find `item_id` (or we hit a root).
|
||||||
check.visit_trait_ref(trait_ref);
|
let mut id = id;
|
||||||
check.min_visibility
|
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) {
|
fn visit_item(&mut self, item: &hir::Item) {
|
||||||
|
let tcx = self.tcx;
|
||||||
let min = |vis1: ty::Visibility, vis2| {
|
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, tcx);
|
||||||
let item_visibility = ty::Visibility::from_hir(&item.vis, item.id, self.tcx);
|
|
||||||
|
|
||||||
match item.node {
|
match item.node {
|
||||||
// Crates are always public
|
// Crates are always public
|
||||||
@ -1093,56 +1077,87 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for PrivateItemsInPublicInterfacesVisitor
|
|||||||
hir::ItemUse(..) => {}
|
hir::ItemUse(..) => {}
|
||||||
// Subitems of these items have inherited publicity
|
// Subitems of these items have inherited publicity
|
||||||
hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
|
hir::ItemConst(..) | hir::ItemStatic(..) | hir::ItemFn(..) |
|
||||||
hir::ItemEnum(..) | hir::ItemTrait(..) | hir::ItemTy(..) => {
|
hir::ItemTy(..) => {
|
||||||
check.required_visibility = item_visibility;
|
self.check(item.id, item_visibility).generics().predicates().item_type();
|
||||||
check.visit_item(item);
|
|
||||||
|
// 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
|
// Subitems of foreign modules have their own publicity
|
||||||
hir::ItemForeignMod(ref foreign_mod) => {
|
hir::ItemForeignMod(ref foreign_mod) => {
|
||||||
for foreign_item in &foreign_mod.items {
|
for foreign_item in &foreign_mod.items {
|
||||||
check.required_visibility =
|
let vis = ty::Visibility::from_hir(&foreign_item.vis, item.id, tcx);
|
||||||
ty::Visibility::from_hir(&foreign_item.vis, item.id, self.tcx);
|
self.check(foreign_item.id, vis).generics().predicates().item_type();
|
||||||
check.visit_foreign_item(foreign_item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Subitems of structs and unions have their own publicity
|
// Subitems of structs and unions have their own publicity
|
||||||
hir::ItemStruct(ref struct_def, ref generics) |
|
hir::ItemStruct(ref struct_def, _) |
|
||||||
hir::ItemUnion(ref struct_def, ref generics) => {
|
hir::ItemUnion(ref struct_def, _) => {
|
||||||
check.required_visibility = item_visibility;
|
self.check(item.id, item_visibility).generics().predicates();
|
||||||
check.visit_generics(generics);
|
|
||||||
|
|
||||||
for field in struct_def.fields() {
|
for field in struct_def.fields() {
|
||||||
let field_visibility = ty::Visibility::from_hir(&field.vis, item.id, self.tcx);
|
let field_visibility = ty::Visibility::from_hir(&field.vis, item.id, tcx);
|
||||||
check.required_visibility = min(item_visibility, field_visibility);
|
self.check(field.id, min(item_visibility, field_visibility)).item_type();
|
||||||
check.visit_struct_field(field);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The interface is empty
|
// The interface is empty
|
||||||
hir::ItemDefaultImpl(..) => {}
|
hir::ItemDefaultImpl(..) => {}
|
||||||
// An inherent impl is public when its type is public
|
// An inherent impl is public when its type is public
|
||||||
// Subitems of inherent impls have their own publicity
|
// Subitems of inherent impls have their own publicity
|
||||||
hir::ItemImpl(.., ref generics, None, ref ty, ref impl_item_refs) => {
|
hir::ItemImpl(.., None, _, ref impl_item_refs) => {
|
||||||
let ty_vis = self.ty_visibility(ty);
|
let ty_vis = self.check(item.id, ty::Visibility::PrivateExternal)
|
||||||
check.required_visibility = ty_vis;
|
.item_type().min_visibility;
|
||||||
check.visit_generics(generics);
|
self.check(item.id, ty_vis).generics().predicates();
|
||||||
|
|
||||||
for impl_item_ref in impl_item_refs {
|
for impl_item_ref in impl_item_refs {
|
||||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
||||||
let impl_item_vis =
|
let impl_item_vis =
|
||||||
ty::Visibility::from_hir(&impl_item.vis, item.id, self.tcx);
|
ty::Visibility::from_hir(&impl_item.vis, item.id, tcx);
|
||||||
check.required_visibility = min(impl_item_vis, ty_vis);
|
self.check(impl_item.id, min(impl_item_vis, ty_vis))
|
||||||
check.visit_impl_item(impl_item);
|
.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
|
// A trait impl is public when both its type and its trait are public
|
||||||
// Subitems of trait impls have inherited publicity
|
// Subitems of trait impls have inherited publicity
|
||||||
hir::ItemImpl(.., ref generics, Some(ref trait_ref), ref ty, ref impl_item_refs) => {
|
hir::ItemImpl(.., Some(_), _, ref impl_item_refs) => {
|
||||||
let vis = min(self.ty_visibility(ty), self.trait_ref_visibility(trait_ref));
|
let vis = self.check(item.id, ty::Visibility::PrivateExternal)
|
||||||
check.required_visibility = vis;
|
.item_type().impl_trait_ref().min_visibility;
|
||||||
check.visit_generics(generics);
|
self.check(item.id, vis).generics().predicates();
|
||||||
for impl_item_ref in impl_item_refs {
|
for impl_item_ref in impl_item_refs {
|
||||||
let impl_item = self.tcx.map.impl_item(impl_item_ref.id);
|
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) {
|
fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem) {
|
||||||
// handled in `visit_item` above
|
// 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<Item=T>` has two predicates,
|
||||||
|
// `X: Iterator` and `<X as Iterator>::Item == T`,
|
||||||
|
// where `X` is the `impl Iterator<Item=T>` 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>,
|
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 {
|
let mut visitor = PrivateItemsInPublicInterfacesVisitor {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
old_error_set: &visitor.old_error_set,
|
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
|
visitor.access_levels
|
||||||
|
@ -13,13 +13,13 @@ trait Foo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Bar : 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
|
//~| NOTE private trait can't be public
|
||||||
pub struct Bar2<T: Foo>(pub T);
|
pub struct Bar2<T: Foo>(pub T);
|
||||||
//~^ ERROR private trait in public interface [E0445]
|
//~^ ERROR private trait `Foo` in public interface [E0445]
|
||||||
//~| NOTE private trait can't be public
|
//~| NOTE private trait can't be public
|
||||||
pub fn foo<T: Foo> (t: T) {}
|
pub fn foo<T: 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
|
//~| NOTE private trait can't be public
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
@ -14,7 +14,8 @@ use std::any::TypeId;
|
|||||||
trait Private<P, R> {
|
trait Private<P, R> {
|
||||||
fn call(&self, p: P, r: R);
|
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<<Self as Public>::P, <Self as Public>::R>` in public interface
|
||||||
<Self as Public>::P,
|
<Self as Public>::P,
|
||||||
<Self as Public>::R
|
<Self as Public>::R
|
||||||
> {
|
> {
|
||||||
|
@ -21,7 +21,7 @@ mod inner {
|
|||||||
fn b(&self) { }
|
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
|
//~^ WARN will become a hard error
|
||||||
fn c(&self) { }
|
fn c(&self) { }
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ struct SemiPriv;
|
|||||||
mod m1 {
|
mod m1 {
|
||||||
struct Priv;
|
struct Priv;
|
||||||
impl ::SemiPriv {
|
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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ mod m1 {
|
|||||||
mod m2 {
|
mod m2 {
|
||||||
struct Priv;
|
struct Priv;
|
||||||
impl ::std::ops::Deref for ::SemiPriv {
|
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
|
//~^ WARNING hard error
|
||||||
fn deref(&self) -> &Self::Target { unimplemented!() }
|
fn deref(&self) -> &Self::Target { unimplemented!() }
|
||||||
}
|
}
|
||||||
@ -46,7 +46,7 @@ trait SemiPrivTrait {
|
|||||||
mod m3 {
|
mod m3 {
|
||||||
struct Priv;
|
struct Priv;
|
||||||
impl ::SemiPrivTrait for () {
|
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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ mod m1 {
|
|||||||
struct Priv;
|
struct Priv;
|
||||||
|
|
||||||
impl Pub {
|
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;
|
struct Priv;
|
||||||
|
|
||||||
impl Pub {
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,34 +24,34 @@ mod types {
|
|||||||
type Alias;
|
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
|
//~^ WARNING hard error
|
||||||
pub enum E {
|
pub enum E {
|
||||||
V1(Priv), //~ ERROR private type in public interface
|
V1(Priv), //~ ERROR private type `types::Priv` in public interface
|
||||||
//~^ WARNING hard error
|
//~^ 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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
pub trait Tr {
|
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
|
//~^ 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
|
//~^ 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
|
//~^ 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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
extern {
|
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
|
//~^ 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
|
//~^ 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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
impl PubTr for Pub {
|
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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,22 +61,23 @@ mod traits {
|
|||||||
pub struct Pub<T>(T);
|
pub struct Pub<T>(T);
|
||||||
pub trait PubTr {}
|
pub trait PubTr {}
|
||||||
|
|
||||||
pub type Alias<T: PrivTr> = T; //~ ERROR private trait in public interface
|
pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
//~^ WARN trait bounds are not (yet) enforced in type definitions
|
//~^ WARN trait bounds are not (yet) enforced in type definitions
|
||||||
//~| WARNING hard error
|
//~| 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
|
//~^ WARNING hard error
|
||||||
pub trait Tr2<T: PrivTr> {} //~ ERROR private trait in public interface
|
pub trait Tr2<T: PrivTr> {} //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
//~^ WARNING hard error
|
//~^ WARNING hard error
|
||||||
pub trait Tr3 {
|
pub trait Tr3 {
|
||||||
type Alias: PrivTr; //~ ERROR private trait in public interface
|
//~^ ERROR private trait `traits::PrivTr` in public interface
|
||||||
//~^ WARNING hard error
|
//~| WARNING hard error
|
||||||
fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait in public interface
|
type Alias: PrivTr;
|
||||||
|
fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
//~^ WARNING hard error
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
impl<T: PrivTr> Pub<T> {} //~ ERROR private trait in public interface
|
impl<T: PrivTr> Pub<T> {} //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
//~^ WARNING hard error
|
//~^ WARNING hard error
|
||||||
impl<T: PrivTr> PubTr for Pub<T> {} //~ ERROR private trait in public interface
|
impl<T: PrivTr> PubTr for Pub<T> {} //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
//~^ WARNING hard error
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,18 +86,23 @@ mod traits_where {
|
|||||||
pub struct Pub<T>(T);
|
pub struct Pub<T>(T);
|
||||||
pub trait PubTr {}
|
pub trait PubTr {}
|
||||||
|
|
||||||
pub type Alias<T> where T: PrivTr = T; //~ ERROR private trait in public interface
|
pub type Alias<T> where T: PrivTr = T;
|
||||||
//~^ WARNING hard error
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
pub trait Tr2<T> where T: PrivTr {} //~ ERROR private trait in public interface
|
//~| WARNING hard error
|
||||||
//~^ WARNING hard error
|
pub trait Tr2<T> where T: PrivTr {}
|
||||||
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
|
//~| WARNING hard error
|
||||||
pub trait Tr3 {
|
pub trait Tr3 {
|
||||||
fn f<T>(arg: T) where T: PrivTr {} //~ ERROR private trait in public interface
|
fn f<T>(arg: T) where T: PrivTr {}
|
||||||
//~^ WARNING hard error
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
|
//~| WARNING hard error
|
||||||
}
|
}
|
||||||
impl<T> Pub<T> where T: PrivTr {} //~ ERROR private trait in public interface
|
impl<T> Pub<T> where T: PrivTr {}
|
||||||
//~^ WARNING hard error
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
impl<T> PubTr for Pub<T> where T: PrivTr {} //~ ERROR private trait in public interface
|
//~| WARNING hard error
|
||||||
//~^ WARNING hard error
|
impl<T> PubTr for Pub<T> where T: PrivTr {}
|
||||||
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
|
//~| WARNING hard error
|
||||||
}
|
}
|
||||||
|
|
||||||
mod generics {
|
mod generics {
|
||||||
@ -105,13 +111,14 @@ mod generics {
|
|||||||
trait PrivTr<T> {}
|
trait PrivTr<T> {}
|
||||||
pub trait PubTr<T> {}
|
pub trait PubTr<T> {}
|
||||||
|
|
||||||
pub trait Tr1: PrivTr<Pub> {} //~ ERROR private trait in public interface
|
pub trait Tr1: PrivTr<Pub> {}
|
||||||
|
//~^ ERROR private trait `generics::PrivTr<generics::Pub>` in public interface
|
||||||
|
//~| WARNING hard error
|
||||||
|
pub trait Tr2: PubTr<Priv> {} //~ ERROR private type `generics::Priv` in public interface
|
||||||
//~^ WARNING hard error
|
//~^ WARNING hard error
|
||||||
pub trait Tr2: PubTr<Priv> {} //~ ERROR private type in public interface
|
pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type `generics::Priv` in public interface
|
||||||
//~^ WARNING hard error
|
//~^ WARNING hard error
|
||||||
pub trait Tr3: PubTr<[Priv; 1]> {} //~ ERROR private type in public interface
|
pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR private type `generics::Priv` in public interface
|
||||||
//~^ WARNING hard error
|
|
||||||
pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR private type in public interface
|
|
||||||
//~^ WARNING hard error
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +145,7 @@ mod impls {
|
|||||||
type Alias = Priv; // OK
|
type Alias = Priv; // OK
|
||||||
}
|
}
|
||||||
impl PubTr for Pub {
|
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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -210,23 +217,23 @@ mod aliases_pub {
|
|||||||
pub trait Tr2: PrivUseAliasTr<PrivAlias> {} // OK
|
pub trait Tr2: PrivUseAliasTr<PrivAlias> {} // OK
|
||||||
|
|
||||||
impl PrivAlias {
|
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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
// This doesn't even parse
|
// This doesn't even parse
|
||||||
// impl <Priv as PrivTr>::AssocAlias {
|
// impl <Priv as PrivTr>::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 {
|
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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
impl PrivUseAliasTr for PrivAlias {
|
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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
impl PrivUseAliasTr for <Priv as PrivTr>::AssocAlias {
|
impl PrivUseAliasTr for <Priv as PrivTr>::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
|
//~^ WARNING hard error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,11 +258,13 @@ mod aliases_priv {
|
|||||||
type AssocAlias = Priv3;
|
type AssocAlias = Priv3;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Tr1: PrivUseAliasTr {} //~ ERROR private trait in public interface
|
pub trait Tr1: PrivUseAliasTr {}
|
||||||
//~^ WARNING hard error
|
//~^ ERROR private trait `aliases_priv::PrivTr1` in public interface
|
||||||
pub trait Tr2: PrivUseAliasTr<PrivAlias> {} //~ ERROR private trait in public interface
|
|
||||||
//~^ ERROR private type in public interface
|
|
||||||
//~| WARNING hard error
|
//~| WARNING hard error
|
||||||
|
pub trait Tr2: PrivUseAliasTr<PrivAlias> {}
|
||||||
|
//~^ ERROR private trait `aliases_priv::PrivTr1<aliases_priv::Priv2>` in public interface
|
||||||
|
//~| WARNING hard error
|
||||||
|
//~| ERROR private type `aliases_priv::Priv2` in public interface
|
||||||
//~| WARNING hard error
|
//~| WARNING hard error
|
||||||
|
|
||||||
impl PrivUseAlias {
|
impl PrivUseAlias {
|
||||||
|
@ -21,16 +21,16 @@ mod types {
|
|||||||
type Alias;
|
type Alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const C: Priv = 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 in public interface
|
pub static S: Priv = Priv; //~ ERROR private type `types::Priv` in public interface
|
||||||
pub fn f1(arg: Priv) {} //~ ERROR private type in public interface
|
pub fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface
|
||||||
pub fn f2() -> Priv { panic!() } //~ ERROR private type in public interface
|
pub fn f2() -> Priv { panic!() } //~ ERROR private type `types::Priv` in public interface
|
||||||
pub struct S1(pub Priv); //~ ERROR private type 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 in public interface
|
pub struct S2 { pub field: Priv } //~ ERROR private type `types::Priv` in public interface
|
||||||
impl Pub {
|
impl Pub {
|
||||||
pub const C: Priv = Priv; //~ 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 in public interface
|
pub fn f1(arg: Priv) {} //~ ERROR private type `types::Priv` in public interface
|
||||||
pub fn f2() -> Priv { panic!() } //~ ERROR private type 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>(T);
|
pub struct Pub<T>(T);
|
||||||
pub trait PubTr {}
|
pub trait PubTr {}
|
||||||
|
|
||||||
pub enum E<T: PrivTr> { V(T) } //~ ERROR private trait in public interface
|
pub enum E<T: PrivTr> { V(T) } //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
pub fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait in public interface
|
pub fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
pub struct S1<T: PrivTr>(T); //~ ERROR private trait in public interface
|
pub struct S1<T: PrivTr>(T); //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
impl<T: PrivTr> Pub<T> {
|
impl<T: PrivTr> Pub<T> { //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
pub fn f<U: PrivTr>(arg: U) {} //~ ERROR private trait in public interface
|
pub fn f<U: PrivTr>(arg: U) {} //~ ERROR private trait `traits::PrivTr` in public interface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,11 +52,16 @@ mod traits_where {
|
|||||||
pub struct Pub<T>(T);
|
pub struct Pub<T>(T);
|
||||||
pub trait PubTr {}
|
pub trait PubTr {}
|
||||||
|
|
||||||
pub enum E<T> where T: PrivTr { V(T) } //~ ERROR private trait in public interface
|
pub enum E<T> where T: PrivTr { V(T) }
|
||||||
pub fn f<T>(arg: T) where T: PrivTr {} //~ ERROR private trait in public interface
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
pub struct S1<T>(T) where T: PrivTr; //~ ERROR private trait in public interface
|
pub fn f<T>(arg: T) where T: PrivTr {}
|
||||||
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
|
pub struct S1<T>(T) where T: PrivTr;
|
||||||
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
impl<T> Pub<T> where T: PrivTr {
|
impl<T> Pub<T> where T: PrivTr {
|
||||||
pub fn f<U>(arg: U) where U: PrivTr {} //~ ERROR private trait in public interface
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
|
pub fn f<U>(arg: U) where U: PrivTr {}
|
||||||
|
//~^ ERROR private trait `traits_where::PrivTr` in public interface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,9 +71,10 @@ mod generics {
|
|||||||
trait PrivTr<T> {}
|
trait PrivTr<T> {}
|
||||||
pub trait PubTr<T> {}
|
pub trait PubTr<T> {}
|
||||||
|
|
||||||
pub fn f1(arg: [Priv; 1]) {} //~ 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<Priv>) {} //~ ERROR private type in public interface
|
pub fn f2(arg: Pub<Priv>) {} //~ ERROR private type `generics::Priv` in public interface
|
||||||
pub fn f3(arg: Priv<Pub>) {} //~ ERROR private type in public interface
|
pub fn f3(arg: Priv<Pub>) {}
|
||||||
|
//~^ ERROR private type `generics::Priv<generics::Pub>` in public interface
|
||||||
}
|
}
|
||||||
|
|
||||||
mod impls {
|
mod impls {
|
||||||
@ -82,7 +88,7 @@ mod impls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Pub {
|
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;
|
use self::m::PubTr as PrivUseAliasTr;
|
||||||
type PrivAlias = m::Pub2;
|
type PrivAlias = m::Pub2;
|
||||||
trait PrivTr {
|
trait PrivTr {
|
||||||
type AssocAlias = m::Pub3;
|
type Assoc = m::Pub3;
|
||||||
}
|
}
|
||||||
impl PrivTr for Priv {}
|
impl PrivTr for Priv {}
|
||||||
|
|
||||||
// This should be OK, but associated type aliases are not substituted yet
|
// This should be OK, but associated type aliases are not substituted yet
|
||||||
pub fn f3(arg: <Priv as PrivTr>::AssocAlias) {} //~ ERROR private type in public interface
|
pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
|
||||||
|
//~^ ERROR private type `<aliases_pub::Priv as aliases_pub::PrivTr>::Assoc` in public interface
|
||||||
|
//~| ERROR private type `aliases_pub::Priv` in public interface
|
||||||
|
|
||||||
impl PrivUseAlias {
|
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;
|
use self::PrivTr1 as PrivUseAliasTr;
|
||||||
type PrivAlias = Priv2;
|
type PrivAlias = Priv2;
|
||||||
trait PrivTr {
|
trait PrivTr {
|
||||||
type AssocAlias = Priv3;
|
type Assoc = Priv3;
|
||||||
}
|
}
|
||||||
impl PrivTr for Priv {}
|
impl PrivTr for Priv {}
|
||||||
|
|
||||||
pub fn f1(arg: PrivUseAlias) {} //~ 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 in public interface
|
pub fn f2(arg: PrivAlias) {} //~ ERROR private type `aliases_priv::Priv2` in public interface
|
||||||
pub fn f3(arg: <Priv as PrivTr>::AssocAlias) {} //~ ERROR private type in public interface
|
pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
|
||||||
|
//~^ ERROR private type `<aliases_priv::Priv as aliases_priv::PrivTr>::Assoc` in public
|
||||||
|
//~| ERROR private type `aliases_priv::Priv` in public interface
|
||||||
}
|
}
|
||||||
|
|
||||||
mod aliases_params {
|
mod aliases_params {
|
||||||
@ -141,8 +151,9 @@ mod aliases_params {
|
|||||||
type PrivAliasGeneric<T = Priv> = T;
|
type PrivAliasGeneric<T = Priv> = T;
|
||||||
type Result<T> = ::std::result::Result<T, Priv>;
|
type Result<T> = ::std::result::Result<T, Priv>;
|
||||||
|
|
||||||
pub fn f2(arg: PrivAliasGeneric) {} //~ ERROR private type in public interface
|
pub fn f2(arg: PrivAliasGeneric) {}
|
||||||
pub fn f3(arg: Result<u8>) {} //~ ERROR private type in public interface
|
//~^ ERROR private type `aliases_params::Priv` in public interface
|
||||||
|
pub fn f3(arg: Result<u8>) {} //~ ERROR private type `aliases_params::Priv` in public interface
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
Loading…
Reference in New Issue
Block a user