Refactor a bit to prepare for resolving trait assoc items

This commit is contained in:
Florian Diebold 2019-09-14 16:26:03 +02:00
parent 913ab1ec0a
commit 828d60574f
10 changed files with 85 additions and 54 deletions

View file

@ -749,6 +749,10 @@ impl Const {
db.const_data(self) db.const_data(self)
} }
pub fn name(&self, db: &impl HirDatabase) -> Option<Name> {
self.data(db).name().cloned()
}
pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> { pub fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult> {
db.infer(self.into()) 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<TraitItem> 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<crate::ImplItem> 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),
}
}
}

View file

@ -85,7 +85,7 @@ pub use self::{
pub use self::code_model::{ pub use self::code_model::{
docs::{DocDef, Docs, Documentation}, docs::{DocDef, Docs, Documentation},
src::{HasBodySource, HasSource, Source}, src::{HasBodySource, HasSource, Source},
Adt, BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, Adt, AssocItem, BuiltinType, Const, ConstData, Container, Crate, CrateDependency, DefWithBody,
EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef, ModuleSource, Enum, EnumVariant, FieldSource, FnData, Function, HasBody, MacroDef, Module, ModuleDef,
Static, Struct, StructField, Trait, TypeAlias, Union, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, Union,
}; };

View file

@ -50,7 +50,7 @@ pub(crate) enum Scope {
ExprScope(ExprScope), ExprScope(ExprScope),
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum TypeNs { pub enum TypeNs {
SelfType(ImplBlock), SelfType(ImplBlock),
GenericParam(u32), GenericParam(u32),
@ -59,19 +59,19 @@ pub enum TypeNs {
TypeAlias(TypeAlias), TypeAlias(TypeAlias),
BuiltinType(BuiltinType), BuiltinType(BuiltinType),
Trait(Trait), 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. // are fully resolved.
// Module(Module) // Module(Module)
} }
#[derive(Debug)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ResolveValueResult<'a> { pub enum ResolveValueResult<'a> {
ValueNs(ValueNs), ValueNs(ValueNs),
Partial(TypeNs, usize), Partial(TypeNs, usize),
TypeRef(&'a TypeRef), TypeRef(&'a TypeRef),
} }
#[derive(Debug)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ValueNs { pub enum ValueNs {
LocalBinding(PatId), LocalBinding(PatId),
Function(Function), Function(Function),

View file

@ -190,7 +190,7 @@ pub enum PathResolution {
GenericParam(u32), GenericParam(u32),
SelfType(crate::ImplBlock), SelfType(crate::ImplBlock),
Macro(MacroDef), Macro(MacroDef),
AssocItem(crate::ImplItem), AssocItem(crate::AssocItem),
} }
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]

View file

@ -48,7 +48,7 @@ use crate::{
resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs}, resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs},
ty::infer::diagnostics::InferenceDiagnostic, ty::infer::diagnostics::InferenceDiagnostic,
type_ref::{Mutability, TypeRef}, 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, StructField,
}; };
@ -121,7 +121,7 @@ pub struct InferenceResult {
/// For each struct literal, records the variant it resolves to. /// For each struct literal, records the variant it resolves to.
variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>, variant_resolutions: FxHashMap<ExprOrPatId, VariantDef>,
/// For each associated item record what it resolves to /// For each associated item record what it resolves to
assoc_resolutions: FxHashMap<ExprOrPatId, ImplItem>, assoc_resolutions: FxHashMap<ExprOrPatId, AssocItem>,
diagnostics: Vec<InferenceDiagnostic>, diagnostics: Vec<InferenceDiagnostic>,
pub(super) type_of_expr: ArenaMap<ExprId, Ty>, pub(super) type_of_expr: ArenaMap<ExprId, Ty>,
pub(super) type_of_pat: ArenaMap<PatId, Ty>, pub(super) type_of_pat: ArenaMap<PatId, Ty>,
@ -141,10 +141,10 @@ impl InferenceResult {
pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantDef> { pub fn variant_resolution_for_pat(&self, id: PatId) -> Option<VariantDef> {
self.variant_resolutions.get(&id.into()).copied() self.variant_resolutions.get(&id.into()).copied()
} }
pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<ImplItem> { pub fn assoc_resolutions_for_expr(&self, id: ExprId) -> Option<AssocItem> {
self.assoc_resolutions.get(&id.into()).copied() self.assoc_resolutions.get(&id.into()).copied()
} }
pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<ImplItem> { pub fn assoc_resolutions_for_pat(&self, id: PatId) -> Option<AssocItem> {
self.assoc_resolutions.get(&id.into()).copied() self.assoc_resolutions.get(&id.into()).copied()
} }
pub fn type_mismatch_for_expr(&self, expr: ExprId) -> Option<&TypeMismatch> { 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); 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); 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); let ty = mem::replace(&mut ty, Ty::Unknown);
def_or_ty = ty.iterate_impl_items(self.db, krate, |item| { def_or_ty = ty.iterate_impl_items(self.db, krate, |item| {
match item { match item {
crate::ImplItem::Method(_) => None, crate::ImplItem::Method(_) | crate::ImplItem::Const(_) => None,
crate::ImplItem::Const(_) => None,
// FIXME: Resolve associated types // FIXME: Resolve associated types
crate::ImplItem::TypeAlias(_) => { crate::ImplItem::TypeAlias(_) => {
@ -573,34 +572,32 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
} }
let segment = path.segments.last().unwrap(); let segment = path.segments.last().unwrap();
let def = ty.clone().iterate_impl_items(self.db, krate, |item| { let def = ty.clone().iterate_impl_items(self.db, krate, |item| match item {
let matching_def: Option<ValueNs> = match item { crate::ImplItem::Method(func) => {
crate::ImplItem::Method(func) => { if segment.name == func.name(self.db) {
if segment.name == func.name(self.db) { Some(ValueNs::Function(func))
Some(ValueNs::Function(func)) } else {
} else { None
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
}
None => None,
} }
crate::ImplItem::Const(konst) => {
if konst.name(self.db).map_or(false, |n| n == segment.name) {
Some(ValueNs::Const(konst))
} else {
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); let self_types = self.find_self_types(&def, ty);
Some((def, self_types)) Some((def, self_types))
} }

View file

@ -1,4 +1,4 @@
use hir::{FieldSource, HasSource, ImplItem, ModuleSource}; use hir::{AssocItem, FieldSource, HasSource, ModuleSource};
use ra_db::{FileId, SourceDatabase}; use ra_db::{FileId, SourceDatabase};
use ra_syntax::{ use ra_syntax::{
algo::visit::{visitor, Visitor}, algo::visit::{visitor, Visitor},
@ -221,11 +221,14 @@ impl NavigationTarget {
) )
} }
pub(crate) fn from_impl_item(db: &RootDatabase, impl_item: hir::ImplItem) -> NavigationTarget { pub(crate) fn from_assoc_item(
match impl_item { db: &RootDatabase,
ImplItem::Method(it) => NavigationTarget::from_def_source(db, it), assoc_item: hir::AssocItem,
ImplItem::Const(it) => NavigationTarget::from_def_source(db, it), ) -> NavigationTarget {
ImplItem::TypeAlias(it) => NavigationTarget::from_def_source(db, it), 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),
} }
} }

View file

@ -60,7 +60,7 @@ pub(crate) fn reference_definition(
match classify_name_ref(db, &analyzer, name_ref) { match classify_name_ref(db, &analyzer, name_ref) {
Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)), Some(Macro(mac)) => return Exact(NavigationTarget::from_macro_def(db, mac)),
Some(FieldAccess(field)) => return Exact(NavigationTarget::from_field(db, field)), 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(Method(func)) => return Exact(NavigationTarget::from_def_source(db, func)),
Some(Def(def)) => match NavigationTarget::from_def(db, def) { Some(Def(def)) => match NavigationTarget::from_def(db, def) {
Some(nav) => return Exact(nav), Some(nav) => return Exact(nav),

View file

@ -117,9 +117,9 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
} }
} }
Some(AssocItem(it)) => res.extend(match it { Some(AssocItem(it)) => res.extend(match it {
hir::ImplItem::Method(it) => from_def_source(db, it), hir::AssocItem::Function(it) => from_def_source(db, it),
hir::ImplItem::Const(it) => from_def_source(db, it), hir::AssocItem::Const(it) => from_def_source(db, it),
hir::ImplItem::TypeAlias(it) => from_def_source(db, it), hir::AssocItem::TypeAlias(it) => from_def_source(db, it),
}), }),
Some(Def(it)) => { Some(Def(it)) => {
match it { match it {

View file

@ -8,7 +8,7 @@ pub enum NameRefKind {
Method(hir::Function), Method(hir::Function),
Macro(hir::MacroDef), Macro(hir::MacroDef),
FieldAccess(hir::StructField), FieldAccess(hir::StructField),
AssocItem(hir::ImplItem), AssocItem(hir::AssocItem),
Def(hir::ModuleDef), Def(hir::ModuleDef),
SelfType(hir::Ty), SelfType(hir::Ty),
Pat(AstPtr<ast::BindPat>), Pat(AstPtr<ast::BindPat>),

View file

@ -102,9 +102,9 @@ pub(crate) fn highlight(db: &RootDatabase, file_id: FileId) -> Vec<HighlightedRa
Some(Method(_)) => "function", Some(Method(_)) => "function",
Some(Macro(_)) => "macro", Some(Macro(_)) => "macro",
Some(FieldAccess(_)) => "field", Some(FieldAccess(_)) => "field",
Some(AssocItem(hir::ImplItem::Method(_))) => "function", Some(AssocItem(hir::AssocItem::Function(_))) => "function",
Some(AssocItem(hir::ImplItem::Const(_))) => "constant", Some(AssocItem(hir::AssocItem::Const(_))) => "constant",
Some(AssocItem(hir::ImplItem::TypeAlias(_))) => "type", Some(AssocItem(hir::AssocItem::TypeAlias(_))) => "type",
Some(Def(hir::ModuleDef::Module(_))) => "module", Some(Def(hir::ModuleDef::Module(_))) => "module",
Some(Def(hir::ModuleDef::Function(_))) => "function", Some(Def(hir::ModuleDef::Function(_))) => "function",
Some(Def(hir::ModuleDef::Adt(_))) => "type", Some(Def(hir::ModuleDef::Adt(_))) => "type",