Skip to content

Commit

Permalink
Move privacy checking later in the pipeline and make some passes run …
Browse files Browse the repository at this point in the history
…in parallel
  • Loading branch information
Zoxc committed Jan 30, 2019
1 parent d9a2e3b commit 38bcd4b
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 104 deletions.
26 changes: 10 additions & 16 deletions src/librustc/hir/mod.rs
Expand Up @@ -30,7 +30,7 @@ use syntax::util::parser::ExprPrecedence;
use ty::AdtKind;
use ty::query::Providers;

use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync, scope};
use rustc_data_structures::sync::{ParallelIterator, par_iter, Send, Sync};
use rustc_data_structures::thin_vec::ThinVec;

use serialize::{self, Encoder, Encodable, Decoder, Decodable};
Expand Down Expand Up @@ -754,23 +754,17 @@ impl Crate {
pub fn par_visit_all_item_likes<'hir, V>(&'hir self, visitor: &V)
where V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send
{
scope(|s| {
s.spawn(|_| {
par_iter(&self.items).for_each(|(_, item)| {
visitor.visit_item(item);
});
parallel!({
par_iter(&self.items).for_each(|(_, item)| {
visitor.visit_item(item);
});

s.spawn(|_| {
par_iter(&self.trait_items).for_each(|(_, trait_item)| {
visitor.visit_trait_item(trait_item);
});
}, {
par_iter(&self.trait_items).for_each(|(_, trait_item)| {
visitor.visit_trait_item(trait_item);
});

s.spawn(|_| {
par_iter(&self.impl_items).for_each(|(_, impl_item)| {
visitor.visit_impl_item(impl_item);
});
}, {
par_iter(&self.impl_items).for_each(|(_, impl_item)| {
visitor.visit_impl_item(impl_item);
});
});
}
Expand Down
1 change: 0 additions & 1 deletion src/librustc/middle/liveness.rs
Expand Up @@ -189,7 +189,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
for &module in tcx.hir().krate().modules.keys() {
queries::check_mod_liveness::ensure(tcx, tcx.hir().local_def_id(module));
}
tcx.sess.abort_if_errors();
}

pub fn provide(providers: &mut Providers<'_>) {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/session/mod.rs
Expand Up @@ -85,7 +85,7 @@ pub struct Session {
/// in order to avoid redundantly verbose output (Issue #24690, #44953).
pub one_time_diagnostics: Lock<FxHashSet<(DiagnosticMessageId, Option<Span>, String)>>,
pub plugin_llvm_passes: OneThread<RefCell<Vec<String>>>,
pub plugin_attributes: OneThread<RefCell<Vec<(String, AttributeType)>>>,
pub plugin_attributes: Lock<Vec<(String, AttributeType)>>,
pub crate_types: Once<Vec<config::CrateType>>,
pub dependency_formats: Once<dependency_format::Dependencies>,
/// The crate_disambiguator is constructed out of all the `-C metadata`
Expand Down Expand Up @@ -1178,7 +1178,7 @@ pub fn build_session_(
buffered_lints: Lock::new(Some(Default::default())),
one_time_diagnostics: Default::default(),
plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),
plugin_attributes: OneThread::new(RefCell::new(Vec::new())),
plugin_attributes: Lock::new(Vec::new()),
crate_types: Once::new(),
dependency_formats: Once::new(),
crate_disambiguator: Once::new(),
Expand Down
27 changes: 27 additions & 0 deletions src/librustc_data_structures/sync.rs
Expand Up @@ -127,6 +127,13 @@ cfg_if! {
pub use self::serial_join as join;
pub use self::serial_scope as scope;

#[macro_export]
macro_rules! parallel {
($($blocks:tt),*) => {
$($blocks)*;
}
}

pub use std::iter::Iterator as ParallelIterator;

pub fn par_iter<T: IntoIterator>(t: T) -> T::IntoIter {
Expand Down Expand Up @@ -271,6 +278,26 @@ cfg_if! {
use std::thread;
pub use rayon::{join, scope};

#[macro_export]
macro_rules! parallel {
(impl [$($c:tt,)*] [$block:tt $(, $rest:tt)*]) => {
parallel!(impl [$block, $($c,)*] [$($rest),*])
};
(impl [$($blocks:tt,)*] []) => {
::rustc_data_structures::sync::scope(|s| {
$(
s.spawn(|_| $blocks);
)*
})
};
($($blocks:tt),*) => {
// Reverse the order of the blocks since Rayon executes them in reverse order
// when using a single thread. This ensures the execution order matches that
// of a single threaded rustc
parallel!(impl [] [$($blocks),*]);
};
}

pub use rayon_core::WorkerLocal;

pub use rayon::iter::ParallelIterator;
Expand Down
102 changes: 58 additions & 44 deletions src/librustc_driver/driver.rs
Expand Up @@ -1222,26 +1222,28 @@ where
// tcx available.
time(sess, "dep graph tcx init", || rustc_incremental::dep_graph_tcx_init(tcx));

time(sess, "looking for entry point", || {
middle::entry::find_entry_point(tcx)
});

time(sess, "looking for plugin registrar", || {
plugin::build::find_plugin_registrar(tcx)
});

time(sess, "looking for derive registrar", || {
proc_macro_decls::find(tcx)
});

time(sess, "loop checking", || loops::check_crate(tcx));
parallel!({
time(sess, "looking for entry point", || {
middle::entry::find_entry_point(tcx)
});

time(sess, "attribute checking", || {
hir::check_attr::check_crate(tcx)
});
time(sess, "looking for plugin registrar", || {
plugin::build::find_plugin_registrar(tcx)
});

time(sess, "stability checking", || {
stability::check_unstable_api_usage(tcx)
time(sess, "looking for derive registrar", || {
proc_macro_decls::find(tcx)
});
}, {
time(sess, "loop checking", || loops::check_crate(tcx));
}, {
time(sess, "attribute checking", || {
hir::check_attr::check_crate(tcx)
});
}, {
time(sess, "stability checking", || {
stability::check_unstable_api_usage(tcx)
});
});

// passes are timed inside typeck
Expand All @@ -1253,27 +1255,31 @@ where
}
}

time(sess, "rvalue promotion", || {
rvalue_promotion::check_crate(tcx)
});

time(sess, "privacy checking", || {
rustc_privacy::check_crate(tcx)
});

time(sess, "intrinsic checking", || {
middle::intrinsicck::check_crate(tcx)
time(sess, "misc checking", || {
parallel!({
time(sess, "rvalue promotion", || {
rvalue_promotion::check_crate(tcx)
});
}, {
time(sess, "intrinsic checking", || {
middle::intrinsicck::check_crate(tcx)
});
}, {
time(sess, "match checking", || mir::matchck_crate(tcx));
}, {
// this must run before MIR dump, because
// "not all control paths return a value" is reported here.
//
// maybe move the check to a MIR pass?
time(sess, "liveness checking", || {
middle::liveness::check_crate(tcx)
});
});
});

time(sess, "match checking", || mir::matchck_crate(tcx));

// this must run before MIR dump, because
// "not all control paths return a value" is reported here.
//
// maybe move the check to a MIR pass?
time(sess, "liveness checking", || {
middle::liveness::check_crate(tcx)
});
// Abort so we don't try to construct MIR with liveness errors.
// We also won't want to continue with errors from rvalue promotion
tcx.sess.abort_if_errors();

time(sess, "borrow checking", || {
if tcx.use_ast_borrowck() {
Expand All @@ -1297,7 +1303,7 @@ where

time(sess, "layout testing", || layout_test::test_layout(tcx));

// Avoid overwhelming user with errors if type checking failed.
// Avoid overwhelming user with errors if borrow checking failed.
// I'm not sure how helpful this is, to be honest, but it avoids
// a
// lot of annoying errors in the compile-fail tests (basically,
Expand All @@ -1307,14 +1313,22 @@ where
return Ok(f(tcx, rx, sess.compile_status()));
}

time(sess, "death checking", || middle::dead::check_crate(tcx));

time(sess, "unused lib feature checking", || {
stability::check_unused_or_stable_features(tcx)
time(sess, "misc checking", || {
parallel!({
time(sess, "privacy checking", || {
rustc_privacy::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, "lint checking", || lint::check_crate(tcx));
});
});

time(sess, "lint checking", || lint::check_crate(tcx));

return Ok(f(tcx, rx, tcx.sess.compile_status()));
},
)
Expand Down
1 change: 1 addition & 0 deletions src/librustc_driver/lib.rs
Expand Up @@ -30,6 +30,7 @@ extern crate rustc;
extern crate rustc_allocator;
extern crate rustc_target;
extern crate rustc_borrowck;
#[macro_use]
extern crate rustc_data_structures;
extern crate rustc_errors as errors;
extern crate rustc_passes;
Expand Down
1 change: 0 additions & 1 deletion src/librustc_passes/rvalue_promotion.rs
Expand Up @@ -44,7 +44,6 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let def_id = tcx.hir().body_owner_def_id(body_id);
tcx.const_is_rvalue_promotable_to_static(def_id);
}
tcx.sess.abort_if_errors();
}

fn const_is_rvalue_promotable_to_static<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/error-codes/E0446.rs
@@ -1,4 +1,4 @@
mod Foo {
mod foo {
struct Bar(u32);

pub fn bar() -> Bar { //~ ERROR E0446
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/error-codes/E0446.stderr
@@ -1,8 +1,8 @@
error[E0446]: private type `Foo::Bar` in public interface
error[E0446]: private type `foo::Bar` in public interface
--> $DIR/E0446.rs:4:5
|
LL | struct Bar(u32);
| - `Foo::Bar` declared as private
| - `foo::Bar` declared as private
LL |
LL | / pub fn bar() -> Bar { //~ ERROR E0446
LL | | Bar(0)
Expand Down
8 changes: 4 additions & 4 deletions src/test/ui/error-codes/E0451.rs
@@ -1,4 +1,4 @@
mod Bar {
mod bar {
pub struct Foo {
pub a: isize,
b: isize,
Expand All @@ -10,10 +10,10 @@ mod Bar {
);
}

fn pat_match(foo: Bar::Foo) {
let Bar::Foo{a:a, b:b} = foo; //~ ERROR E0451
fn pat_match(foo: bar::Foo) {
let bar::Foo{a, b} = foo; //~ ERROR E0451
}

fn main() {
let f = Bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451
let f = bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451
}
12 changes: 6 additions & 6 deletions src/test/ui/error-codes/E0451.stderr
@@ -1,13 +1,13 @@
error[E0451]: field `b` of struct `Bar::Foo` is private
--> $DIR/E0451.rs:14:23
error[E0451]: field `b` of struct `bar::Foo` is private
--> $DIR/E0451.rs:14:21
|
LL | let Bar::Foo{a:a, b:b} = foo; //~ ERROR E0451
| ^^^ field `b` is private
LL | let bar::Foo{a, b} = foo; //~ ERROR E0451
| ^ field `b` is private

error[E0451]: field `b` of struct `Bar::Foo` is private
error[E0451]: field `b` of struct `bar::Foo` is private
--> $DIR/E0451.rs:18:29
|
LL | let f = Bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451
LL | let f = bar::Foo{ a: 0, b: 0 }; //~ ERROR E0451
| ^^^^ field `b` is private

error: aborting due to 2 previous errors
Expand Down
Expand Up @@ -6,12 +6,12 @@ use self::foo::S;
mod foo {
use std::cell::{UnsafeCell};

static mut count : UnsafeCell<u64> = UnsafeCell::new(1);
static mut COUNT : UnsafeCell<u64> = UnsafeCell::new(1);

pub struct S { pub a: u8, pub b: String, secret_uid: u64 }

pub fn make_secrets(a: u8, b: String) -> S {
let val = unsafe { let p = count.get(); let val = *p; *p = val + 1; val };
let val = unsafe { let p = COUNT.get(); let val = *p; *p = val + 1; val };
println!("creating {}, uid {}", b, val);
S { a: a, b: b, secret_uid: val }
}
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/privacy/private-in-public-warn.rs
Expand Up @@ -49,6 +49,7 @@ mod traits {

pub type Alias<T: PrivTr> = T; //~ ERROR private trait `traits::PrivTr` in public interface
//~| WARNING hard error
//~| WARNING bounds on generic parameters are not enforced in type aliases
pub trait Tr1: PrivTr {} //~ ERROR private trait `traits::PrivTr` in public interface
//~^ WARNING hard error
pub trait Tr2<T: PrivTr> {} //~ ERROR private trait `traits::PrivTr` in public interface
Expand All @@ -74,6 +75,7 @@ mod traits_where {
pub type Alias<T> where T: PrivTr = T;
//~^ ERROR private trait `traits_where::PrivTr` in public interface
//~| WARNING hard error
//~| WARNING where clauses are not enforced in type aliases
pub trait Tr2<T> where T: PrivTr {}
//~^ ERROR private trait `traits_where::PrivTr` in public interface
//~| WARNING hard error
Expand Down

0 comments on commit 38bcd4b

Please sign in to comment.