Skip to content

Commit fcbd553

Browse files
committed
Substitute type aliases before checking for privacy
1 parent a745614 commit fcbd553

File tree

5 files changed

+43
-24
lines changed

5 files changed

+43
-24
lines changed

src/librustc_privacy/lib.rs

+27-7
Original file line numberDiff line numberDiff line change
@@ -1460,13 +1460,38 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> {
14601460
old_error_set: &'a NodeSet,
14611461
}
14621462

1463+
impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
1464+
// Check if the type alias contain private types when substituted
1465+
fn is_public_type_alias(&self, item: &hir::Item, path: &hir::Path) -> bool {
1466+
// Type alias is considered public if the aliased type is
1467+
// public, even if the type alias itself is private. So, something
1468+
// like `type A = u8; pub fn f() -> A {...}` doesn't cause an error.
1469+
if let hir::ItemTy(ref ty, ref generics) = item.node {
1470+
let mut check = SearchInterfaceForPrivateItemsVisitor {
1471+
tcx: self.tcx, is_quiet: self.is_quiet,
1472+
is_public: true, old_error_set: self.old_error_set,
1473+
};
1474+
check.visit_ty(ty);
1475+
let provided_params = path.segments.last().unwrap().parameters.types().len();
1476+
for ty_param in &generics.ty_params[provided_params..] {
1477+
if let Some(ref default_ty) = ty_param.default {
1478+
check.visit_ty(default_ty);
1479+
}
1480+
}
1481+
check.is_public
1482+
} else {
1483+
false
1484+
}
1485+
}
1486+
}
1487+
14631488
impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> {
14641489
fn visit_ty(&mut self, ty: &hir::Ty) {
14651490
if self.is_quiet && !self.is_public {
14661491
// We are in quiet mode and a private type is already found, no need to proceed
14671492
return
14681493
}
1469-
if let hir::TyPath(..) = ty.node {
1494+
if let hir::TyPath(_, ref path) = ty.node {
14701495
let def = self.tcx.def_map.borrow().get(&ty.id).unwrap().full_def();
14711496
match def {
14721497
def::DefPrimTy(..) | def::DefSelfTy(..) | def::DefTyParam(..) => {
@@ -1482,12 +1507,7 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a,
14821507
// Non-local means public, local needs to be checked
14831508
if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) {
14841509
if let Some(ast_map::NodeItem(ref item)) = self.tcx.map.find(node_id) {
1485-
if let (&hir::ItemTy(..), true) = (&item.node, self.is_quiet) {
1486-
// Conservatively approximate the whole type alias as public without
1487-
// recursing into its components when determining impl publicity.
1488-
return
1489-
}
1490-
if item.vis != hir::Public {
1510+
if item.vis != hir::Public && !self.is_public_type_alias(item, path) {
14911511
if !self.is_quiet {
14921512
if self.old_error_set.contains(&ty.id) {
14931513
span_err!(self.tcx.sess, ty.span, E0446,

src/librustc_trans/back/msvc/registry.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::os::windows::prelude::*;
1414
use std::ptr;
1515
use libc::{c_void, c_long};
1616

17-
pub type DWORD = u32;
17+
type DWORD = u32;
1818
type LPCWSTR = *const u16;
1919
type LONG = c_long;
2020
type LPDWORD = *mut DWORD;

src/test/compile-fail/issue-28450-1.rs

-16
This file was deleted.

src/test/compile-fail/lint-visible-private-types-1.rs

+6
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,11 @@ impl PubTrait for <Private<isize> as PrivTrait2>::Alias {
3737
type Output = Private<isize>; //~ WARN private type in public interface
3838
}
3939

40+
type PrivAliasPubType = u8;
41+
pub fn f1(_: PrivAliasPubType) {} // Ok, not an error
42+
43+
type PrivAliasGeneric<T = Private<isize>> = T;
44+
pub fn f2(_: PrivAliasGeneric<u8>) {} // Ok, not an error
45+
4046
#[rustc_error]
4147
fn main() {} //~ ERROR compilation successful

src/test/compile-fail/lint-visible-private-types.rs

+9
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,12 @@ impl<T: ParamTrait<Private<isize>>> //~ ERROR private type in public interface
121121
ParamTrait<T> for Public<i8> {
122122
fn foo() -> T { panic!() }
123123
}
124+
125+
type PrivAliasPrivType = Private<isize>;
126+
pub fn f1(_: PrivAliasPrivType) {} //~ ERROR private type in public interface
127+
128+
type PrivAliasGeneric<T = Private<isize>> = T;
129+
pub fn f2(_: PrivAliasGeneric) {} //~ ERROR private type in public interface
130+
131+
type Result<T> = std::result::Result<T, Private<isize>>;
132+
pub fn f3(_: Result<u8>) {} //~ ERROR private type in public interface

0 commit comments

Comments
 (0)