Skip to content

Commit 4a030e8

Browse files
committed
import path fixes only
1 parent 42d87a0 commit 4a030e8

File tree

2 files changed

+57
-13
lines changed

2 files changed

+57
-13
lines changed

codegen/src/import_path.rs

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use indexmap::IndexMap;
1+
use crate_feature_graph::WorkspaceGraph;
2+
use indexmap::{IndexMap, IndexSet};
23
use log::trace;
34
use rustc_hir::{
45
def::DefKind,
5-
def_id::{CrateNum, DefId},
6+
def_id::{CrateNum, DefId, LOCAL_CRATE},
67
};
78
use rustc_middle::ty::TyCtxt;
89

@@ -42,6 +43,7 @@ impl std::fmt::Debug for ImportPathElement {
4243
pub(crate) struct ImportPathFinder<'tcx> {
4344
pub(crate) tcx: TyCtxt<'tcx>,
4445
pub(crate) cache: IndexMap<DefId, Vec<Vec<ImportPathElement>>>,
46+
pub(crate) crawled_crates: IndexSet<CrateNum>,
4547
pub(crate) include_private_paths: bool,
4648
pub(crate) import_path_processor: Option<Box<dyn Fn(&str) -> String>>,
4749
}
@@ -58,18 +60,59 @@ impl<'tcx> ImportPathFinder<'tcx> {
5860
cache: Default::default(),
5961
include_private_paths,
6062
import_path_processor,
63+
crawled_crates: Default::default(),
6164
}
6265
}
6366

64-
pub(crate) fn crawl_crate(&mut self, crate_num: CrateNum) {
65-
self.crawl_module(
66-
crate_num.as_def_id(),
67-
&[ImportPathElement::Crate(crate_num)],
68-
);
69-
// sort by length of path, shortest wins
70-
self.cache.iter_mut().for_each(|(_, paths)| {
71-
paths.sort_by_key(|a| a.len());
72-
});
67+
/// Sort the import paths according to some heuristics, so best ones are first
68+
pub(crate) fn stable_sort(&mut self, graph: &WorkspaceGraph) {
69+
for (_, values) in &mut self.cache {
70+
values.sort_by_cached_key(|k| Self::path_score(k, graph, self.tcx));
71+
}
72+
}
73+
74+
pub(crate) fn crawled_items_in_crate(&self, krate: CrateNum) -> impl Iterator<Item = DefId> {
75+
self.cache
76+
.keys()
77+
.filter_map(move |i| (i.krate == krate).then_some(*i))
78+
}
79+
80+
/// Higher is worse
81+
fn path_score(path: &[ImportPathElement], graph: &WorkspaceGraph, tcx: TyCtxt) -> usize {
82+
let length_score = path.len();
83+
// crate proximity score
84+
let mut crate_proximity_score = 0;
85+
if let Some(ImportPathElement::Crate(crate_num)) = path.first() {
86+
let crate_name = tcx.crate_name(*crate_num);
87+
let is_std_or_core = crate_name.as_str() == "std" || crate_name.as_str() == "core";
88+
let not_in_workspace = !graph
89+
.all_enabled_workspace_crates()
90+
.iter()
91+
.any(|c| c.as_ref() == crate_name.as_str());
92+
93+
let is_not_local_crate = if &LOCAL_CRATE != crate_num && !is_std_or_core {
94+
10
95+
} else {
96+
0
97+
};
98+
let is_not_in_workspace = if not_in_workspace && !is_std_or_core {
99+
10
100+
} else {
101+
0
102+
};
103+
crate_proximity_score = is_not_local_crate + is_not_in_workspace;
104+
}
105+
length_score + crate_proximity_score
106+
}
107+
108+
pub(crate) fn ensure_crate_crawled(&mut self, crate_num: CrateNum) {
109+
if !self.crawled_crates.contains(&crate_num) {
110+
self.crawl_module(
111+
crate_num.as_def_id(),
112+
&[ImportPathElement::Crate(crate_num)],
113+
);
114+
self.crawled_crates.insert(crate_num);
115+
}
73116
}
74117

75118
fn crawl_module(&mut self, did: DefId, frontier: &[ImportPathElement]) {

codegen/src/passes/crawl_paths.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ use crate::{Args, BevyCtxt};
44

55
/// Finds and caches import paths
66
pub(crate) fn crawl_paths(ctxt: &mut BevyCtxt<'_>, _args: &Args) -> bool {
7-
ctxt.path_finder.crawl_crate(LOCAL_CRATE);
7+
ctxt.path_finder.ensure_crate_crawled(LOCAL_CRATE);
88

99
for c in ctxt.tcx.crates(()) {
10-
ctxt.path_finder.crawl_crate(*c);
10+
ctxt.path_finder.ensure_crate_crawled(*c);
1111
}
12+
ctxt.path_finder.stable_sort(&ctxt.workspace);
1213
true
1314
}

0 commit comments

Comments
 (0)