]> git.lizzy.rs Git - rust.git/commitdiff
rustc_privacy: switch private-in-public checking to Ty.
authorEduard Burtescu <edy.burt@gmail.com>
Sat, 12 Nov 2016 10:24:17 +0000 (12:24 +0200)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Mon, 28 Nov 2016 03:12:41 +0000 (05:12 +0200)
src/librustc_privacy/lib.rs
src/test/compile-fail/E0445.rs
src/test/compile-fail/issue-18389.rs
src/test/compile-fail/issue-28514.rs
src/test/compile-fail/issue-30079.rs
src/test/compile-fail/private-in-public-lint.rs
src/test/compile-fail/private-in-public-warn.rs
src/test/compile-fail/private-in-public.rs

index 797371001d8d64c509c916082df6f217f2b25e6f..ee18968ff35e3b61bb3099eff84d675c5e084af8 100644 (file)
@@ -31,7 +31,7 @@
 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 @@ fn visit_expr(&mut self, _: &'tcx hir::Expr) {}
 
 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
     }
-}
 
-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<ty::Visibility> {
-        // 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 = 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
-        }
+    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, '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 <Type as Trait>::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 @@ fn visit_trait_ref(&mut self, trait_ref: &hir::TraitRef) {
                 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;
+
+        // 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;
+            }
+        }
 
-    // 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
+        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 @@ fn visit_item(&mut self, item: &hir::Item) {
             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 @@ fn visit_item(&mut self, item: &hir::Item) {
     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<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>,
@@ -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
index 7c5c862a6f812ab724520c75f9260fde6aaa5061..efef8305e53547734b7fd1255dd9c809bcaeff79 100644 (file)
@@ -13,13 +13,13 @@ fn dummy(&self) { }
 }
 
 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<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
 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
 
 fn main() {}
index 300fc5a6ef736427ba86f9b33c6b92b342b4717d..aad3d52153a2d471b25dc5b5c54f1ddf0284773f 100644 (file)
@@ -14,7 +14,8 @@
 trait Private<P, 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>::R
 > {
index fb25166531dcb6fb1a409279ed687b79fdc8037f..3488310b128834dbbd866cbb4fa43e06addcf8a3 100644 (file)
@@ -21,7 +21,7 @@ pub trait B {
         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) { }
     }
index 6a54e53f146382c174207819b94d7feabfd0bfba..15b7edb32d41ddebac3326b6491bbfd4d1222608 100644 (file)
@@ -16,7 +16,7 @@
 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 @@ pub fn f(_: Priv) {} // ok
 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
     }
 }
index 4796548112d9e0ae4b201cda345f95c4b93ec344..030fbfc4914497aacc910ecf9db41f8f2bdc6425 100644 (file)
@@ -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
     }
 }
 
index 455de37aee96f2bb0e7af1f3e72900a6ac39d17c..3496348985d8d174ca8faae75cdb8e6013e2772d 100644 (file)
@@ -24,34 +24,34 @@ pub trait PubTr {
         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 @@ trait PrivTr {}
     pub struct Pub<T>(T);
     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
     //~| 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<T: PrivTr> {} //~ ERROR private trait in public interface
+    pub trait Tr2<T: PrivTr> {} //~ 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<T: PrivTr>(arg: T) {} //~ ERROR private trait in public interface
+        //~^ ERROR private trait `traits::PrivTr` in public interface
+        //~| WARNING hard error
+        type Alias: PrivTr;
+        fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait `traits::PrivTr` in public interface
         //~^ 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
-    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
 }
 
@@ -85,18 +86,23 @@ trait PrivTr {}
     pub struct Pub<T>(T);
     pub trait PubTr {}
 
-    pub type Alias<T> where T: PrivTr = T; //~ ERROR private trait in public interface
-        //~^ WARNING hard error
-    pub trait Tr2<T> where T: PrivTr {} //~ ERROR private trait in public interface
-        //~^ WARNING hard error
+    pub type Alias<T> where T: PrivTr = T;
+        //~^ ERROR private trait `traits_where::PrivTr` in public interface
+        //~| 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 {
-        fn f<T>(arg: T) where T: PrivTr {} //~ ERROR private trait in public interface
-        //~^ WARNING hard error
+        fn f<T>(arg: T) where T: PrivTr {}
+        //~^ 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
-        //~^ WARNING hard error
-    impl<T> PubTr for Pub<T> where T: PrivTr {} //~ ERROR private trait in public interface
-        //~^ WARNING hard error
+    impl<T> Pub<T> where T: PrivTr {}
+        //~^ ERROR private trait `traits_where::PrivTr` in public interface
+        //~| 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 {
@@ -105,13 +111,14 @@ mod generics {
     trait PrivTr<T> {}
     pub trait PubTr<T> {}
 
-    pub trait Tr1: PrivTr<Pub> {} //~ ERROR private trait in public interface
-        //~^ WARNING hard error
-    pub trait Tr2: PubTr<Priv> {} //~ ERROR private type 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
-    pub trait Tr3: PubTr<[Priv; 1]> {} //~ 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 Tr4: PubTr<Pub<Priv>> {} //~ ERROR private type in public interface
+    pub trait Tr4: PubTr<Pub<Priv>> {} //~ ERROR private type `generics::Priv` in public interface
         //~^ WARNING hard error
 }
 
@@ -138,7 +145,7 @@ impl PrivTr for Pub {
         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 @@ pub trait Tr1: PrivUseAliasTr {} // OK
     pub trait Tr2: PrivUseAliasTr<PrivAlias> {} // 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 <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 {
-        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 <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
     }
 }
@@ -251,11 +258,13 @@ impl PrivTr for Priv {
         type AssocAlias = Priv3;
     }
 
-    pub trait Tr1: PrivUseAliasTr {} //~ ERROR private trait in public interface
-        //~^ WARNING hard error
-    pub trait Tr2: PrivUseAliasTr<PrivAlias> {} //~ 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<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
 
     impl PrivUseAlias {
index 7d4dcfd3145abdd313a6663c8fd620579d88fd26..b819ef116efe91d5c8eb0949404edd441c4ff79f 100644 (file)
@@ -21,16 +21,16 @@ pub trait PubTr {
         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 @@ trait PrivTr {}
     pub struct Pub<T>(T);
     pub trait PubTr {}
 
-    pub enum E<T: PrivTr> { V(T) } //~ ERROR private trait in public interface
-    pub fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait in public interface
-    pub struct S1<T: PrivTr>(T); //~ ERROR private trait in public interface
-    impl<T: PrivTr> Pub<T> {
-        pub fn f<U: PrivTr>(arg: U) {} //~ 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 `traits::PrivTr` in public interface
+    pub struct S1<T: PrivTr>(T); //~ ERROR private trait `traits::PrivTr` in public interface
+    impl<T: PrivTr> Pub<T> { //~ ERROR private trait `traits::PrivTr` in public interface
+        pub fn f<U: PrivTr>(arg: U) {} //~ ERROR private trait `traits::PrivTr` in public interface
     }
 }
 
@@ -52,11 +52,16 @@ trait PrivTr {}
     pub struct Pub<T>(T);
     pub trait PubTr {}
 
-    pub enum E<T> where T: PrivTr { V(T) } //~ ERROR private trait in public interface
-    pub fn f<T>(arg: T) where T: PrivTr {} //~ ERROR private trait in public interface
-    pub struct S1<T>(T) where T: PrivTr; //~ ERROR private trait in public interface
+    pub enum E<T> where T: PrivTr { V(T) }
+    //~^ ERROR private trait `traits_where::PrivTr` 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 {
-        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> {}
     pub trait PubTr<T> {}
 
-    pub fn f1(arg: [Priv; 1]) {} //~ ERROR private type in public interface
-    pub fn f2(arg: Pub<Priv>) {} //~ ERROR private type in public interface
-    pub fn f3(arg: Priv<Pub>) {} //~ 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 `generics::Priv` in public interface
+    pub fn f3(arg: Priv<Pub>) {}
+    //~^ ERROR private type `generics::Priv<generics::Pub>` in public interface
 }
 
 mod impls {
@@ -82,7 +88,7 @@ pub trait PubTr {
     }
 
     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 @@ pub trait PubTr<T = u8> {
     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: <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 {
-        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 @@ trait PrivTr1<T = u8> {
     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: <Priv as PrivTr>::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: <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 {
@@ -141,8 +151,9 @@ mod aliases_params {
     type PrivAliasGeneric<T = Priv> = T;
     type Result<T> = ::std::result::Result<T, Priv>;
 
-    pub fn f2(arg: PrivAliasGeneric) {} //~ ERROR private type in public interface
-    pub fn f3(arg: Result<u8>) {} //~ 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<u8>) {} //~ ERROR private type `aliases_params::Priv` in public interface
 }
 
 fn main() {}