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 ++++++++++++++++++-------------------- 5 files changed, 66 insertions(+), 38 deletions(-) (limited to 'crates/ra_hir/src') 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)) } -- cgit v1.2.3