Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"on-demandify" privacy and access levels #40771

Merged
merged 3 commits into from
Mar 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// 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;

Expand Down Expand Up @@ -81,7 +82,7 @@ pub enum DepNode<D: Clone + Debug> {
TypeckItemType(D),
UnusedTraitCheck,
CheckConst(D),
Privacy,
PrivacyAccessLevels(CrateNum),
IntrinsicCheck(D),
MatchCheck(D),

Expand Down Expand Up @@ -230,7 +231,7 @@ impl<D: Clone + Debug> DepNode<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),
Expand Down
12 changes: 8 additions & 4 deletions src/librustc/dep_graph/edges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,15 @@ impl<D: Clone + Debug + Eq + Hash> DepGraphEdges<D> {
}

/// Indicates that the current task `C` reads `v` by adding an
/// edge from `v` to `C`. If there is no current task, panics. If
/// you want to suppress this edge, use `ignore`.
/// edge from `v` to `C`. If there is no current task, has no
/// effect. Note that *reading* from tracked state is harmless if
/// you are not in a task; what is bad is *writing* to tracked
/// state (and leaking data that you read into a tracked task).
pub fn read(&mut self, v: DepNode<D>) {
let source = self.make_node(v);
self.add_edge_from_current_node(|current| (source, current))
if self.current_node().is_some() {
let source = self.make_node(v);
self.add_edge_from_current_node(|current| (source, current))
}
}

/// Indicates that the current task `C` writes `v` by adding an
Expand Down
10 changes: 8 additions & 2 deletions src/librustc/dep_graph/shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ impl ShadowGraph {

let mut stack = self.stack.borrow_mut();
match *message {
DepMessage::Read(ref n) => self.check_edge(Some(Some(n)), top(&stack)),
// It is ok to READ shared state outside of a
// task. That can't do any harm (at least, the only
// way it can do harm is by leaking that data into a
// query or task, which would be a problem
// anyway). What would be bad is WRITING to that
// state.
DepMessage::Read(_) => { }
DepMessage::Write(ref n) => self.check_edge(top(&stack), Some(Some(n))),
DepMessage::PushTask(ref n) => stack.push(Some(n.clone())),
DepMessage::PushIgnore => stack.push(None),
Expand Down Expand Up @@ -116,7 +122,7 @@ impl ShadowGraph {
(None, None) => unreachable!(),

// nothing on top of the stack
(None, Some(n)) | (Some(n), None) => bug!("read/write of {:?} but no current task", n),
(None, Some(n)) | (Some(n), None) => bug!("write of {:?} but no current task", n),

// this corresponds to an Ignore being top of the stack
(Some(None), _) | (_, Some(None)) => (),
Expand Down
8 changes: 5 additions & 3 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ use std::ops::Deref;
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;

Expand Down Expand Up @@ -1231,10 +1232,11 @@ fn check_lint_name_cmdline(sess: &Session, lint_cx: &LintStore,
/// 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.
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,8 +255,8 @@ pub trait CrateStore {
fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>;
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource;
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum>;
fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
reachable: &NodeSet) -> Vec<u8>;
fn metadata_encoding_version(&self) -> &[u8];
Expand Down Expand Up @@ -412,10 +412,10 @@ impl CrateStore for DummyCrateStore {
{ vec![] }
fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") }
fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> { None }
fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
link_meta: &LinkMeta,
reachable: &NodeSet) -> Vec<u8> { vec![] }
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
reachable: &NodeSet) -> Vec<u8> { vec![] }
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
}

Expand Down
7 changes: 4 additions & 3 deletions src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ use hir::itemlikevisit::ItemLikeVisitor;
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
Expand Down Expand Up @@ -592,9 +593,9 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
}
}

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 };
Expand Down
8 changes: 5 additions & 3 deletions src/librustc/middle/reachable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ use util::nodemap::{NodeSet, FxHashSet};
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;
Expand Down Expand Up @@ -359,11 +361,11 @@ impl<'a, 'tcx: 'a> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a,
}
}

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
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -656,10 +656,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// 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();
Expand Down
6 changes: 5 additions & 1 deletion src/librustc/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use session::Session;
use lint;
use middle;
use hir::TraitMap;
use hir::def::Def;
use hir::def::{Def, ExportMap};
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use hir::map as hir_map;
use hir::map::DisambiguatedDefPathData;
Expand Down Expand Up @@ -416,6 +416,9 @@ pub struct GlobalCtxt<'tcx> {
/// is relevant; generated by resolve.
pub trait_map: TraitMap,

/// Export map produced by name resolution.
pub export_map: ExportMap,

pub named_region_map: resolve_lifetime::NamedRegionMap,

pub region_maps: RegionMaps,
Expand Down Expand Up @@ -698,6 +701,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
region_maps: region_maps,
variance_computed: Cell::new(false),
trait_map: resolutions.trait_map,
export_map: resolutions.export_map,
fulfilled_predicates: RefCell::new(fulfilled_predicates),
hir: hir,
maps: maps::Maps::new(dep_graph, providers),
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/ty/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
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};

Expand Down Expand Up @@ -189,6 +190,12 @@ impl<'tcx> QueryDescription for queries::mir_shims<'tcx> {
}
}

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])*
Expand Down Expand Up @@ -406,6 +413,9 @@ define_maps! { <'tcx>
/// 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>>
}

Expand Down
9 changes: 6 additions & 3 deletions src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ pub use self::fold::TypeFoldable;

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;
Expand Down Expand Up @@ -108,10 +108,12 @@ mod sty;

/// 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 export_map: ExportMap,
pub access_levels: middle::privacy::AccessLevels,
pub access_levels: Rc<AccessLevels>,
pub reachable: NodeSet,
pub name: String,
pub glob_map: Option<hir::GlobMap>,
Expand All @@ -122,6 +124,7 @@ pub struct Resolutions {
pub freevars: FreevarMap,
pub trait_map: TraitMap,
pub maybe_unused_trait_imports: NodeSet,
pub export_map: ExportMap,
}

#[derive(Clone, Copy, PartialEq, Eq, Debug)]
Expand Down
24 changes: 10 additions & 14 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use std::fs;
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;
Expand Down Expand Up @@ -807,18 +808,18 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
expanded_crate: krate,
defs: resolver.definitions,
analysis: ty::CrateAnalysis {
export_map: resolver.export_map,
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 },
},
resolutions: Resolutions {
freevars: resolver.freevars,
export_map: resolver.export_map,
trait_map: resolver.trait_map,
maybe_unused_trait_imports: resolver.maybe_unused_trait_imports,
},
hir_forest: hir_forest
hir_forest: hir_forest,
})
}

Expand Down Expand Up @@ -888,6 +889,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,

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);

Expand Down Expand Up @@ -931,9 +933,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|| consts::check_crate(tcx));

analysis.access_levels =
time(time_passes, "privacy checking", || {
rustc_privacy::check_crate(tcx, &analysis.export_map)
});
time(time_passes, "privacy checking", || rustc_privacy::check_crate(tcx));

time(time_passes,
"intrinsic checking",
Expand Down Expand Up @@ -1000,19 +1000,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
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 {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,12 +496,12 @@ impl CrateStore for cstore::CStore {
self.do_extern_mod_stmt_cnum(emod_id)
}

fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
reexports: &def::ExportMap,
fn encode_metadata<'a, 'tcx>(&self,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
link_meta: &LinkMeta,
reachable: &NodeSet) -> Vec<u8>
{
encoder::encode_metadata(tcx, self, reexports, link_meta, reachable)
encoder::encode_metadata(tcx, self, link_meta, reachable)
}

fn metadata_encoding_version(&self) -> &[u8]
Expand Down
Loading