Split up privacy checking so privacy_access_levels only does computations required for AccessLevels
This commit is contained in:
parent
f22dca0a1b
commit
d5bb71c9f1
7 changed files with 89 additions and 75 deletions
|
@ -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);
|
||||
});
|
||||
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, "death checking", || middle::dead::check_crate(tcx));
|
||||
}, {
|
||||
time(sess, "unused lib feature checking", || {
|
||||
stability::check_unused_or_stable_features(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));
|
||||
});
|
||||
});
|
||||
}, {
|
||||
time(sess, "lint checking", || lint::check_crate(tcx));
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
Lrc::new(visitor.access_levels)
|
||||
}
|
||||
|
||||
fn check_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, krate: CrateNum) {
|
||||
assert_eq!(krate, LOCAL_CRATE);
|
||||
|
||||
let access_levels = tcx.privacy_access_levels(LOCAL_CRATE);
|
||||
|
||||
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: false
|
||||
};
|
||||
intravisit::walk_crate(&mut pub_restricted_visitor, krate);
|
||||
pub_restricted_visitor.has_pub_restricted
|
||||
};
|
||||
|
||||
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`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue