From 6241cf9a598b19cbd6c8c41c3743f8d56adafd2b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 20 Nov 2019 21:55:33 +0300 Subject: [PATCH] Add HasResolver trait --- crates/ra_hir/src/code_model.rs | 106 +------------- crates/ra_hir/src/expr.rs | 1 + crates/ra_hir/src/generics.rs | 18 +-- crates/ra_hir/src/impl_block.rs | 10 +- crates/ra_hir/src/resolve.rs | 131 +++++++++++++++++- crates/ra_hir/src/source_binder.rs | 2 +- crates/ra_hir/src/ty/infer.rs | 2 +- crates/ra_hir/src/ty/lower.rs | 2 +- .../src/completion/complete_scope.rs | 7 + 9 files changed, 145 insertions(+), 134 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9b6276b51bc..c5539e0764a 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -30,7 +30,7 @@ AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, TypeAliasId, }, - resolve::{Resolver, Scope, TypeNs}, + resolve::{HasResolver, TypeNs}, ty::{InferenceResult, Namespace, TraitRef}, Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, }; @@ -223,11 +223,6 @@ pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { } } - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - let def_map = db.crate_def_map(self.id.krate); - Resolver::default().push_module_scope(def_map, self.id.module_id) - } - pub fn declarations(self, db: &impl DefDatabase) -> Vec { let def_map = db.crate_def_map(self.id.krate); def_map[self.id.module_id].scope.declarations().map(ModuleDef::from).collect() @@ -315,15 +310,6 @@ pub fn constructor_ty(self, db: &impl HirDatabase) -> Ty { db.type_for_def(self.into(), Namespace::Values) } - // FIXME move to a more general type - /// Builds a resolver for type references inside this struct. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - r.push_generic_params_scope(db, self.into()) - } - fn variant_data(self, db: &impl DefDatabase) -> Arc { db.struct_data(self.id.into()).variant_data.clone() } @@ -339,22 +325,13 @@ pub fn name(self, db: &impl DefDatabase) -> Option { db.struct_data(self.id.into()).name.clone() } - pub fn module(self, db: &impl HirDatabase) -> Module { + pub fn module(self, db: &impl DefDatabase) -> Module { Module { id: self.id.0.module(db) } } pub fn ty(self, db: &impl HirDatabase) -> Ty { db.type_for_def(self.into(), Namespace::Types) } - - // FIXME move to a more general type - /// Builds a resolver for type references inside this union. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - r.push_generic_params_scope(db, self.into()) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -394,16 +371,6 @@ pub fn variant(self, db: &impl DefDatabase, name: &Name) -> Option pub fn ty(self, db: &impl HirDatabase) -> Ty { db.type_for_def(self.into(), Namespace::Types) } - - // FIXME: move to a more general type - /// Builds a resolver for type references inside this struct. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.module(db).resolver(db); - // ...and add generic params, if present - let r = r.push_generic_params_scope(db, self.into()); - r.push_scope(Scope::AdtScope(self.into())) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -475,14 +442,6 @@ pub fn krate(self, db: &impl HirDatabase) -> Option { .krate(), ) } - - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - match self { - Adt::Struct(it) => it.resolver(db), - Adt::Union(it) => it.resolver(db), - Adt::Enum(it) => it.resolver(db), - } - } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -533,15 +492,6 @@ pub enum DefWithBody { impl_froms!(DefWithBody: Function, Const, Static); impl DefWithBody { - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - match self { - DefWithBody::Const(c) => c.resolver(db), - DefWithBody::Function(f) => f.resolver(db), - DefWithBody::Static(s) => s.resolver(db), - } - } - pub(crate) fn krate(self, db: &impl HirDatabase) -> Option { match self { DefWithBody::Const(c) => c.krate(db), @@ -738,15 +688,6 @@ pub fn container(self, db: &impl DefDatabase) -> Option { } } - // FIXME: move to a more general type for 'body-having' items - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); - // ...and add generic params, if present - r.push_generic_params_scope(db, self.into()) - } - pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { let infer = self.infer(db); infer.add_diagnostics(db, self, sink); @@ -804,17 +745,6 @@ pub fn container(self, db: &impl DefDatabase) -> Option { ContainerId::ModuleId(_) => None, } } - - // FIXME: move to a more general type for 'body-having' items - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self - .impl_block(db) - .map(|ib| ib.resolver(db)) - .unwrap_or_else(|| self.module(db).resolver(db)); - r - } } #[derive(Debug, Clone, PartialEq, Eq)] @@ -874,12 +804,6 @@ pub fn data(self, db: &impl HirDatabase) -> Arc { db.static_data(self) } - /// Builds a resolver for code inside this item. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - self.module(db).resolver(db) - } - pub fn infer(self, db: &impl HirDatabase) -> Arc { db.infer(self.into()) } @@ -975,12 +899,6 @@ pub fn trait_ref(self, db: &impl HirDatabase) -> TraitRef { pub fn is_auto(self, db: &impl DefDatabase) -> bool { self.trait_data(db).auto } - - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - let r = self.module(db).resolver(db); - // add generic params, if present - r.push_generic_params_scope(db, self.into()) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -1032,17 +950,6 @@ pub fn ty(self, db: &impl HirDatabase) -> Ty { pub fn name(self, db: &impl DefDatabase) -> Name { db.type_alias_data(self).name.clone() } - - /// Builds a resolver for the type references in this type alias. - pub(crate) fn resolver(self, db: &impl HirDatabase) -> Resolver { - // take the outer scope... - let r = self - .impl_block(db) - .map(|ib| ib.resolver(db)) - .unwrap_or_else(|| self.module(db).resolver(db)); - // ...and add generic params, if present - r.push_generic_params_scope(db, self.into()) - } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -1058,15 +965,6 @@ pub enum Container { } impl_froms!(Container: Trait, ImplBlock); -impl Container { - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - match self { - Container::Trait(trait_) => trait_.resolver(db), - Container::ImplBlock(impl_block) => impl_block.resolver(db), - } - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub enum AssocItem { Function(Function), diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 8bfdda45e12..869879bdfa4 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -11,6 +11,7 @@ use crate::{ db::HirDatabase, diagnostics::{MissingFields, MissingOkInTailExpr}, + resolve::HasResolver, ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, Adt, DefWithBody, Function, HasBody, Name, Path, Resolver, }; diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 54ed03642a0..f1bf2ee9d19 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs @@ -2,8 +2,8 @@ use std::sync::Arc; use crate::{ - db::{DefDatabase, HirDatabase}, - Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, TypeAlias, Union, + db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, + TypeAlias, Union, }; pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate}; @@ -31,20 +31,6 @@ pub enum GenericDef { Const ); -impl GenericDef { - pub(crate) fn resolver(&self, db: &impl HirDatabase) -> crate::Resolver { - match self { - GenericDef::Function(inner) => inner.resolver(db), - GenericDef::Adt(adt) => adt.resolver(db), - GenericDef::Trait(inner) => inner.resolver(db), - GenericDef::TypeAlias(inner) => inner.resolver(db), - GenericDef::ImplBlock(inner) => inner.resolver(db), - GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), - GenericDef::Const(inner) => inner.resolver(db), - } - } -} - impl From for GenericDef { fn from(c: Container) -> Self { match c { diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 492d964a43c..964a3da8c08 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -5,7 +5,7 @@ use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, - resolve::Resolver, + resolve::HasResolver, ty::Ty, AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, }; @@ -50,12 +50,4 @@ pub fn module(&self, db: &impl DefDatabase) -> Module { pub fn krate(&self, db: &impl DefDatabase) -> Crate { Crate { crate_id: self.module(db).id.krate } } - - pub(crate) fn resolver(self, db: &impl DefDatabase) -> Resolver { - let r = self.module(db).resolver(db); - // add generic params, if present - let r = r.push_generic_params_scope(db, self.into()); - let r = r.push_impl_block_scope(self); - r - } } diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index e5e768be90e..b8e1b4dad73 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -15,8 +15,8 @@ db::{DefDatabase, HirDatabase}, expr::{ExprScopes, PatId, ScopeId}, generics::{GenericParams, HasGenericParams}, - Adt, Const, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, MacroDef, - ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, + Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, + MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, Union, }; #[derive(Debug, Clone, Default)] @@ -486,3 +486,130 @@ fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef) } } } + +pub(crate) trait HasResolver { + /// Builds a resolver for type references inside this def. + fn resolver(self, db: &impl DefDatabase) -> Resolver; +} + +impl HasResolver for Module { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + let def_map = db.crate_def_map(self.id.krate); + Resolver::default().push_module_scope(def_map, self.id.module_id) + } +} + +impl HasResolver for Trait { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db).resolver(db).push_generic_params_scope(db, self.into()) + } +} + +impl HasResolver for Struct { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_scope(Scope::AdtScope(self.into())) + } +} + +impl HasResolver for Union { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_scope(Scope::AdtScope(self.into())) + } +} + +impl HasResolver for Enum { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_scope(Scope::AdtScope(self.into())) + } +} + +impl HasResolver for Adt { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + Adt::Struct(it) => it.resolver(db), + Adt::Union(it) => it.resolver(db), + Adt::Enum(it) => it.resolver(db), + } + } +} + +impl HasResolver for Function { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.container(db) + .map(|c| c.resolver(db)) + .unwrap_or_else(|| self.module(db).resolver(db)) + .push_generic_params_scope(db, self.into()) + } +} + +impl HasResolver for DefWithBody { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + DefWithBody::Const(c) => c.resolver(db), + DefWithBody::Function(f) => f.resolver(db), + DefWithBody::Static(s) => s.resolver(db), + } + } +} + +impl HasResolver for Const { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.container(db).map(|c| c.resolver(db)).unwrap_or_else(|| self.module(db).resolver(db)) + } +} + +impl HasResolver for Static { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db).resolver(db) + } +} + +impl HasResolver for TypeAlias { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.container(db) + .map(|ib| ib.resolver(db)) + .unwrap_or_else(|| self.module(db).resolver(db)) + .push_generic_params_scope(db, self.into()) + } +} + +impl HasResolver for Container { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + Container::Trait(trait_) => trait_.resolver(db), + Container::ImplBlock(impl_block) => impl_block.resolver(db), + } + } +} + +impl HasResolver for GenericDef { + fn resolver(self, db: &impl DefDatabase) -> crate::Resolver { + match self { + GenericDef::Function(inner) => inner.resolver(db), + GenericDef::Adt(adt) => adt.resolver(db), + GenericDef::Trait(inner) => inner.resolver(db), + GenericDef::TypeAlias(inner) => inner.resolver(db), + GenericDef::ImplBlock(inner) => inner.resolver(db), + GenericDef::EnumVariant(inner) => inner.parent_enum(db).resolver(db), + GenericDef::Const(inner) => inner.resolver(db), + } + } +} + +impl HasResolver for ImplBlock { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_impl_block_scope(self) + } +} diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index fd9994098b9..727310f0662 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -23,7 +23,7 @@ db::HirDatabase, expr::{self, BodySourceMap, ExprScopes, ScopeId}, ids::LocationCtx, - resolve::{ScopeDef, TypeNs, ValueNs}, + resolve::{HasResolver, ScopeDef, TypeNs, ValueNs}, ty::method_resolution::{self, implements_trait}, AssocItem, Const, DefWithBody, Either, Enum, FromSource, Function, GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, Struct, Ty, diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 092bc3a3f2b..7f9e81d6492 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -40,7 +40,7 @@ code_model::TypeAlias, db::HirDatabase, expr::{BindingAnnotation, Body, ExprId, PatId}, - resolve::{Resolver, TypeNs}, + resolve::{HasResolver, Resolver, TypeNs}, ty::infer::diagnostics::InferenceDiagnostic, Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, StructField, VariantDef, diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 91e60b5ab4c..397ee7d5fc3 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -22,7 +22,7 @@ db::HirDatabase, generics::HasGenericParams, generics::{GenericDef, WherePredicate}, - resolve::{Resolver, TypeNs}, + resolve::{HasResolver, Resolver, TypeNs}, ty::{ primitive::{FloatTy, IntTy, Uncertain}, Adt, diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 8c57c907d9b..d5739b58a6d 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs @@ -304,6 +304,13 @@ struct X { ), @r###" [ + CompletionItem { + label: "Self", + source_range: [54; 54), + delete: [54; 54), + insert: "Self", + kind: TypeParam, + }, CompletionItem { label: "T", source_range: [54; 54),