Skip to content

Commit 27c98b8

Browse files
committed
Parallelize type collecting and item-types checking
1 parent 45d4695 commit 27c98b8

File tree

7 files changed

+74
-17
lines changed

7 files changed

+74
-17
lines changed

src/librustc/hir/map/mod.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ use crate::middle::cstore::CrateStoreDyn;
88
use crate::ty::query::Providers;
99
use rustc_data_structures::fx::FxHashMap;
1010
use rustc_data_structures::svh::Svh;
11+
12+
use rustc_data_structures::sync::{self, par_for_each};
1113
use rustc_hir::def::{DefKind, Res};
1214
use rustc_hir::def_id::{DefId, DefIndex, LocalDefId, CRATE_DEF_INDEX};
1315
use rustc_hir::intravisit;
14-
use rustc_hir::itemlikevisit::ItemLikeVisitor;
16+
use rustc_hir::itemlikevisit::{ItemLikeVisitor, ParItemLikeVisitor};
1517
use rustc_hir::print::Nested;
1618
use rustc_hir::*;
1719
use rustc_index::vec::IndexVec;
@@ -582,6 +584,40 @@ impl<'hir> Map<'hir> {
582584
}
583585
}
584586

587+
/// A parallel version of `visit_item_likes_in_module`.
588+
pub fn par_visit_item_likes_in_module<V>(&self, module: DefId, visitor: &V)
589+
where
590+
V: ParItemLikeVisitor<'hir> + sync::Sync,
591+
{
592+
let hir_id = self.as_local_hir_id(module).unwrap();
593+
594+
// Read the module so we'll be re-executed if new items
595+
// appear immediately under in the module. If some new item appears
596+
// in some nested item in the module, we'll be re-executed due to reads
597+
// in the expect_* calls the loops below
598+
self.read(hir_id);
599+
600+
let module = &self.forest.krate.modules[&hir_id];
601+
602+
parallel!(
603+
{
604+
par_for_each(&module.items, |id| {
605+
visitor.visit_item(self.expect_item(*id));
606+
});
607+
},
608+
{
609+
par_for_each(&module.trait_items, |id| {
610+
visitor.visit_trait_item(self.expect_trait_item(id.hir_id));
611+
});
612+
},
613+
{
614+
par_for_each(&module.impl_items, |id| {
615+
visitor.visit_impl_item(self.expect_impl_item(id.hir_id));
616+
});
617+
}
618+
);
619+
}
620+
585621
/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
586622
pub fn get(&self, id: HirId) -> Node<'hir> {
587623
// read recorded by `find`

src/librustc_hir/intravisit.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ pub trait IntoVisitor<'hir> {
7070
fn into_visitor(&self) -> Self::Visitor;
7171
}
7272

73+
impl<'hir, T: Clone + Visitor<'hir>> IntoVisitor<'hir> for T {
74+
type Visitor = Self;
75+
fn into_visitor(&self) -> Self::Visitor {
76+
self.clone()
77+
}
78+
}
79+
7380
pub struct ParDeepVisitor<V>(pub V);
7481

7582
impl<'hir, V> ParItemLikeVisitor<'hir> for ParDeepVisitor<V>

src/librustc_typeck/check/mod.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ use rustc_hir as hir;
123123
use rustc_hir::def::{CtorOf, DefKind, Res};
124124
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LOCAL_CRATE};
125125
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
126-
use rustc_hir::itemlikevisit::ItemLikeVisitor;
126+
use rustc_hir::itemlikevisit::ParItemLikeVisitor;
127127
use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath};
128128
use rustc_index::vec::Idx;
129129
use rustc_span::hygiene::DesugaringKind;
@@ -729,12 +729,12 @@ struct CheckItemTypesVisitor<'tcx> {
729729
tcx: TyCtxt<'tcx>,
730730
}
731731

732-
impl ItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
733-
fn visit_item(&mut self, i: &'tcx hir::Item<'tcx>) {
732+
impl ParItemLikeVisitor<'tcx> for CheckItemTypesVisitor<'tcx> {
733+
fn visit_item(&self, i: &'tcx hir::Item<'tcx>) {
734734
check_item_type(self.tcx, i);
735735
}
736-
fn visit_trait_item(&mut self, _: &'tcx hir::TraitItem<'tcx>) {}
737-
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem<'tcx>) {}
736+
fn visit_trait_item(&self, _: &'tcx hir::TraitItem<'tcx>) {}
737+
fn visit_impl_item(&self, _: &'tcx hir::ImplItem<'tcx>) {}
738738
}
739739

740740
pub fn check_wf_new(tcx: TyCtxt<'_>) {
@@ -743,7 +743,7 @@ pub fn check_wf_new(tcx: TyCtxt<'_>) {
743743
}
744744

745745
fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
746-
tcx.hir().visit_item_likes_in_module(module_def_id, &mut CheckItemTypesVisitor { tcx });
746+
tcx.hir().par_visit_item_likes_in_module(module_def_id, &CheckItemTypesVisitor { tcx });
747747
}
748748

749749
fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {

src/librustc_typeck/collect.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use rustc_errors::{struct_span_err, Applicability, StashKey};
4040
use rustc_hir as hir;
4141
use rustc_hir::def::{CtorKind, DefKind, Res};
4242
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
43-
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
43+
use rustc_hir::intravisit::{self, NestedVisitorMap, ParDeepVisitor, Visitor};
4444
use rustc_hir::{GenericParamKind, Node, Unsafety};
4545
use rustc_span::symbol::{kw, sym, Symbol};
4646
use rustc_span::{Span, DUMMY_SP};
@@ -54,9 +54,9 @@ struct OnlySelfBounds(bool);
5454
// Main entry point
5555

5656
fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
57-
tcx.hir().visit_item_likes_in_module(
57+
tcx.hir().par_visit_item_likes_in_module(
5858
module_def_id,
59-
&mut CollectItemTypesVisitor { tcx }.as_deep_visitor(),
59+
&ParDeepVisitor(CollectItemTypesVisitor { tcx }),
6060
);
6161
}
6262

@@ -117,6 +117,7 @@ impl<'v> Visitor<'v> for PlaceholderHirTyCollector {
117117
}
118118
}
119119

120+
#[derive(Clone)]
120121
struct CollectItemTypesVisitor<'tcx> {
121122
tcx: TyCtxt<'tcx>,
122123
}

src/librustc_typeck/lib.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ use rustc::ty::subst::SubstsRef;
102102
use rustc::ty::{self, Ty, TyCtxt};
103103
use rustc::util;
104104
use rustc::util::common::ErrorReported;
105+
use rustc_data_structures::sync::par_for_each;
105106
use rustc_errors::struct_span_err;
106107
use rustc_hir as hir;
107108
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
@@ -308,9 +309,13 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> {
308309
// FIXME(matthewjasper) We shouldn't need to do this.
309310
tcx.sess.track_errors(|| {
310311
tcx.sess.time("type_collecting", || {
311-
for &module in tcx.hir().krate().modules.keys() {
312+
// Run dependencies of type collecting before entering the loop
313+
tcx.inferred_outlives_crate(LOCAL_CRATE);
314+
315+
let _prof_timer = tcx.sess.timer("type_collecting_loop");
316+
par_for_each(&tcx.hir().krate().modules, |(&module, _)| {
312317
tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module));
313-
}
318+
});
314319
});
315320
})?;
316321

@@ -339,9 +344,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> {
339344
})?;
340345

341346
tcx.sess.time("item_types_checking", || {
342-
for &module in tcx.hir().krate().modules.keys() {
347+
par_for_each(&tcx.hir().krate().modules, |(&module, _)| {
343348
tcx.ensure().check_mod_item_types(tcx.hir().local_def_id(module));
344-
}
349+
});
345350
});
346351

347352
tcx.sess.time("item_bodies_checking", || tcx.typeck_item_bodies(LOCAL_CRATE));

src/test/ui/span/issue-35987.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@ struct Foo<T: Clone>(T);
33
use std::ops::Add;
44

55
impl<T: Clone, Add> Add for Foo<T> {
6-
//~^ ERROR expected trait, found type parameter
6+
//~^ ERROR expected trait, found type parameter
77
type Output = usize;
88

99
fn add(self, rhs: Self) -> Self::Output {
10+
//~^ ERROR ambiguous associated type
1011
unimplemented!();
1112
}
1213
}

src/test/ui/span/issue-35987.stderr

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ help: possible better candidate is found in another module, you can import it in
99
LL | use std::ops::Add;
1010
|
1111

12-
error: aborting due to previous error
12+
error[E0223]: ambiguous associated type
13+
--> $DIR/issue-35987.rs:9:32
14+
|
15+
LL | fn add(self, rhs: Self) -> Self::Output {
16+
| ^^^^^^^^^^^^ help: use fully-qualified syntax: `<Foo<T> as Trait>::Output`
17+
18+
error: aborting due to 2 previous errors
1319

14-
For more information about this error, try `rustc --explain E0404`.
20+
Some errors have detailed explanations: E0223, E0404.
21+
For more information about an error, try `rustc --explain E0223`.

0 commit comments

Comments
 (0)