mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 14:51:48 +00:00
Refactor a bit to prepare for resolving trait assoc items
This commit is contained in:
parent
913ab1ec0a
commit
828d60574f
10 changed files with 85 additions and 54 deletions
|
@ -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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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)]
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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>),
|
||||||
|
|
|
@ -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",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue