diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 275f328bfe01..8993b998738b 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1460,13 +1460,38 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { old_error_set: &'a NodeSet, } +impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { + // Check if the type alias contain private types when substituted + fn is_public_type_alias(&self, item: &hir::Item, path: &hir::Path) -> bool { + // 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 { + tcx: self.tcx, is_quiet: self.is_quiet, + is_public: true, old_error_set: self.old_error_set, + }; + check.visit_ty(ty); + let provided_params = path.segments.last().unwrap().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); + } + } + check.is_public + } else { + false + } + } +} + impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn visit_ty(&mut self, ty: &hir::Ty) { if self.is_quiet && !self.is_public { // We are in quiet mode and a private type is already found, no need to proceed return } - if let hir::TyPath(..) = ty.node { + if let hir::TyPath(_, ref path) = ty.node { let def = self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def(); match def { def::DefPrimTy(..) | def::DefSelfTy(..) | def::DefTyParam(..) => { @@ -1482,12 +1507,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, // Non-local means public, local needs to be checked if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { if let Some(ast_map::NodeItem(ref item)) = self.tcx.map.find(node_id) { - if let (&hir::ItemTy(..), true) = (&item.node, self.is_quiet) { - // Conservatively approximate the whole type alias as public without - // recursing into its components when determining impl publicity. - return - } - if item.vis != hir::Public { + if item.vis != hir::Public && !self.is_public_type_alias(item, path) { if !self.is_quiet { if self.old_error_set.contains(&ty.id) { span_err!(self.tcx.sess, ty.span, E0446, diff --git a/src/librustc_trans/back/msvc/registry.rs b/src/librustc_trans/back/msvc/registry.rs index 44b161a7575c..8f60be3fab3b 100644 --- a/src/librustc_trans/back/msvc/registry.rs +++ b/src/librustc_trans/back/msvc/registry.rs @@ -14,7 +14,7 @@ use std::os::windows::prelude::*; use std::ptr; use libc::{c_void, c_long}; -pub type DWORD = u32; +type DWORD = u32; type LPCWSTR = *const u16; type LONG = c_long; type LPDWORD = *mut DWORD; diff --git a/src/test/compile-fail/issue-28450-1.rs b/src/test/compile-fail/issue-28450-1.rs deleted file mode 100644 index 7239e6ddc379..000000000000 --- a/src/test/compile-fail/issue-28450-1.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// Checks for private types in public interfaces - -type Foo = u8; -pub fn foo(f: Foo) {} //~ ERROR private type in public interface - -fn main() {} diff --git a/src/test/compile-fail/lint-visible-private-types-1.rs b/src/test/compile-fail/lint-visible-private-types-1.rs index 69c4eca1a0a7..939f2400d1b8 100644 --- a/src/test/compile-fail/lint-visible-private-types-1.rs +++ b/src/test/compile-fail/lint-visible-private-types-1.rs @@ -37,5 +37,11 @@ impl PubTrait for as PrivTrait2>::Alias { type Output = Private; //~ WARN private type in public interface } +type PrivAliasPubType = u8; +pub fn f1(_: PrivAliasPubType) {} // Ok, not an error + +type PrivAliasGeneric> = T; +pub fn f2(_: PrivAliasGeneric) {} // Ok, not an error + #[rustc_error] fn main() {} //~ ERROR compilation successful diff --git a/src/test/compile-fail/lint-visible-private-types.rs b/src/test/compile-fail/lint-visible-private-types.rs index 1fd616055575..e9890dc32b73 100644 --- a/src/test/compile-fail/lint-visible-private-types.rs +++ b/src/test/compile-fail/lint-visible-private-types.rs @@ -121,3 +121,12 @@ impl>> //~ ERROR private type in public interface ParamTrait for Public { fn foo() -> T { panic!() } } + +type PrivAliasPrivType = Private; +pub fn f1(_: PrivAliasPrivType) {} //~ ERROR private type in public interface + +type PrivAliasGeneric> = T; +pub fn f2(_: PrivAliasGeneric) {} //~ ERROR private type in public interface + +type Result = std::result::Result>; +pub fn f3(_: Result) {} //~ ERROR private type in public interface