From 828d60574f8ecbc33fe4987913c6f713e41af1ae Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 14 Sep 2019 16:26:03 +0200 Subject: Refactor a bit to prepare for resolving trait assoc items --- crates/ra_hir/src/code_model.rs | 31 ++++++++++++ crates/ra_hir/src/lib.rs | 6 +-- crates/ra_hir/src/resolve.rs | 8 +-- crates/ra_hir/src/source_binder.rs | 2 +- crates/ra_hir/src/ty/infer.rs | 57 ++++++++++------------ crates/ra_ide_api/src/display/navigation_target.rs | 15 +++--- crates/ra_ide_api/src/goto_definition.rs | 2 +- crates/ra_ide_api/src/hover.rs | 6 +-- crates/ra_ide_api/src/name_ref_kind.rs | 2 +- crates/ra_ide_api/src/syntax_highlighting.rs | 6 +-- 10 files changed, 83 insertions(+), 52 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 84e15385c..892208c1a 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -749,6 +749,10 @@ impl Const { db.const_data(self) } + pub fn name(&self, db: &impl HirDatabase) -> Option { + self.data(db).name().cloned() + } + pub fn infer(self, db: &impl HirDatabase) -> Arc { db.infer(self.into()) } @@ -1019,3 +1023,30 @@ impl Container { } } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum AssocItem { + Function(Function), + Const(Const), + TypeAlias(TypeAlias), +} + +impl From for AssocItem { + fn from(t: TraitItem) -> Self { + match t { + TraitItem::Function(f) => AssocItem::Function(f), + TraitItem::Const(c) => AssocItem::Const(c), + TraitItem::TypeAlias(t) => AssocItem::TypeAlias(t), + } + } +} + +impl From for AssocItem { + fn from(i: crate::ImplItem) -> Self { + match i { + crate::ImplItem::Method(f) => AssocItem::Function(f), + crate::ImplItem::Const(c) => AssocItem::Const(c), + crate::ImplItem::TypeAlias(t) => AssocItem::TypeAlias(t), + } + } +} diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 80cf8d9c0..db82a463c 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -85,7 +85,7 @@ pub use self::{ pub use self::code_model::{ docs::{DocDef, Docs, Documentation}, src::{HasBodySource, HasSource, Source}, - Adt, BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, - EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef, ModuleSource, - Static, Struct, StructField, Trait, TypeAlias, Union, + Adt, AssocItem, BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, + Enum, EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef, + ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union, }; diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index bb6915901..7f4c78859 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -50,7 +50,7 @@ pub(crate) enum Scope { ExprScope(ExprScope), } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TypeNs { SelfType(ImplBlock), GenericParam(u32), @@ -59,19 +59,19 @@ pub enum TypeNs { TypeAlias(TypeAlias), BuiltinType(BuiltinType), Trait(Trait), - // Module belong to type ns, but the resovler is used when all module paths + // Module belong to type ns, but the resolver is used when all module paths // are fully resolved. // Module(Module) } -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ResolveValueResult<'a> { ValueNs(ValueNs), Partial(TypeNs, usize), TypeRef(&'a TypeRef), } -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ValueNs { LocalBinding(PatId), Function(Function), diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 2a907c9f1..4d895f0a1 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -190,7 +190,7 @@ pub enum PathResolution { GenericParam(u32), SelfType(crate::ImplBlock), Macro(MacroDef), - AssocItem(crate::ImplItem), + AssocItem(crate::AssocItem), } #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index bf9609d8c..6aaf61c0e 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -48,7 +48,7 @@ use crate::{ resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs}, ty::infer::diagnostics::InferenceDiagnostic, type_ref::{Mutability, TypeRef}, - Adt, ConstData, DefWithBody, Either, FnData, Function, HasBody, ImplItem, Name, Path, + Adt, AssocItem, ConstData, DefWithBody, Either, FnData, Function, HasBody, ImplItem, Name, Path, StructField, }; @@ -121,7 +121,7 @@ pub struct InferenceResult { /// For each struct literal, records the variant it resolves to. variant_resolutions: FxHashMap, /// For each associated item record what it resolves to - assoc_resolutions: FxHashMap, + assoc_resolutions: FxHashMap, diagnostics: Vec, pub(super) type_of_expr: ArenaMap, pub(super) type_of_pat: ArenaMap, @@ -141,10 +141,10 @@ impl InferenceResult { pub fn variant_resolution_for_pat(&self, id: PatId) -> Option { self.variant_resolutions.get(&id.into()).copied() } - pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option { + pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option { self.assoc_resolutions.get(&id.into()).copied() } - pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option { + pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option { self.assoc_resolutions.get(&id.into()).copied() } pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { @@ -235,7 +235,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { self.result.variant_resolutions.insert(id, variant); } - fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: ImplItem) { + fn write_assoc_resolution(&mut self, id: ExprOrPatId, item: AssocItem) { self.result.assoc_resolutions.insert(id, item); } @@ -560,8 +560,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { let ty = mem::replace(&mut ty, Ty::Unknown); def_or_ty = ty.iterate_impl_items(self.db, krate, |item| { match item { - crate::ImplItem::Method(_) => None, - crate::ImplItem::Const(_) => None, + crate::ImplItem::Method(_) | crate::ImplItem::Const(_) => None, // FIXME: Resolve associated types crate::ImplItem::TypeAlias(_) => { @@ -573,34 +572,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { } let segment = path.segments.last().unwrap(); - let def = ty.clone().iterate_impl_items(self.db, krate, |item| { - let matching_def: Option = match item { - crate::ImplItem::Method(func) => { - if segment.name == func.name(self.db) { - Some(ValueNs::Function(func)) - } else { - None - } + let def = ty.clone().iterate_impl_items(self.db, krate, |item| match item { + crate::ImplItem::Method(func) => { + if segment.name == func.name(self.db) { + Some(ValueNs::Function(func)) + } else { + None } + } - crate::ImplItem::Const(konst) => { - let data = konst.data(self.db); - if Some(&segment.name) == data.name() { - Some(ValueNs::Const(konst)) - } else { - None - } - } - crate::ImplItem::TypeAlias(_) => None, - }; - match matching_def { - Some(_) => { - self.write_assoc_resolution(id, item); - matching_def + crate::ImplItem::Const(konst) => { + if konst.name(self.db).map_or(false, |n| n == segment.name) { + Some(ValueNs::Const(konst)) + } else { + None } - None => None, } + crate::ImplItem::TypeAlias(_) => None, })?; + self.write_assoc_resolution( + id, + match def { + ValueNs::Function(f) => AssocItem::Function(f), + ValueNs::Const(c) => AssocItem::Const(c), + _ => unreachable!(), + }, + ); let self_types = self.find_self_types(&def, ty); Some((def, self_types)) } diff --git a/crates/ra_ide_api/src/display/navigation_target.rs b/crates/ra_ide_api/src/display/navigation_target.rs index 03382ab3c..11f73ccfd 100644 --- a/crates/ra_ide_api/src/display/navigation_target.rs +++ b/crates/ra_ide_api/src/display/navigation_target.rs @@ -1,4 +1,4 @@ -use hir::{FieldSource, HasSource, ImplItem, ModuleSource}; +use hir::{AssocItem, FieldSource, HasSource, ModuleSource}; use ra_db::{FileId, SourceDatabase}; use ra_syntax::{ algo::visit::{visitor, Visitor}, @@ -221,11 +221,14 @@ impl NavigationTarget { ) } - pub(crate) fn from_impl_item(db: &RootDatabase, impl_item: hir::ImplItem) -> NavigationTarget { - match impl_item { - ImplItem::Method(it) => NavigationTarget::from_def_source(db, it), - ImplItem::Const(it) => NavigationTarget::from_def_source(db, it), - ImplItem::TypeAlias(it) => NavigationTarget::from_def_source(db, it), + pub(crate) fn from_assoc_item( + db: &RootDatabase, + assoc_item: hir::AssocItem, + ) -> NavigationTarget { + match assoc_item { + AssocItem::Function(it) => NavigationTarget::from_def_source(db, it), + AssocItem::Const(it) => NavigationTarget::from_def_source(db, it), + AssocItem::TypeAlias(it) => NavigationTarget::from_def_source(db, it), } } diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 28529a2de..503dcacff 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs @@ -60,7 +60,7 @@ pub(crate) fn reference_definition( match classify_name_ref(db, &analyzer, name_ref) { Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)), Some(FieldAccess(field)) => return Exact(NavigationTarget::from_field(db, field)), - Some(AssocItem(assoc)) => return Exact(NavigationTarget::from_impl_item(db, assoc)), + Some(AssocItem(assoc)) => return Exact(NavigationTarget::from_assoc_item(db, assoc)), Some(Method(func)) => return Exact(NavigationTarget::from_def_source(db, func)), Some(Def(def)) => match NavigationTarget::from_def(db, def) { Some(nav) => return Exact(nav), diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 28a6bef12..655bcdb16 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs @@ -117,9 +117,9 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option res.extend(match it { - hir::ImplItem::Method(it) => from_def_source(db, it), - hir::ImplItem::Const(it) => from_def_source(db, it), - hir::ImplItem::TypeAlias(it) => from_def_source(db, it), + hir::AssocItem::Function(it) => from_def_source(db, it), + hir::AssocItem::Const(it) => from_def_source(db, it), + hir::AssocItem::TypeAlias(it) => from_def_source(db, it), }), Some(Def(it)) => { match it { diff --git a/crates/ra_ide_api/src/name_ref_kind.rs b/crates/ra_ide_api/src/name_ref_kind.rs index 6c2a7b260..aff03464a 100644 --- a/crates/ra_ide_api/src/name_ref_kind.rs +++ b/crates/ra_ide_api/src/name_ref_kind.rs @@ -8,7 +8,7 @@ pub enum NameRefKind { Method(hir::Function), Macro(hir::MacroDef), FieldAccess(hir::StructField), - AssocItem(hir::ImplItem), + AssocItem(hir::AssocItem), Def(hir::ModuleDef), SelfType(hir::Ty), Pat(AstPtr), diff --git a/crates/ra_ide_api/src/syntax_highlighting.rs b/crates/ra_ide_api/src/syntax_highlighting.rs index 86ab3a260..3d7f91c1d 100644 --- a/crates/ra_ide_api/src/syntax_highlighting.rs +++ b/crates/ra_ide_api/src/syntax_highlighting.rs @@ -102,9 +102,9 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec "function", Some(Macro(_)) => "macro", Some(FieldAccess(_)) => "field", - Some(AssocItem(hir::ImplItem::Method(_))) => "function", - Some(AssocItem(hir::ImplItem::Const(_))) => "constant", - Some(AssocItem(hir::ImplItem::TypeAlias(_))) => "type", + Some(AssocItem(hir::AssocItem::Function(_))) => "function", + Some(AssocItem(hir::AssocItem::Const(_))) => "constant", + Some(AssocItem(hir::AssocItem::TypeAlias(_))) => "type", Some(Def(hir::ModuleDef::Module(_))) => "module", Some(Def(hir::ModuleDef::Function(_))) => "function", Some(Def(hir::ModuleDef::Adt(_))) => "type", -- cgit v1.2.3