Skip to content

Commit

Permalink
Use dynamic dispatch for name resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
matklad committed Nov 12, 2019
1 parent aa0646b commit e4dabdb
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 33 deletions.
9 changes: 9 additions & 0 deletions crates/ra_hir_def/src/nameres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ impl CrateDefMap {
db: &impl DefDatabase2,
original_module: CrateModuleId,
path: &Path,
) -> (PerNs, Option<usize>) {
self._resolve_path(db, original_module, path)
}

fn _resolve_path(
&self,
db: &dyn DefDatabase2,
original_module: CrateModuleId,
path: &Path,
) -> (PerNs, Option<usize>) {
let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path);
(res.resolved_def, res.segment_index)
Expand Down
78 changes: 54 additions & 24 deletions crates/ra_hir_def/src/nameres/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ use crate::{
per_ns::PerNs, raw, CrateDefMap, ModuleData, Resolution, ResolveMode,
},
path::{Path, PathKind},
AdtId, AstId, AstItemDef, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId,
LocationCtx, ModuleDefId, ModuleId, StaticId, StructId, StructOrUnionId, TraitId, TypeAliasId,
UnionId,
AdtId, AstId, ConstId, CrateModuleId, EnumId, EnumVariantId, FunctionId, ItemLoc, ModuleDefId,
ModuleId, StaticId, StructId, StructOrUnionId, TraitId, TypeAliasId, UnionId,
};

pub(super) fn collect_defs(db: &impl DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap {
pub(super) fn collect_defs(db: &dyn DefDatabase2, mut def_map: CrateDefMap) -> CrateDefMap {
let crate_graph = db.crate_graph();

// populate external prelude
Expand Down Expand Up @@ -91,8 +90,8 @@ impl MacroStackMonitor {
}

/// Walks the tree of module recursively
struct DefCollector<'a, DB> {
db: &'a DB,
struct DefCollector<'a> {
db: &'a dyn DefDatabase2,
def_map: CrateDefMap,
glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>,
Expand All @@ -106,10 +105,7 @@ struct DefCollector<'a, DB> {
cfg_options: &'a CfgOptions,
}

impl<DB> DefCollector<'_, DB>
where
DB: DefDatabase2,
{
impl DefCollector<'_> {
fn collect(&mut self) {
let crate_graph = self.db.crate_graph();
let file_id = crate_graph.crate_root(self.def_map.krate);
Expand Down Expand Up @@ -528,10 +524,7 @@ struct ModCollector<'a, D> {
mod_dir: ModDir,
}

impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>>
where
DB: DefDatabase2,
{
impl ModCollector<'_, &'_ mut DefCollector<'_>> {
fn collect(&mut self, items: &[raw::RawItem]) {
// Note: don't assert that inserted value is fresh: it's simply not true
// for macros.
Expand Down Expand Up @@ -659,31 +652,68 @@ where
fn define_def(&mut self, def: &raw::DefData) {
let module =
ModuleId { krate: self.def_collector.def_map.krate, module_id: self.module_id };
let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id);

let name = def.name.clone();
let def: PerNs = match def.kind {
raw::DefKind::Function(ast_id) => {
PerNs::values(FunctionId::from_ast_id(ctx, ast_id).into())
let id: FunctionId = self
.def_collector
.db
.intern_function(ItemLoc { module, ast_id: AstId::new(self.file_id, ast_id) });
PerNs::values(id.into())
}
raw::DefKind::Struct(ast_id) => {
let id = StructOrUnionId::from_ast_id(ctx, ast_id).into();
let id: StructOrUnionId = self.def_collector.db.intern_struct_or_union(ItemLoc {
module,
ast_id: AstId::new(self.file_id, ast_id),
});
let s = StructId(id).into();
PerNs::both(s, s)
}
raw::DefKind::Union(ast_id) => {
let id = StructOrUnionId::from_ast_id(ctx, ast_id).into();
let id: StructOrUnionId = self.def_collector.db.intern_struct_or_union(ItemLoc {
module,
ast_id: AstId::new(self.file_id, ast_id),
});
let u = UnionId(id).into();
PerNs::both(u, u)
}
raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()),
raw::DefKind::Const(ast_id) => PerNs::values(ConstId::from_ast_id(ctx, ast_id).into()),
raw::DefKind::Enum(ast_id) => {
let id: EnumId = self
.def_collector
.db
.intern_enum(ItemLoc { module, ast_id: AstId::new(self.file_id, ast_id) });
PerNs::types(id.into())
}
raw::DefKind::Const(ast_id) => {
let id: ConstId = self
.def_collector
.db
.intern_const(ItemLoc { module, ast_id: AstId::new(self.file_id, ast_id) });
PerNs::values(id.into())
}
raw::DefKind::Static(ast_id) => {
PerNs::values(StaticId::from_ast_id(ctx, ast_id).into())
let id: StaticId = self
.def_collector
.db
.intern_static(ItemLoc { module, ast_id: AstId::new(self.file_id, ast_id) });

PerNs::values(id.into())
}
raw::DefKind::Trait(ast_id) => {
let id: TraitId = self
.def_collector
.db
.intern_trait(ItemLoc { module, ast_id: AstId::new(self.file_id, ast_id) });

PerNs::types(id.into())
}
raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()),
raw::DefKind::TypeAlias(ast_id) => {
PerNs::types(TypeAliasId::from_ast_id(ctx, ast_id).into())
let id: TypeAliasId = self.def_collector.db.intern_type_alias(ItemLoc {
module,
ast_id: AstId::new(self.file_id, ast_id),
});

PerNs::types(id.into())
}
};
let resolution = Resolution { def, import: None };
Expand Down
16 changes: 14 additions & 2 deletions crates/ra_hir_def/src/nameres/mod_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,24 @@ impl ModDir {

pub(super) fn resolve_declaration(
&self,
db: &impl DefDatabase2,
db: &dyn DefDatabase2,
file_id: HirFileId,
name: &Name,
attr_path: Option<&SmolStr>,
) -> Result<(FileId, ModDir), RelativePathBuf> {
let file_id = file_id.original_file(db);
// Urgs. HirFileId::original_file wants `dyn AstDatabase`, we have `dyn
// DefDatabase2`, and Rust can't upcast trait-objects yet :(
fn original_file(file_id: HirFileId, db: &dyn DefDatabase2) -> FileId {
match file_id.0 {
hir_expand::HirFileIdRepr::FileId(file_id) => file_id,
hir_expand::HirFileIdRepr::MacroFile(macro_file) => {
let loc = db.lookup_intern_macro(macro_file.macro_call_id);
original_file(loc.ast_id.file_id(), db)
}
}
}

let file_id = original_file(file_id, db);

let mut candidate_files = Vec::new();
match attr_to_path(attr_path) {
Expand Down
8 changes: 4 additions & 4 deletions crates/ra_hir_def/src/nameres/path_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl CrateDefMap {
// the result.
pub(super) fn resolve_path_fp_with_macro(
&self,
db: &impl DefDatabase2,
db: &dyn DefDatabase2,
mode: ResolveMode,
original_module: CrateModuleId,
path: &Path,
Expand Down Expand Up @@ -159,7 +159,7 @@ impl CrateDefMap {
Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ };
log::debug!("resolving {:?} in other crate", path);
let defp_map = db.crate_def_map(module.krate);
let (def, s) = defp_map.resolve_path(db, module.module_id, &path);
let (def, s) = defp_map._resolve_path(db, module.module_id, &path);
return ResolvePathResult::with(
def,
ReachedFixedPoint::Yes,
Expand Down Expand Up @@ -216,7 +216,7 @@ impl CrateDefMap {

fn resolve_name_in_module(
&self,
db: &impl DefDatabase2,
db: &dyn DefDatabase2,
module: CrateModuleId,
name: &Name,
) -> PerNs {
Expand All @@ -243,7 +243,7 @@ impl CrateDefMap {
from_crate_root.or(from_extern_prelude)
}

fn resolve_in_prelude(&self, db: &impl DefDatabase2, name: &Name) -> PerNs {
fn resolve_in_prelude(&self, db: &dyn DefDatabase2, name: &Name) -> PerNs {
if let Some(prelude) = self.prelude {
let keep;
let def_map = if prelude.krate == self.krate {
Expand Down
6 changes: 3 additions & 3 deletions crates/ra_hir_expand/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ use crate::builtin_macro::BuiltinExpander;
/// finite (because everything bottoms out at the real `FileId`) and small
/// (`MacroCallId` uses the location interner).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct HirFileId(HirFileIdRepr);
pub struct HirFileId(pub HirFileIdRepr);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
enum HirFileIdRepr {
pub enum HirFileIdRepr {
FileId(FileId),
MacroFile(MacroFile),
}
Expand Down Expand Up @@ -98,7 +98,7 @@ impl HirFileId {

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MacroFile {
macro_call_id: MacroCallId,
pub macro_call_id: MacroCallId,
macro_file_kind: MacroFileKind,
}

Expand Down

0 comments on commit e4dabdb

Please sign in to comment.