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,
|
[eval_always] CoherenceInherentImplOverlapCheck,
|
||||||
[] CoherenceCheckTrait(DefId),
|
[] CoherenceCheckTrait(DefId),
|
||||||
[eval_always] PrivacyAccessLevels(CrateNum),
|
[eval_always] PrivacyAccessLevels(CrateNum),
|
||||||
|
[eval_always] CheckPrivacy(CrateNum),
|
||||||
[eval_always] Analysis(CrateNum),
|
[eval_always] Analysis(CrateNum),
|
||||||
|
|
||||||
// Represents the MIR for a fn; also used as the task node for
|
// 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> {
|
impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
|
||||||
fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
|
fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
|
||||||
"type-checking all item bodies".into()
|
"type-checking all item bodies".into()
|
||||||
|
|
|
@ -350,8 +350,9 @@ define_queries! { <'tcx>
|
||||||
[] fn check_match: CheckMatch(DefId)
|
[] fn check_match: CheckMatch(DefId)
|
||||||
-> Result<(), ErrorReported>,
|
-> 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 privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Lrc<AccessLevels>,
|
||||||
|
[] fn check_privacy: CheckPrivacy(CrateNum) -> (),
|
||||||
},
|
},
|
||||||
|
|
||||||
Other {
|
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)
|
force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
|
||||||
},
|
},
|
||||||
DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, 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::MirBuilt => { force!(mir_built, def_id!()); }
|
||||||
DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
|
DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
|
||||||
DepKind::MirConst => { force!(mir_const, 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_codegen_utils::codegen_backend::CodegenBackend;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::stable_hasher::StableHasher;
|
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_incremental;
|
||||||
use rustc_metadata::creader::CrateLoader;
|
use rustc_metadata::creader::CrateLoader;
|
||||||
use rustc_metadata::cstore::{self, CStore};
|
use rustc_metadata::cstore::{self, CStore};
|
||||||
|
@ -277,9 +277,13 @@ fn analysis<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
time(sess, "misc checking", || {
|
time(sess, "misc checking", || {
|
||||||
|
parallel!({
|
||||||
|
time(sess, "privacy access levels", || {
|
||||||
|
tcx.ensure().privacy_access_levels(LOCAL_CRATE);
|
||||||
|
});
|
||||||
parallel!({
|
parallel!({
|
||||||
time(sess, "privacy checking", || {
|
time(sess, "privacy checking", || {
|
||||||
rustc_privacy::check_crate(tcx)
|
tcx.ensure().check_privacy(LOCAL_CRATE);
|
||||||
});
|
});
|
||||||
}, {
|
}, {
|
||||||
time(sess, "death checking", || middle::dead::check_crate(tcx));
|
time(sess, "death checking", || middle::dead::check_crate(tcx));
|
||||||
|
@ -290,6 +294,13 @@ fn analysis<'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));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1760,19 +1760,15 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
|
||||||
pub fn provide(providers: &mut Providers<'_>) {
|
pub fn provide(providers: &mut Providers<'_>) {
|
||||||
*providers = Providers {
|
*providers = Providers {
|
||||||
privacy_access_levels,
|
privacy_access_levels,
|
||||||
|
check_privacy,
|
||||||
check_mod_privacy,
|
check_mod_privacy,
|
||||||
..*providers
|
..*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) {
|
fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
|
||||||
let empty_tables = ty::TypeckTables::empty(None);
|
let empty_tables = ty::TypeckTables::empty(None);
|
||||||
|
|
||||||
|
|
||||||
// Check privacy of names not checked in previous compilation stages.
|
// Check privacy of names not checked in previous compilation stages.
|
||||||
let mut visitor = NamePrivacyVisitor {
|
let mut visitor = NamePrivacyVisitor {
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -1803,18 +1799,6 @@ fn privacy_access_levels<'tcx>(
|
||||||
) -> Lrc<AccessLevels> {
|
) -> Lrc<AccessLevels> {
|
||||||
assert_eq!(krate, LOCAL_CRATE);
|
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
|
// 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.
|
// items which are reachable from external crates based on visibility.
|
||||||
let mut visitor = EmbargoVisitor {
|
let mut visitor = EmbargoVisitor {
|
||||||
|
@ -1824,7 +1808,7 @@ fn privacy_access_levels<'tcx>(
|
||||||
changed: false,
|
changed: false,
|
||||||
};
|
};
|
||||||
loop {
|
loop {
|
||||||
intravisit::walk_crate(&mut visitor, krate);
|
intravisit::walk_crate(&mut visitor, tcx.hir().krate());
|
||||||
if visitor.changed {
|
if visitor.changed {
|
||||||
visitor.changed = false;
|
visitor.changed = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1833,16 +1817,24 @@ fn privacy_access_levels<'tcx>(
|
||||||
}
|
}
|
||||||
visitor.update(hir::CRATE_HIR_ID, Some(AccessLevel::Public));
|
visitor.update(hir::CRATE_HIR_ID, Some(AccessLevel::Public));
|
||||||
|
|
||||||
{
|
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 {
|
let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
|
||||||
tcx,
|
tcx,
|
||||||
access_levels: &visitor.access_levels,
|
access_levels: &access_levels,
|
||||||
in_variant: false,
|
in_variant: false,
|
||||||
old_error_set: Default::default(),
|
old_error_set: Default::default(),
|
||||||
};
|
};
|
||||||
intravisit::walk_crate(&mut visitor, krate);
|
intravisit::walk_crate(&mut visitor, krate);
|
||||||
|
|
||||||
|
|
||||||
let has_pub_restricted = {
|
let has_pub_restricted = {
|
||||||
let mut pub_restricted_visitor = PubRestrictedVisitor {
|
let mut pub_restricted_visitor = PubRestrictedVisitor {
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -1852,6 +1844,11 @@ fn privacy_access_levels<'tcx>(
|
||||||
pub_restricted_visitor.has_pub_restricted
|
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.
|
// Check for private types and traits in public interfaces.
|
||||||
let mut visitor = PrivateItemsInPublicInterfacesVisitor {
|
let mut visitor = PrivateItemsInPublicInterfacesVisitor {
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -1862,7 +1859,4 @@ fn privacy_access_levels<'tcx>(
|
||||||
krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
|
krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
|
||||||
}
|
}
|
||||||
|
|
||||||
Lrc::new(visitor.access_levels)
|
|
||||||
}
|
|
||||||
|
|
||||||
__build_diagnostic_array! { librustc_privacy, DIAGNOSTICS }
|
__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
|
error: type `m::Priv` is private
|
||||||
--> $DIR/private-inferred-type.rs:97:9
|
--> $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
|
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
|
error: aborting due to 33 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0446`.
|
For more information about this error, try `rustc --explain E0446`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue