Skip to content

Commit

Permalink
Add optimalization on resolve import
Browse files Browse the repository at this point in the history
  • Loading branch information
edwin0cheng committed Dec 3, 2019
1 parent c934cf1 commit c23353d
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 18 deletions.
64 changes: 50 additions & 14 deletions crates/ra_hir_def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,18 @@ impl MacroStackMonitor {
}
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum PartialResolvedImport {
Unresolved,
Resolved(PerNs),
}

/// Walks the tree of module recursively
struct DefCollector<'a, DB> {
db: &'a DB,
def_map: CrateDefMap,
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, LocalImportId)>>,
unresolved_imports: Vec<(LocalModuleId, LocalImportId, raw::ImportData, ReachedFixedPoint)>,
unresolved_imports: Vec<(LocalModuleId, LocalImportId, raw::ImportData, PartialResolvedImport)>,
unexpanded_macros: Vec<(LocalModuleId, AstId<ast::MacroCall>, Path)>,
mod_dirs: FxHashMap<LocalModuleId, ModDir>,

Expand Down Expand Up @@ -158,8 +164,8 @@ where
let unresolved_imports = std::mem::replace(&mut self.unresolved_imports, Vec::new());
// show unresolved imports in completion, etc
for (module_id, import, import_data, status) in unresolved_imports {
if status == ReachedFixedPoint::No {
self.record_resolved_import(module_id, PerNs::none(), import, &import_data)
if status == PartialResolvedImport::Unresolved {
self.record_resolved_import(module_id, PerNs::none(), import, &import_data, status)
}
}
}
Expand Down Expand Up @@ -267,13 +273,20 @@ where
let mut previous_resolved = 0;

imports.retain(|(module_id, import, import_data, status)| {
if *status == ReachedFixedPoint::Yes {
if let PartialResolvedImport::Resolved(_) = status {
previous_resolved += 1;
}

let (def, fp) = self.resolve_import(*module_id, import_data);
let (def, fp, krate) = self.resolve_import(*module_id, import_data);
if fp == ReachedFixedPoint::Yes {
resolved.push((*module_id, def, *import, import_data.clone()))
resolved.push((
*module_id,
def,
*import,
import_data.clone(),
krate,
status.clone(),
))
}
fp == ReachedFixedPoint::No
});
Expand All @@ -284,24 +297,39 @@ where
} else {
ReachedFixedPoint::No
};
for (module_id, def, import, import_data) in resolved {
self.record_resolved_import(module_id, def, import, &import_data);
for (module_id, def, import, import_data, krate, status) in resolved {
self.record_resolved_import(module_id, def, import, &import_data, status);

// external crate graphs can't change in other crates.
if import_data.is_extern_crate {
continue;
}
if let Some(krate) = krate {
if krate != self.def_map.krate {
continue;
}
}

// Reput resolved into unresolved_imports
// This is because other unresolved imports and macros will bring in another PerNSs,
// so we can only assume that it has been partially resolved.
// We must try to solve it again in the next round.
self.unresolved_imports.push((module_id, import, import_data, ReachedFixedPoint::Yes));
self.unresolved_imports.push((
module_id,
import,
import_data,
PartialResolvedImport::Resolved(def),
));
}

result
return result;
}

fn resolve_import(
&self,
module_id: LocalModuleId,
import: &raw::ImportData,
) -> (PerNs, ReachedFixedPoint) {
) -> (PerNs, ReachedFixedPoint, Option<CrateId>) {
log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition);
if import.is_extern_crate {
let res = self.def_map.resolve_name_in_extern_prelude(
Expand All @@ -310,7 +338,7 @@ where
.as_ident()
.expect("extern crate should have been desugared to one-element path"),
);
(res, ReachedFixedPoint::Yes)
(res, ReachedFixedPoint::Yes, None)
} else {
let res = self.def_map.resolve_path_fp_with_macro(
self.db,
Expand All @@ -320,7 +348,7 @@ where
BuiltinShadowMode::Module,
);

(res.resolved_def, res.reached_fixedpoint)
(res.resolved_def, res.reached_fixedpoint, res.krate)
}
}

Expand All @@ -330,7 +358,15 @@ where
def: PerNs,
import_id: LocalImportId,
import: &raw::ImportData,
status: PartialResolvedImport,
) {
// record import if it was changed
if let PartialResolvedImport::Resolved(ns) = status {
if ns == def {
return;
}
}

if import.is_glob {
log::debug!("glob import: {:?}", import);
match def.take_types() {
Expand Down Expand Up @@ -606,7 +642,7 @@ where
self.module_id,
import_id,
self.raw_items[import_id].clone(),
ReachedFixedPoint::No,
PartialResolvedImport::Unresolved,
))
}
raw::RawItemKind::Def(def) => self.define_def(&self.raw_items[def]),
Expand Down
13 changes: 9 additions & 4 deletions crates/ra_hir_def/src/nameres/path_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
nameres::{BuiltinShadowMode, CrateDefMap},
path::{Path, PathKind},
per_ns::PerNs,
AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
};

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

impl ResolvePathResult {
fn empty(reached_fixedpoint: ReachedFixedPoint) -> ResolvePathResult {
ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None)
ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None, None)
}

fn with(
resolved_def: PerNs,
reached_fixedpoint: ReachedFixedPoint,
segment_index: Option<usize>,
krate: Option<CrateId>,
) -> ResolvePathResult {
ResolvePathResult { resolved_def, reached_fixedpoint, segment_index }
ResolvePathResult { resolved_def, reached_fixedpoint, segment_index, krate }
}
}

Expand Down Expand Up @@ -175,6 +177,7 @@ impl CrateDefMap {
def,
ReachedFixedPoint::Yes,
s.map(|s| s + i),
Some(module.krate),
);
}

Expand All @@ -201,6 +204,7 @@ impl CrateDefMap {
PerNs::types(e.into()),
ReachedFixedPoint::Yes,
Some(i),
Some(self.krate),
);
}
}
Expand All @@ -218,12 +222,13 @@ impl CrateDefMap {
PerNs::types(s),
ReachedFixedPoint::Yes,
Some(i),
Some(self.krate),
);
}
};
}

ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None)
ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None, Some(self.krate))
}

fn resolve_name_in_module(
Expand Down

0 comments on commit c23353d

Please sign in to comment.