Skip to content
Permalink
Browse files

Split up privacy checking so privacy_access_levels only does computat…

…ions required for AccessLevels
  • Loading branch information...
Zoxc committed Feb 23, 2019
1 parent f22dca0 commit d5bb71c9f1042c0c931c7dddecc418233de6e30f
@@ -456,6 +456,7 @@ define_dep_nodes!( <'tcx>
[eval_always] CoherenceInherentImplOverlapCheck,
[] CoherenceCheckTrait(DefId),
[eval_always] PrivacyAccessLevels(CrateNum),
[eval_always] CheckPrivacy(CrateNum),
[eval_always] Analysis(CrateNum),

// Represents the MIR for a fn; also used as the task node for
@@ -369,6 +369,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::privacy_access_levels<'tcx> {
}
}

impl<'tcx> QueryDescription<'tcx> for queries::check_privacy<'tcx> {
fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
"privacy checking".into()
}
}

impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
"type-checking all item bodies".into()
@@ -350,8 +350,9 @@ define_queries! { <'tcx>
[] fn check_match: CheckMatch(DefId)
-> Result<(), ErrorReported>,

/// Performs the privacy check and computes "access levels".
/// Performs part of the privacy check and computes "access levels".
[] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Lrc<AccessLevels>,
[] fn check_privacy: CheckPrivacy(CrateNum) -> (),
},

Other {
@@ -1251,6 +1251,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
},
DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
DepKind::CheckPrivacy => { force!(check_privacy, LOCAL_CRATE); }
DepKind::MirBuilt => { force!(mir_built, def_id!()); }
DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
DepKind::MirConst => { force!(mir_const, def_id!()); }
@@ -21,7 +21,7 @@ use rustc_borrowck as borrowck;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_data_structures::sync::Lrc;
use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
use rustc_incremental;
use rustc_metadata::creader::CrateLoader;
use rustc_metadata::cstore::{self, CStore};
@@ -278,17 +278,28 @@ fn analysis<'tcx>(

time(sess, "misc checking", || {
parallel!({
time(sess, "privacy checking", || {
rustc_privacy::check_crate(tcx)
time(sess, "privacy access levels", || {
tcx.ensure().privacy_access_levels(LOCAL_CRATE);
});
}, {
time(sess, "death checking", || middle::dead::check_crate(tcx));
}, {
time(sess, "unused lib feature checking", || {
stability::check_unused_or_stable_features(tcx)
parallel!({
time(sess, "privacy checking", || {
tcx.ensure().check_privacy(LOCAL_CRATE);
});
}, {
time(sess, "death checking", || middle::dead::check_crate(tcx));
}, {
time(sess, "unused lib feature checking", || {
stability::check_unused_or_stable_features(tcx)
});
}, {
time(sess, "lint checking", || lint::check_crate(tcx));
});
}, {
time(sess, "lint checking", || lint::check_crate(tcx));
time(sess, "privacy checking modules", || {
par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module));
});
});
});
});

@@ -1760,19 +1760,15 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
pub fn provide(providers: &mut Providers<'_>) {
*providers = Providers {
privacy_access_levels,
check_privacy,
check_mod_privacy,
..*providers
};
}

pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Lrc<AccessLevels> {
tcx.privacy_access_levels(LOCAL_CRATE)
}

fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
let empty_tables = ty::TypeckTables::empty(None);


// Check privacy of names not checked in previous compilation stages.
let mut visitor = NamePrivacyVisitor {
tcx,
@@ -1803,18 +1799,6 @@ fn privacy_access_levels<'tcx>(
) -> Lrc<AccessLevels> {
assert_eq!(krate, LOCAL_CRATE);

let krate = tcx.hir().krate();

for &module in krate.modules.keys() {
tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module));
}

let private_crates: FxHashSet<CrateNum> = tcx.sess.opts.extern_private.iter()
.flat_map(|c| {
tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned()
}).collect();


// Build up a set of all exported items in the AST. This is a set of all
// items which are reachable from external crates based on visibility.
let mut visitor = EmbargoVisitor {
@@ -1824,7 +1808,7 @@ fn privacy_access_levels<'tcx>(
changed: false,
};
loop {
intravisit::walk_crate(&mut visitor, krate);
intravisit::walk_crate(&mut visitor, tcx.hir().krate());
if visitor.changed {
visitor.changed = false;
} else {
@@ -1833,36 +1817,46 @@ fn privacy_access_levels<'tcx>(
}
visitor.update(hir::CRATE_HIR_ID, Some(AccessLevel::Public));

{
let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
tcx,
access_levels: &visitor.access_levels,
in_variant: false,
old_error_set: Default::default(),
};
intravisit::walk_crate(&mut visitor, krate);
Lrc::new(visitor.access_levels)
}

fn check_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, krate: CrateNum) {
assert_eq!(krate, LOCAL_CRATE);

let has_pub_restricted = {
let mut pub_restricted_visitor = PubRestrictedVisitor {
tcx,
has_pub_restricted: false
};
intravisit::walk_crate(&mut pub_restricted_visitor, krate);
pub_restricted_visitor.has_pub_restricted
};
let access_levels = tcx.privacy_access_levels(LOCAL_CRATE);

// Check for private types and traits in public interfaces.
let mut visitor = PrivateItemsInPublicInterfacesVisitor {
let krate = tcx.hir().krate();

let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
tcx,
access_levels: &access_levels,
in_variant: false,
old_error_set: Default::default(),
};
intravisit::walk_crate(&mut visitor, krate);

let has_pub_restricted = {
let mut pub_restricted_visitor = PubRestrictedVisitor {
tcx,
has_pub_restricted,
old_error_set: &visitor.old_error_set,
private_crates
has_pub_restricted: false
};
krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
}
intravisit::walk_crate(&mut pub_restricted_visitor, krate);
pub_restricted_visitor.has_pub_restricted
};

Lrc::new(visitor.access_levels)
let private_crates: FxHashSet<CrateNum> = tcx.sess.opts.extern_private.iter()
.flat_map(|c| {
tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned()
}).collect();

// Check for private types and traits in public interfaces.
let mut visitor = PrivateItemsInPublicInterfacesVisitor {
tcx,
has_pub_restricted,
old_error_set: &visitor.old_error_set,
private_crates
};
krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
}

__build_diagnostic_array! { librustc_privacy, DIAGNOSTICS }
@@ -1,3 +1,21 @@
error[E0446]: private type `m::Priv` in public interface
--> $DIR/private-inferred-type.rs:61:36
|
LL | struct Priv;
| - `m::Priv` declared as private
...
LL | impl TraitWithAssocTy for u8 { type AssocTy = Priv; }
| ^^^^^^^^^^^^^^^^^^^^ can't leak private type

error[E0446]: private type `adjust::S2` in public interface
--> $DIR/private-inferred-type.rs:83:9
|
LL | struct S2;
| - `adjust::S2` declared as private
...
LL | type Target = S2Alias; //~ ERROR private type `adjust::S2` in public interface
| ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type

error: type `m::Priv` is private
--> $DIR/private-inferred-type.rs:97:9
|
@@ -202,24 +220,6 @@ error: type `m::Priv` is private
LL | match a { //~ ERROR type `m::Priv` is private
| ^

error[E0446]: private type `m::Priv` in public interface
--> $DIR/private-inferred-type.rs:61:36
|
LL | struct Priv;
| - `m::Priv` declared as private
...
LL | impl TraitWithAssocTy for u8 { type AssocTy = Priv; }
| ^^^^^^^^^^^^^^^^^^^^ can't leak private type

error[E0446]: private type `adjust::S2` in public interface
--> $DIR/private-inferred-type.rs:83:9
|
LL | struct S2;
| - `adjust::S2` declared as private
...
LL | type Target = S2Alias; //~ ERROR private type `adjust::S2` in public interface
| ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type

error: aborting due to 33 previous errors

For more information about this error, try `rustc --explain E0446`.

0 comments on commit d5bb71c

Please sign in to comment.
You can’t perform that action at this time.