Skip to content

Commit c621cd6

Browse files
committed
Parallelize type collecting and item-types checking
1 parent 934abf2 commit c621cd6

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
@@ -121,7 +121,7 @@ use rustc_hir as hir;
121121
use rustc_hir::def::{CtorOf, DefKind, Res};
122122
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LOCAL_CRATE};
123123
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
124-
use rustc_hir::itemlikevisit::ItemLikeVisitor;
124+
use rustc_hir::itemlikevisit::ParItemLikeVisitor;
125125
use rustc_hir::{ExprKind, GenericArg, HirIdMap, ItemKind, Node, PatKind, QPath};
126126
use rustc_index::vec::Idx;
127127
use rustc_span::hygiene::DesugaringKind;
@@ -730,12 +730,12 @@ struct CheckItemTypesVisitor<'tcx> {
730730
tcx: TyCtxt<'tcx>,
731731
}
732732

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

741741
pub fn check_wf_new(tcx: TyCtxt<'_>) {
@@ -744,7 +744,7 @@ pub fn check_wf_new(tcx: TyCtxt<'_>) {
744744
}
745745

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

750750
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
@@ -38,7 +38,7 @@ use rustc_errors::{struct_span_err, Applicability, StashKey};
3838
use rustc_hir as hir;
3939
use rustc_hir::def::{CtorKind, DefKind, Res};
4040
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
41-
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
41+
use rustc_hir::intravisit::{self, NestedVisitorMap, ParDeepVisitor, Visitor};
4242
use rustc_hir::{GenericParamKind, Node, Unsafety};
4343
use rustc_span::symbol::{kw, sym, Symbol};
4444
use rustc_span::{Span, DUMMY_SP};
@@ -55,9 +55,9 @@ struct OnlySelfBounds(bool);
5555
// Main entry point
5656

5757
fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
58-
tcx.hir().visit_item_likes_in_module(
58+
tcx.hir().par_visit_item_likes_in_module(
5959
module_def_id,
60-
&mut CollectItemTypesVisitor { tcx }.as_deep_visitor(),
60+
&ParDeepVisitor(CollectItemTypesVisitor { tcx }),
6161
);
6262
}
6363

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

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

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};
@@ -310,9 +311,13 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> {
310311
// FIXME(matthewjasper) We shouldn't need to do this.
311312
tcx.sess.track_errors(|| {
312313
tcx.sess.time("type_collecting", || {
313-
for &module in tcx.hir().krate().modules.keys() {
314+
// Run dependencies of type collecting before entering the loop
315+
tcx.inferred_outlives_crate(LOCAL_CRATE);
316+
317+
let _prof_timer = tcx.sess.timer("type_collecting_loop");
318+
par_for_each(&tcx.hir().krate().modules, |(&module, _)| {
314319
tcx.ensure().collect_mod_item_types(tcx.hir().local_def_id(module));
315-
}
320+
});
316321
});
317322
})?;
318323

@@ -341,9 +346,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorReported> {
341346
})?;
342347

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

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