// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use hir::def_id::CrateNum;
use std::fmt::Debug;
use std::sync::Arc;
TypeckItemType(D),
UnusedTraitCheck,
CheckConst(D),
- Privacy,
+ PrivacyAccessLevels(CrateNum),
IntrinsicCheck(D),
MatchCheck(D),
CheckEntryFn => Some(CheckEntryFn),
Variance => Some(Variance),
UnusedTraitCheck => Some(UnusedTraitCheck),
- Privacy => Some(Privacy),
+ PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)),
Reachability => Some(Reachability),
DeadCheck => Some(DeadCheck),
LateLintCheck => Some(LateLintCheck),
use syntax::attr;
use syntax::ast;
use syntax::symbol::Symbol;
-use syntax_pos::{MultiSpan, Span};
+use syntax_pos::{DUMMY_SP, MultiSpan, Span};
use errors::{self, Diagnostic, DiagnosticBuilder};
use hir;
+use hir::def_id::LOCAL_CRATE;
use hir::intravisit as hir_visit;
use syntax::visit as ast_visit;
/// Perform lint checking on a crate.
///
/// Consumes the `lint_store` field of the `Session`.
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- access_levels: &AccessLevels) {
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let _task = tcx.dep_graph.in_task(DepNode::LateLintCheck);
+ let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
+
let krate = tcx.hir.krate();
// We want to own the lint store, so move it out of the session.
use middle::privacy;
use ty::{self, TyCtxt};
use hir::def::Def;
-use hir::def_id::{DefId};
+use hir::def_id::{DefId, LOCAL_CRATE};
use lint;
use util::nodemap::FxHashSet;
use syntax::{ast, codemap};
use syntax::attr;
+use syntax::codemap::DUMMY_SP;
use syntax_pos;
// Any local node that may call something in its body block should be
}
}
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- access_levels: &privacy::AccessLevels) {
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let _task = tcx.dep_graph.in_task(DepNode::DeadCheck);
+ let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
let krate = tcx.hir.krate();
let live_symbols = find_live(tcx, access_levels, krate);
let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols };
use syntax::abi::Abi;
use syntax::ast;
use syntax::attr;
+use syntax::codemap::DUMMY_SP;
use hir;
+use hir::def_id::LOCAL_CRATE;
use hir::intravisit::{Visitor, NestedVisitorMap};
use hir::itemlikevisit::ItemLikeVisitor;
use hir::intravisit;
}
}
-pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- access_levels: &privacy::AccessLevels)
- -> NodeSet {
+pub fn find_reachable<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> NodeSet {
let _task = tcx.dep_graph.in_task(DepNode::Reachability);
+ let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
+
let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
*ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib ||
*ty == config::CrateTypeProcMacro
/// Given the list of enabled features that were not language features (i.e. that
/// were expected to be library features), and the list of features used from
/// libraries, identify activated features that don't exist and error about them.
-pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
- access_levels: &AccessLevels) {
+pub fn check_unused_or_stable_features<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let sess = &tcx.sess;
+ let access_levels = &ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE);
+
if tcx.stability.borrow().staged_api[&LOCAL_CRATE] && tcx.sess.features.borrow().staged_api {
let _task = tcx.dep_graph.in_task(DepNode::StabilityIndex);
let krate = tcx.hir.krate();
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use middle::const_val::ConstVal;
+use middle::privacy::AccessLevels;
use mir;
use ty::{self, Ty, TyCtxt};
}
}
+impl<'tcx> QueryDescription for queries::privacy_access_levels<'tcx> {
+ fn describe(_: TyCtxt, _: CrateNum) -> String {
+ format!("privacy access levels")
+ }
+}
+
macro_rules! define_maps {
(<$tcx:tt>
$($(#[$attr:meta])*
/// other items, such as enum variant explicit discriminants.
pub monomorphic_const_eval: MonomorphicConstEval(DefId) -> Result<ConstVal<'tcx>, ()>,
+ /// Performs the privacy check and computes "access levels".
+ pub privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Rc<AccessLevels>,
+
pub mir_shims: mir_shim(ty::InstanceDef<'tcx>) -> &'tcx RefCell<mir::Mir<'tcx>>
}
use dep_graph::{self, DepNode};
use hir::{map as hir_map, FreevarMap, TraitMap};
-use middle;
use hir::def::{Def, CtorKind, ExportMap};
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
use middle::const_val::ConstVal;
use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
+use middle::privacy::AccessLevels;
use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
use middle::resolve_lifetime::ObjectLifetimeDefault;
use mir::Mir;
/// The complete set of all analyses described in this module. This is
/// produced by the driver and fed to trans and later passes.
+///
+/// NB: These contents are being migrated into queries using the
+/// *on-demand* infrastructure.
#[derive(Clone)]
pub struct CrateAnalysis {
- pub access_levels: middle::privacy::AccessLevels,
+ pub access_levels: Rc<AccessLevels>,
pub reachable: NodeSet,
pub name: String,
pub glob_map: Option<hir::GlobMap>,
use std::io::{self, Write};
use std::iter;
use std::path::{Path, PathBuf};
+use std::rc::Rc;
use syntax::{ast, diagnostics, visit};
use syntax::attr;
use syntax::ext::base::ExtCtxt;
expanded_crate: krate,
defs: resolver.definitions,
analysis: ty::CrateAnalysis {
- access_levels: AccessLevels::default(),
+ access_levels: Rc::new(AccessLevels::default()),
reachable: NodeSet(),
name: crate_name.to_string(),
glob_map: if resolver.make_glob_map { Some(resolver.glob_map) } else { None },
let mut local_providers = ty::maps::Providers::default();
mir::provide(&mut local_providers);
+ rustc_privacy::provide(&mut local_providers);
typeck::provide(&mut local_providers);
ty::provide(&mut local_providers);
|| consts::check_crate(tcx));
analysis.access_levels =
- time(time_passes, "privacy checking", || {
- rustc_privacy::check_crate(tcx)
- });
+ time(time_passes, "privacy checking", || rustc_privacy::check_crate(tcx));
time(time_passes,
"intrinsic checking",
analysis.reachable =
time(time_passes,
"reachability checking",
- || reachable::find_reachable(tcx, &analysis.access_levels));
+ || reachable::find_reachable(tcx));
- time(time_passes, "death checking", || {
- middle::dead::check_crate(tcx, &analysis.access_levels);
- });
+ time(time_passes, "death checking", || middle::dead::check_crate(tcx));
time(time_passes, "unused lib feature checking", || {
- stability::check_unused_or_stable_features(tcx, &analysis.access_levels)
+ stability::check_unused_or_stable_features(tcx)
});
- time(time_passes,
- "lint checking",
- || lint::check_crate(tcx, &analysis.access_levels));
+ time(time_passes, "lint checking", || lint::check_crate(tcx));
// The above three passes generate errors w/o aborting
if sess.err_count() > 0 {
html_root_url = "https://doc.rust-lang.org/nightly/")]
#![deny(warnings)]
+#![cfg_attr(stage0, feature(field_init_shorthand))]
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
#[macro_use] extern crate syntax;
extern crate syntax_pos;
-use rustc::dep_graph::DepNode;
use rustc::hir::{self, PatKind};
use rustc::hir::def::Def;
-use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
+use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, CrateNum, DefId};
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
use rustc::hir::itemlikevisit::DeepVisitor;
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
use rustc::middle::privacy::{AccessLevel, AccessLevels};
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
use rustc::ty::fold::TypeVisitor;
+use rustc::ty::maps::Providers;
use rustc::util::nodemap::NodeSet;
use syntax::ast;
-use syntax_pos::Span;
+use syntax_pos::{DUMMY_SP, Span};
use std::cmp;
use std::mem::replace;
+use std::rc::Rc;
pub mod diagnostics;
fn visit_pat(&mut self, _: &'tcx hir::Pat) {}
}
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> AccessLevels {
- let _task = tcx.dep_graph.in_task(DepNode::Privacy);
+pub fn provide(providers: &mut Providers) {
+ *providers = Providers {
+ privacy_access_levels,
+ ..*providers
+ };
+}
+
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Rc<AccessLevels> {
+ tcx.dep_graph.with_ignore(|| { // FIXME
+ ty::queries::privacy_access_levels::get(tcx, DUMMY_SP, LOCAL_CRATE)
+ })
+}
+
+fn privacy_access_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+ krate: CrateNum)
+ -> Rc<AccessLevels> {
+ assert_eq!(krate, LOCAL_CRATE);
let krate = tcx.hir.krate();
krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
}
- visitor.access_levels
+ Rc::new(visitor.access_levels)
}
__build_diagnostic_array! { librustc_privacy, DIAGNOSTICS }
// Convert from a NodeId set to a DefId set since we don't always have easy access
// to the map from defid -> nodeid
let access_levels = AccessLevels {
- map: access_levels.map.into_iter()
- .map(|(k, v)| (tcx.hir.local_def_id(k), v))
+ map: access_levels.map.iter()
+ .map(|(&k, &v)| (tcx.hir.local_def_id(k), v))
.collect()
};