Skip to content

Commit cf661d0

Browse files
committed
Add optimalization on resolve import
1 parent 610b321 commit cf661d0

File tree

2 files changed

+59
-18
lines changed

2 files changed

+59
-18
lines changed

crates/ra_hir_def/src/nameres/collector.rs

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,18 @@ impl MacroStackMonitor {
9595
}
9696
}
9797

98+
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
99+
enum PartialResolvedImport {
100+
Unresolved,
101+
Resolved(PerNs),
102+
}
103+
98104
/// Walks the tree of module recursively
99105
struct DefCollector<'a, DB> {
100106
db: &'a DB,
101107
def_map: CrateDefMap,
102108
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>,
103-
unresolved_imports: Vec<(LocalModuleId, LocalImportId, raw::ImportData, ReachedFixedPoint)>,
109+
unresolved_imports: Vec<(LocalModuleId, LocalImportId, raw::ImportData, PartialResolvedImport)>,
104110
unexpanded_macros: Vec<(LocalModuleId, AstId<ast::MacroCall>, Path)>,
105111
mod_dirs: FxHashMap<LocalModuleId, ModDir>,
106112

@@ -158,8 +164,8 @@ where
158164
let unresolved_imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
159165
// show unresolved imports in completion, etc
160166
for (module_id, import, import_data, status) in unresolved_imports {
161-
if status == ReachedFixedPoint::No {
162-
self.record_resolved_import(module_id, PerNs::none(), import, &import_data)
167+
if status == PartialResolvedImport::Unresolved {
168+
self.record_resolved_import(module_id, PerNs::none(), import, &import_data, status)
163169
}
164170
}
165171
}
@@ -267,13 +273,20 @@ where
267273
let mut previous_resolved = 0;
268274

269275
imports.retain(|(module_id, import, import_data, status)| {
270-
if *status == ReachedFixedPoint::Yes {
276+
if let PartialResolvedImport::Resolved(_) = status {
271277
previous_resolved += 1;
272278
}
273279

274-
let (def, fp) = self.resolve_import(*module_id, import_data);
280+
let (def, fp, krate) = self.resolve_import(*module_id, import_data);
275281
if fp == ReachedFixedPoint::Yes {
276-
resolved.push((*module_id, def, *import, import_data.clone()))
282+
resolved.push((
283+
*module_id,
284+
def,
285+
*import,
286+
import_data.clone(),
287+
krate,
288+
status.clone(),
289+
))
277290
}
278291
fp == ReachedFixedPoint::No
279292
});
@@ -284,24 +297,39 @@ where
284297
} else {
285298
ReachedFixedPoint::No
286299
};
287-
for (module_id, def, import, import_data) in resolved {
288-
self.record_resolved_import(module_id, def, import, &import_data);
300+
for (module_id, def, import, import_data, krate, status) in resolved {
301+
self.record_resolved_import(module_id, def, import, &import_data, status);
302+
303+
// external crate graphs can't change in other crates.
304+
if import_data.is_extern_crate {
305+
continue;
306+
}
307+
if let Some(krate) = krate {
308+
if krate != self.def_map.krate {
309+
continue;
310+
}
311+
}
289312

290313
// Reput resolved into unresolved_imports
291314
// This is because other unresolved imports and macros will bring in another PerNSs,
292315
// so we can only assume that it has been partially resolved.
293316
// We must try to solve it again in the next round.
294-
self.unresolved_imports.push((module_id, import, import_data, ReachedFixedPoint::Yes));
317+
self.unresolved_imports.push((
318+
module_id,
319+
import,
320+
import_data,
321+
PartialResolvedImport::Resolved(def),
322+
));
295323
}
296324

297-
result
325+
return result;
298326
}
299327

300328
fn resolve_import(
301329
&self,
302330
module_id: LocalModuleId,
303331
import: &raw::ImportData,
304-
) -> (PerNs, ReachedFixedPoint) {
332+
) -> (PerNs, ReachedFixedPoint, Option<CrateId>) {
305333
log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition);
306334
if import.is_extern_crate {
307335
let res = self.def_map.resolve_name_in_extern_prelude(
@@ -310,7 +338,7 @@ where
310338
.as_ident()
311339
.expect("extern crate should have been desugared to one-element path"),
312340
);
313-
(res, ReachedFixedPoint::Yes)
341+
(res, ReachedFixedPoint::Yes, None)
314342
} else {
315343
let res = self.def_map.resolve_path_fp_with_macro(
316344
self.db,
@@ -320,7 +348,7 @@ where
320348
BuiltinShadowMode::Module,
321349
);
322350

323-
(res.resolved_def, res.reached_fixedpoint)
351+
(res.resolved_def, res.reached_fixedpoint, res.krate)
324352
}
325353
}
326354

@@ -330,7 +358,15 @@ where
330358
def: PerNs,
331359
import_id: LocalImportId,
332360
import: &raw::ImportData,
361+
status: PartialResolvedImport,
333362
) {
363+
// record import if it was changed
364+
if let PartialResolvedImport::Resolved(ns) = status {
365+
if ns == def {
366+
return;
367+
}
368+
}
369+
334370
if import.is_glob {
335371
log::debug!("glob import: {:?}", import);
336372
match def.take_types() {
@@ -606,7 +642,7 @@ where
606642
self.module_id,
607643
import_id,
608644
self.raw_items[import_id].clone(),
609-
ReachedFixedPoint::No,
645+
PartialResolvedImport::Unresolved,
610646
))
611647
}
612648
raw::RawItemKind::Def(def) => self.define_def(&self.raw_items[def]),

crates/ra_hir_def/src/nameres/path_resolution.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::{
1919
nameres::{BuiltinShadowMode, CrateDefMap},
2020
path::{Path, PathKind},
2121
per_ns::PerNs,
22-
AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
22+
AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
2323
};
2424

2525
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -39,19 +39,21 @@ pub(super) struct ResolvePathResult {
3939
pub(super) resolved_def: PerNs,
4040
pub(super) segment_index: Option<usize>,
4141
pub(super) reached_fixedpoint: ReachedFixedPoint,
42+
pub(super) krate: Option<CrateId>,
4243
}
4344

4445
impl ResolvePathResult {
4546
fn empty(reached_fixedpoint: ReachedFixedPoint) -> ResolvePathResult {
46-
ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None)
47+
ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None, None)
4748
}
4849

4950
fn with(
5051
resolved_def: PerNs,
5152
reached_fixedpoint: ReachedFixedPoint,
5253
segment_index: Option<usize>,
54+
krate: Option<CrateId>,
5355
) -> ResolvePathResult {
54-
ResolvePathResult { resolved_def, reached_fixedpoint, segment_index }
56+
ResolvePathResult { resolved_def, reached_fixedpoint, segment_index, krate }
5557
}
5658
}
5759

@@ -175,6 +177,7 @@ impl CrateDefMap {
175177
def,
176178
ReachedFixedPoint::Yes,
177179
s.map(|s| s + i),
180+
Some(module.krate),
178181
);
179182
}
180183

@@ -201,6 +204,7 @@ impl CrateDefMap {
201204
PerNs::types(e.into()),
202205
ReachedFixedPoint::Yes,
203206
Some(i),
207+
Some(self.krate),
204208
);
205209
}
206210
}
@@ -218,12 +222,13 @@ impl CrateDefMap {
218222
PerNs::types(s),
219223
ReachedFixedPoint::Yes,
220224
Some(i),
225+
Some(self.krate),
221226
);
222227
}
223228
};
224229
}
225230

226-
ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None)
231+
ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None, Some(self.krate))
227232
}
228233

229234
fn resolve_name_in_module(

0 commit comments

Comments
 (0)