From 0102fb41337ac0442e689d410bb424d215e9a7bd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 12:21:46 +0300 Subject: [PATCH 01/21] Decouple Resolver --- crates/ra_hir/src/code_model.rs | 18 ++-- crates/ra_hir/src/expr.rs | 4 +- crates/ra_hir/src/from_id.rs | 65 +++++++++++- crates/ra_hir/src/resolve.rs | 117 +++++++++++----------- crates/ra_hir/src/source_binder.rs | 21 ++-- crates/ra_hir/src/ty/infer.rs | 23 +++-- crates/ra_hir/src/ty/infer/path.rs | 4 +- crates/ra_hir/src/ty/lower.rs | 31 +++--- crates/ra_hir/src/ty/method_resolution.rs | 4 +- crates/ra_hir_def/src/traits.rs | 9 +- 10 files changed, 188 insertions(+), 108 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index a132d128b57..550ab1a985c 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -12,8 +12,8 @@ builtin_type::BuiltinType, traits::TraitData, type_ref::{Mutability, TypeRef}, - AssocItemId, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, - LocalStructFieldId, Lookup, ModuleId, UnionId, + ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, + ModuleId, UnionId, }; use hir_expand::{ diagnostics::DiagnosticSink, @@ -842,9 +842,10 @@ fn direct_super_traits(self, db: &impl HirDatabase) -> Vec { _ => None, }) .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path) { - Some(TypeNs::Trait(t)) => Some(t), + Some(TypeNs::TraitId(t)) => Some(t), _ => None, }) + .map(Trait::from) .collect() } @@ -871,14 +872,9 @@ pub fn all_super_traits(self, db: &impl HirDatabase) -> Vec { pub fn associated_type_by_name(self, db: &impl DefDatabase, name: &Name) -> Option { let trait_data = self.trait_data(db); - trait_data - .items - .iter() - .filter_map(|item| match item { - AssocItemId::TypeAliasId(t) => Some(TypeAlias::from(*t)), - _ => None, - }) - .find(|t| &t.name(db) == name) + let res = + trait_data.associated_types().map(TypeAlias::from).find(|t| &t.name(db) == name)?; + Some(res) } pub fn associated_type_by_name_including_super_traits( diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 869879bdfa4..8c4c63fda34 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -46,7 +46,7 @@ pub(crate) fn resolver_for_scope( let scopes = owner.expr_scopes(db); let scope_chain = scopes.scope_chain(scope_id).collect::>(); for scope in scope_chain.into_iter().rev() { - r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); + r = r.push_expr_scope(owner.into(), Arc::clone(&scopes), scope); } r } @@ -152,7 +152,7 @@ fn validate_results_in_tail_expr( _ => return, }; - let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum)); + let std_result_ctor = TypeCtor::Adt(Adt::Enum(std_result_enum.into())); let params = match &mismatch.expected { Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &std_result_ctor => parameters, _ => return, diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index b7692d40733..7042422ccf8 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -3,9 +3,14 @@ //! It's unclear if we need this long-term, but it's definitelly useful while we //! are splitting the hir. -use hir_def::{AdtId, AssocItemId, DefWithBodyId, EnumVariantId, GenericDefId, ModuleDefId}; +use hir_def::{ + AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, GenericDefId, ModuleDefId, StructId, + TypeAliasId, UnionId, +}; -use crate::{Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef}; +use crate::{ + ty::TypableDef, Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef, TypeAlias, +}; macro_rules! from_id { ($(($id:path, $ty:path)),*) => {$( @@ -83,6 +88,16 @@ fn from(def: DefWithBody) -> Self { } } +impl From for DefWithBody { + fn from(def: DefWithBodyId) -> Self { + match def { + DefWithBodyId::FunctionId(it) => DefWithBody::Function(it.into()), + DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()), + DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()), + } + } +} + impl From for AssocItem { fn from(def: AssocItemId) -> Self { match def { @@ -122,3 +137,49 @@ fn from(def: GenericDefId) -> Self { } } } + +impl From for TypableDef { + fn from(id: AdtId) -> Self { + Adt::from(id).into() + } +} + +impl From for TypableDef { + fn from(id: StructId) -> Self { + AdtId::StructId(id).into() + } +} + +impl From for TypableDef { + fn from(id: UnionId) -> Self { + AdtId::UnionId(id).into() + } +} + +impl From for TypableDef { + fn from(id: EnumId) -> Self { + AdtId::EnumId(id).into() + } +} + +impl From for TypableDef { + fn from(id: EnumVariantId) -> Self { + EnumVariant::from(id).into() + } +} + +impl From for TypableDef { + fn from(id: TypeAliasId) -> Self { + TypeAlias::from(id).into() + } +} + +impl From for GenericDefId { + fn from(id: Adt) -> Self { + match id { + Adt::Struct(it) => it.id.into(), + Adt::Union(it) => it.id.into(), + Adt::Enum(it) => it.id.into(), + } + } +} diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index eca8e05969b..f4165babd37 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -3,19 +3,21 @@ use hir_def::{ builtin_type::BuiltinType, + db::DefDatabase2, + generics::GenericParams, nameres::CrateDefMap, path::{Path, PathKind}, - AdtId, CrateModuleId, ModuleDefId, + AdtId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, GenericDefId, ImplId, ModuleDefId, + StructId, TraitId, TypeAliasId, }; use hir_expand::name::{self, Name}; use rustc_hash::FxHashSet; use crate::{ code_model::Crate, - db::{DefDatabase, HirDatabase}, + db::DefDatabase, expr::{ExprScopes, PatId, ScopeId}, - generics::{GenericParams, HasGenericParams}, - Adt, Const, Container, DefWithBody, Enum, EnumVariant, Function, GenericDef, ImplBlock, Local, + Adt, Const, Container, DefWithBody, EnumVariant, Function, GenericDef, ImplBlock, Local, MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, }; @@ -33,7 +35,7 @@ pub(crate) struct ModuleItemMap { #[derive(Debug, Clone)] pub(crate) struct ExprScope { - owner: DefWithBody, + owner: DefWithBodyId, expr_scopes: Arc, scope_id: ScopeId, } @@ -43,28 +45,28 @@ pub(crate) enum Scope { /// All the items and imported names of a module ModuleScope(ModuleItemMap), /// Brings the generic parameters of an item into scope - GenericParams { def: GenericDef, params: Arc }, + GenericParams { def: GenericDefId, params: Arc }, /// Brings `Self` in `impl` block into scope - ImplBlockScope(ImplBlock), + ImplBlockScope(ImplId), /// Brings `Self` in enum, struct and union definitions into scope - AdtScope(Adt), + AdtScope(AdtId), /// Local bindings ExprScope(ExprScope), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub(crate) enum TypeNs { - SelfType(ImplBlock), + SelfType(ImplId), GenericParam(u32), - Adt(Adt), - AdtSelfType(Adt), - EnumVariant(EnumVariant), - TypeAlias(TypeAlias), + AdtId(AdtId), + AdtSelfType(AdtId), + EnumVariantId(EnumVariantId), + TypeAliasId(TypeAliasId), BuiltinType(BuiltinType), - Trait(Trait), + TraitId(TraitId), // Module belong to type ns, but the resolver is used when all module paths // are fully resolved. - // Module(Module) + // ModuleId(ModuleId) } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -85,10 +87,14 @@ pub(crate) enum ValueNs { impl Resolver { /// Resolve known trait from std, like `std::futures::Future` - pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> Option { + pub(crate) fn resolve_known_trait( + &self, + db: &impl DefDatabase2, + path: &Path, + ) -> Option { let res = self.resolve_module_path(db, path).take_types()?; match res { - ModuleDefId::TraitId(it) => Some(it.into()), + ModuleDefId::TraitId(it) => Some(it), _ => None, } } @@ -96,27 +102,27 @@ pub(crate) fn resolve_known_trait(&self, db: &impl HirDatabase, path: &Path) -> /// Resolve known struct from std, like `std::boxed::Box` pub(crate) fn resolve_known_struct( &self, - db: &impl HirDatabase, + db: &impl DefDatabase2, path: &Path, - ) -> Option { + ) -> Option { let res = self.resolve_module_path(db, path).take_types()?; match res { - ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it.into()), + ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), _ => None, } } /// Resolve known enum from std, like `std::result::Result` - pub(crate) fn resolve_known_enum(&self, db: &impl HirDatabase, path: &Path) -> Option { + pub(crate) fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option { let res = self.resolve_module_path(db, path).take_types()?; match res { - ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it.into()), + ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), _ => None, } } /// pub only for source-binder - pub(crate) fn resolve_module_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs { + pub(crate) fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs { let (item_map, module) = match self.module() { Some(it) => it, None => return PerNs::none(), @@ -130,7 +136,7 @@ pub(crate) fn resolve_module_path(&self, db: &impl HirDatabase, path: &Path) -> pub(crate) fn resolve_path_in_type_ns( &self, - db: &impl HirDatabase, + db: &impl DefDatabase2, path: &Path, ) -> Option<(TypeNs, Option)> { if path.is_type_relative() { @@ -164,13 +170,13 @@ pub(crate) fn resolve_path_in_type_ns( Scope::ModuleScope(m) => { let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); let res = match module_def.take_types()? { - ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), - ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariant(it.into()), + ModuleDefId::AdtId(it) => TypeNs::AdtId(it), + ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), - ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), + ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), - ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), + ModuleDefId::TraitId(it) => TypeNs::TraitId(it), ModuleDefId::FunctionId(_) | ModuleDefId::ConstId(_) @@ -186,7 +192,7 @@ pub(crate) fn resolve_path_in_type_ns( pub(crate) fn resolve_path_in_type_ns_fully( &self, - db: &impl HirDatabase, + db: &impl DefDatabase2, path: &Path, ) -> Option { let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; @@ -198,7 +204,7 @@ pub(crate) fn resolve_path_in_type_ns_fully( pub(crate) fn resolve_path_in_value_ns<'p>( &self, - db: &impl HirDatabase, + db: &impl DefDatabase2, path: &'p Path, ) -> Option { if path.is_type_relative() { @@ -278,9 +284,9 @@ pub(crate) fn resolve_path_in_value_ns<'p>( } Some(idx) => { let ty = match module_def.take_types()? { - ModuleDefId::AdtId(it) => TypeNs::Adt(it.into()), - ModuleDefId::TraitId(it) => TypeNs::Trait(it.into()), - ModuleDefId::TypeAliasId(it) => TypeNs::TypeAlias(it.into()), + ModuleDefId::AdtId(it) => TypeNs::AdtId(it), + ModuleDefId::TraitId(it) => TypeNs::TraitId(it), + ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), ModuleDefId::ModuleId(_) @@ -300,7 +306,7 @@ pub(crate) fn resolve_path_in_value_ns<'p>( pub(crate) fn resolve_path_in_value_ns_fully( &self, - db: &impl HirDatabase, + db: &impl DefDatabase2, path: &Path, ) -> Option { match self.resolve_path_in_value_ns(db, path)? { @@ -311,7 +317,7 @@ pub(crate) fn resolve_path_in_value_ns_fully( pub(crate) fn resolve_path_as_macro( &self, - db: &impl DefDatabase, + db: &impl DefDatabase2, path: &Path, ) -> Option { let (item_map, module) = self.module()?; @@ -320,7 +326,7 @@ pub(crate) fn resolve_path_as_macro( pub(crate) fn process_all_names( &self, - db: &impl HirDatabase, + db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef), ) { for scope in self.scopes.iter().rev() { @@ -328,16 +334,15 @@ pub(crate) fn process_all_names( } } - pub(crate) fn traits_in_scope(&self, db: &impl HirDatabase) -> FxHashSet { + pub(crate) fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet { let mut traits = FxHashSet::default(); for scope in &self.scopes { if let Scope::ModuleScope(m) = scope { if let Some(prelude) = m.crate_def_map.prelude() { let prelude_def_map = db.crate_def_map(prelude.krate); - traits - .extend(prelude_def_map[prelude.module_id].scope.traits().map(Trait::from)); + traits.extend(prelude_def_map[prelude.module_id].scope.traits()); } - traits.extend(m.crate_def_map[m.module_id].scope.traits().map(Trait::from)); + traits.extend(m.crate_def_map[m.module_id].scope.traits()); } } traits @@ -367,7 +372,7 @@ pub(crate) fn where_predicates_in_scope<'a>( .flat_map(|params| params.where_predicates.iter()) } - pub(crate) fn generic_def(&self) -> Option { + pub(crate) fn generic_def(&self) -> Option { self.scopes.iter().find_map(|scope| match scope { Scope::GenericParams { def, .. } => Some(*def), _ => None, @@ -383,10 +388,10 @@ pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver { pub(crate) fn push_generic_params_scope( self, - db: &impl DefDatabase, - def: GenericDef, + db: &impl DefDatabase2, + def: GenericDefId, ) -> Resolver { - let params = def.generic_params(db); + let params = db.generic_params(def); if params.params.is_empty() { self } else { @@ -394,7 +399,7 @@ pub(crate) fn push_generic_params_scope( } } - pub(crate) fn push_impl_block_scope(self, impl_block: ImplBlock) -> Resolver { + pub(crate) fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver { self.push_scope(Scope::ImplBlockScope(impl_block)) } @@ -408,7 +413,7 @@ pub(crate) fn push_module_scope( pub(crate) fn push_expr_scope( self, - owner: DefWithBody, + owner: DefWithBodyId, expr_scopes: Arc, scope_id: ScopeId, ) -> Resolver { @@ -440,7 +445,7 @@ fn from(def: PerNs) -> Self { } impl Scope { - fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { + fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { match self { Scope::ModuleScope(m) => { // FIXME: should we provide `self` here? @@ -472,14 +477,14 @@ fn process_names(&self, db: &impl HirDatabase, f: &mut dyn FnMut(Name, ScopeDef) } } Scope::ImplBlockScope(i) => { - f(name::SELF_TYPE, ScopeDef::ImplSelfType(*i)); + f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into())); } Scope::AdtScope(i) => { - f(name::SELF_TYPE, ScopeDef::AdtSelfType(*i)); + f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into())); } Scope::ExprScope(scope) => { scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { - let local = Local { parent: scope.owner, pat_id: e.pat() }; + let local = Local { parent: scope.owner.into(), pat_id: e.pat() }; f(e.name().clone(), ScopeDef::Local(local)); }); } @@ -501,7 +506,7 @@ fn resolver(self, db: &impl DefDatabase) -> Resolver { impl HasResolver for Trait { fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db).resolver(db).push_generic_params_scope(db, self.into()) + self.module(db).resolver(db).push_generic_params_scope(db, self.id.into()) } } @@ -511,7 +516,7 @@ fn resolver(self, db: &impl DefDatabase) -> Resolver { def.module(db) .resolver(db) .push_generic_params_scope(db, def.into()) - .push_scope(Scope::AdtScope(def)) + .push_scope(Scope::AdtScope(def.into())) } } @@ -520,7 +525,7 @@ 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()) + .push_generic_params_scope(db, self.id.into()) } } @@ -551,7 +556,7 @@ 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()) + .push_generic_params_scope(db, self.id.into()) } } @@ -582,7 +587,7 @@ 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) + .push_generic_params_scope(db, self.id.into()) + .push_impl_block_scope(self.id) } } diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 727310f0662..5abb8d6933b 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -25,8 +25,9 @@ ids::LocationCtx, 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, + Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, + GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, + Struct, Trait, Ty, TypeAlias, }; fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option { @@ -240,16 +241,18 @@ pub fn resolve_hir_path( path: &crate::Path, ) -> Option { let types = self.resolver.resolve_path_in_type_ns_fully(db, &path).map(|ty| match ty { - TypeNs::SelfType(it) => PathResolution::SelfType(it), + TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), TypeNs::GenericParam(idx) => PathResolution::GenericParam(GenericParam { - parent: self.resolver.generic_def().unwrap(), + parent: self.resolver.generic_def().unwrap().into(), idx, }), - TypeNs::AdtSelfType(it) | TypeNs::Adt(it) => PathResolution::Def(it.into()), - TypeNs::EnumVariant(it) => PathResolution::Def(it.into()), - TypeNs::TypeAlias(it) => PathResolution::Def(it.into()), + TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => { + PathResolution::Def(Adt::from(it).into()) + } + TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), + TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), - TypeNs::Trait(it) => PathResolution::Def(it.into()), + TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), }); let values = self.resolver.resolve_path_in_value_ns_fully(db, &path).and_then(|val| { let res = match val { @@ -392,7 +395,7 @@ pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool { let std_future_path = known::std_future_future(); let std_future_trait = match self.resolver.resolve_known_trait(db, &std_future_path) { - Some(it) => it, + Some(it) => it.into(), _ => return false, }; diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 7f9e81d6492..684d6694610 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -24,6 +24,7 @@ use hir_def::{ path::known, type_ref::{Mutability, TypeRef}, + AdtId, }; use hir_expand::{diagnostics::DiagnosticSink, name}; use ra_arena::map::ArenaMap; @@ -43,7 +44,7 @@ resolve::{HasResolver, Resolver, TypeNs}, ty::infer::diagnostics::InferenceDiagnostic, Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, - StructField, VariantDef, + StructField, Trait, VariantDef, }; macro_rules! ty_app { @@ -518,17 +519,17 @@ fn resolve_variant(&mut self, path: Option<&Path>) -> (Ty, Option) { // FIXME: this should resolve assoc items as well, see this example: // https://play.rust-lang.org/?gist=087992e9e22495446c01c0d4e2d69521 match resolver.resolve_path_in_type_ns_fully(self.db, &path) { - Some(TypeNs::Adt(Adt::Struct(it))) => it.into(), - Some(TypeNs::Adt(Adt::Union(it))) => it.into(), + Some(TypeNs::AdtId(AdtId::StructId(it))) => it.into(), + Some(TypeNs::AdtId(AdtId::UnionId(it))) => it.into(), Some(TypeNs::AdtSelfType(adt)) => adt.into(), - Some(TypeNs::EnumVariant(it)) => it.into(), - Some(TypeNs::TypeAlias(it)) => it.into(), + Some(TypeNs::EnumVariantId(it)) => it.into(), + Some(TypeNs::TypeAliasId(it)) => it.into(), Some(TypeNs::SelfType(_)) | Some(TypeNs::GenericParam(_)) | Some(TypeNs::BuiltinType(_)) | - Some(TypeNs::Trait(_)) | - Some(TypeNs::Adt(Adt::Enum(_))) | + Some(TypeNs::TraitId(_)) | + Some(TypeNs::AdtId(AdtId::EnumId(_))) | None => { return (Ty::Unknown, None) } @@ -576,26 +577,26 @@ fn infer_body(&mut self) { fn resolve_into_iter_item(&self) -> Option { let path = known::std_iter_into_iterator(); - let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); trait_.associated_type_by_name(self.db, &name::ITEM_TYPE) } fn resolve_ops_try_ok(&self) -> Option { let path = known::std_ops_try(); - let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); trait_.associated_type_by_name(self.db, &name::OK_TYPE) } fn resolve_future_future_output(&self) -> Option { let path = known::std_future_future(); - let trait_ = self.resolver.resolve_known_trait(self.db, &path)?; + let trait_: Trait = self.resolver.resolve_known_trait(self.db, &path)?.into(); trait_.associated_type_by_name(self.db, &name::OUTPUT_TYPE) } fn resolve_boxed_box(&self) -> Option { let path = known::std_boxed_box(); let struct_ = self.resolver.resolve_known_struct(self.db, &path)?; - Some(Adt::Struct(struct_)) + Some(Adt::Struct(struct_.into())) } } diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 31ca675aac0..f36a2792934 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -94,13 +94,13 @@ fn resolve_assoc_item( let is_before_last = remaining_segments.len() == 1; match (def, is_before_last) { - (TypeNs::Trait(trait_), true) => { + (TypeNs::TraitId(trait_), true) => { let segment = remaining_segments.last().expect("there should be at least one segment here"); let trait_ref = TraitRef::from_resolved_path( self.db, &self.resolver, - trait_, + trait_.into(), resolved_segment, None, ); diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 397ee7d5fc3..d4fbddac020 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -28,8 +28,8 @@ Adt, }, util::make_mut_slice, - Const, Enum, EnumVariant, Function, ModuleDef, Path, Static, Struct, StructField, Trait, - TypeAlias, Union, VariantDef, + Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, StructField, + Trait, TypeAlias, Union, VariantDef, }; // FIXME: this is only really used in `type_for_def`, which contains a bunch of @@ -156,9 +156,14 @@ pub(crate) fn from_partly_resolved_hir_path( remaining_segments: &[PathSegment], ) -> Ty { let ty = match resolution { - TypeNs::Trait(trait_) => { - let trait_ref = - TraitRef::from_resolved_path(db, resolver, trait_, resolved_segment, None); + TypeNs::TraitId(trait_) => { + let trait_ref = TraitRef::from_resolved_path( + db, + resolver, + trait_.into(), + resolved_segment, + None, + ); return if remaining_segments.len() == 1 { let segment = &remaining_segments[0]; match trait_ref @@ -189,18 +194,18 @@ pub(crate) fn from_partly_resolved_hir_path( let name = resolved_segment.name.clone(); Ty::Param { idx, name } } - TypeNs::SelfType(impl_block) => impl_block.target_ty(db), - TypeNs::AdtSelfType(adt) => adt.ty(db), + TypeNs::SelfType(impl_block) => ImplBlock::from(impl_block).target_ty(db), + TypeNs::AdtSelfType(adt) => Adt::from(adt).ty(db), - TypeNs::Adt(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), + TypeNs::AdtId(it) => Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()), TypeNs::BuiltinType(it) => { Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) } - TypeNs::TypeAlias(it) => { + TypeNs::TypeAliasId(it) => { Ty::from_hir_path_inner(db, resolver, resolved_segment, it.into()) } // FIXME: report error - TypeNs::EnumVariant(_) => return Ty::Unknown, + TypeNs::EnumVariantId(_) => return Ty::Unknown, }; Ty::from_type_relative_path(db, resolver, ty, remaining_segments) @@ -247,7 +252,7 @@ fn select_associated_type( Some(def) => def, None => return Ty::Unknown, // this can't actually happen }; - let predicates = db.generic_predicates_for_param(def, param_idx); + let predicates = db.generic_predicates_for_param(def.into(), param_idx); let traits_from_env = predicates.iter().filter_map(|pred| match pred { GenericPredicate::Implemented(tr) if tr.self_ty() == &self_ty => Some(tr.trait_), _ => None, @@ -391,11 +396,11 @@ pub(crate) fn from_path( explicit_self_ty: Option, ) -> Option { let resolved = match resolver.resolve_path_in_type_ns_fully(db, &path)? { - TypeNs::Trait(tr) => tr, + TypeNs::TraitId(tr) => tr, _ => return None, }; let segment = path.segments.last().expect("path should have at least one segment"); - Some(TraitRef::from_resolved_path(db, resolver, resolved, segment, explicit_self_ty)) + Some(TraitRef::from_resolved_path(db, resolver, resolved.into(), segment, explicit_self_ty)) } pub(super) fn from_resolved_path( diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index f377fca48a6..26dd06171c3 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -224,7 +224,9 @@ fn iterate_trait_method_candidates( .trait_predicates_for_self_ty(&ty.value) .map(|tr| tr.trait_) .flat_map(|t| t.all_super_traits(db)); - let traits = inherent_trait.chain(traits_from_env).chain(resolver.traits_in_scope(db)); + let traits = inherent_trait + .chain(traits_from_env) + .chain(resolver.traits_in_scope(db).into_iter().map(Trait::from)); 'traits: for t in traits { let data = t.trait_data(db); diff --git a/crates/ra_hir_def/src/traits.rs b/crates/ra_hir_def/src/traits.rs index 877d73d666d..6c2d5b2a9f7 100644 --- a/crates/ra_hir_def/src/traits.rs +++ b/crates/ra_hir_def/src/traits.rs @@ -11,7 +11,7 @@ use crate::{ db::DefDatabase2, AssocItemId, AstItemDef, ConstLoc, ContainerId, FunctionLoc, Intern, TraitId, - TypeAliasLoc, + TypeAliasId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -56,4 +56,11 @@ pub(crate) fn trait_data_query(db: &impl DefDatabase2, tr: TraitId) -> Arc impl Iterator + '_ { + self.items.iter().filter_map(|item| match item { + AssocItemId::TypeAliasId(t) => Some(*t), + _ => None, + }) + } } From 24964ca58e057b3f32d5cbb17d84e46f2a236ff6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 13:28:04 +0300 Subject: [PATCH 02/21] Move expr resolver to resolve --- crates/ra_hir/src/expr.rs | 26 +------------------------ crates/ra_hir/src/resolve.rs | 31 +++++++++++++++++++++++++++--- crates/ra_hir/src/source_binder.rs | 6 +++--- crates/ra_hir/src/ty/infer/expr.rs | 5 +++-- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 8c4c63fda34..3ca0a4de5ea 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -13,7 +13,7 @@ diagnostics::{MissingFields, MissingOkInTailExpr}, resolve::HasResolver, ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, - Adt, DefWithBody, Function, HasBody, Name, Path, Resolver, + Adt, Function, Name, Path, }; pub use hir_def::{ @@ -27,30 +27,6 @@ }, }; -// needs arbitrary_self_types to be a method... or maybe move to the def? -pub(crate) fn resolver_for_expr( - db: &impl HirDatabase, - owner: DefWithBody, - expr_id: ExprId, -) -> Resolver { - let scopes = owner.expr_scopes(db); - resolver_for_scope(db, owner, scopes.scope_for(expr_id)) -} - -pub(crate) fn resolver_for_scope( - db: &impl HirDatabase, - owner: DefWithBody, - scope_id: Option, -) -> Resolver { - let mut r = owner.resolver(db); - let scopes = owner.expr_scopes(db); - let scope_chain = scopes.scope_chain(scope_id).collect::>(); - for scope in scope_chain.into_iter().rev() { - r = r.push_expr_scope(owner.into(), Arc::clone(&scopes), scope); - } - r -} - pub(crate) struct ExprValidator<'a, 'b: 'a> { func: Function, infer: Arc, diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index f4165babd37..899959532e6 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -4,6 +4,7 @@ use hir_def::{ builtin_type::BuiltinType, db::DefDatabase2, + expr::ExprId, generics::GenericParams, nameres::CrateDefMap, path::{Path, PathKind}, @@ -15,10 +16,10 @@ use crate::{ code_model::Crate, - db::DefDatabase, + db::{DefDatabase, HirDatabase}, expr::{ExprScopes, PatId, ScopeId}, - Adt, Const, Container, DefWithBody, EnumVariant, Function, GenericDef, ImplBlock, Local, - MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, + Adt, Const, Container, DefWithBody, EnumVariant, Function, GenericDef, HasBody, ImplBlock, + Local, MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, }; #[derive(Debug, Clone, Default)] @@ -492,6 +493,30 @@ fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef } } +// needs arbitrary_self_types to be a method... or maybe move to the def? +pub(crate) fn resolver_for_expr( + db: &impl HirDatabase, + owner: DefWithBody, + expr_id: ExprId, +) -> Resolver { + let scopes = owner.expr_scopes(db); + resolver_for_scope(db, owner, scopes.scope_for(expr_id)) +} + +pub(crate) fn resolver_for_scope( + db: &impl HirDatabase, + owner: DefWithBody, + scope_id: Option, +) -> Resolver { + let mut r = owner.resolver(db); + let scopes = owner.expr_scopes(db); + let scope_chain = scopes.scope_chain(scope_id).collect::>(); + for scope in scope_chain.into_iter().rev() { + r = r.push_expr_scope(owner.into(), Arc::clone(&scopes), scope); + } + r +} + pub(crate) trait HasResolver { /// Builds a resolver for type references inside this def. fn resolver(self, db: &impl DefDatabase) -> Resolver; diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 5abb8d6933b..29c928d51bb 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -21,9 +21,9 @@ use crate::{ db::HirDatabase, - expr::{self, BodySourceMap, ExprScopes, ScopeId}, + expr::{BodySourceMap, ExprScopes, ScopeId}, ids::LocationCtx, - resolve::{HasResolver, ScopeDef, TypeNs, ValueNs}, + resolve::{resolver_for_scope, HasResolver, ScopeDef, TypeNs, ValueNs}, ty::method_resolution::{self, implements_trait}, Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, @@ -160,7 +160,7 @@ pub fn new( None => scope_for(&scopes, &source_map, node), Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), }; - let resolver = expr::resolver_for_scope(db, def, scope); + let resolver = resolver_for_scope(db, def, scope); SourceAnalyzer { resolver, body_owner: Some(def), diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 5e68a1678f4..414b06ba16f 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -12,8 +12,9 @@ use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; use crate::{ db::HirDatabase, - expr::{self, Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, + expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, generics::{GenericParams, HasGenericParams}, + resolve::resolver_for_expr, ty::{ autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, @@ -186,7 +187,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { } Expr::Path(p) => { // FIXME this could be more efficient... - let resolver = expr::resolver_for_expr(self.db, self.owner, tgt_expr); + let resolver = resolver_for_expr(self.db, self.owner, tgt_expr); self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) } Expr::Continue => Ty::simple(TypeCtor::Never), From 621cf06156975f8bd75e35af46da034f72e11fad Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 13:32:03 +0300 Subject: [PATCH 03/21] Decouple --- crates/ra_hir/src/from_id.rs | 23 +++++++++++++--- crates/ra_hir/src/resolve.rs | 42 ++++++++++++++---------------- crates/ra_hir/src/source_binder.rs | 12 ++++----- crates/ra_hir/src/ty/infer/expr.rs | 2 +- crates/ra_hir/src/ty/infer/path.rs | 23 ++++++++-------- 5 files changed, 59 insertions(+), 43 deletions(-) diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index 7042422ccf8..e294e957bcb 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -4,12 +4,13 @@ //! are splitting the hir. use hir_def::{ - AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, GenericDefId, ModuleDefId, StructId, - TypeAliasId, UnionId, + AdtId, AssocItemId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, + ModuleDefId, StaticId, StructId, TypeAliasId, UnionId, }; use crate::{ - ty::TypableDef, Adt, AssocItem, DefWithBody, EnumVariant, GenericDef, ModuleDef, TypeAlias, + ty::TypableDef, Adt, AssocItem, Const, DefWithBody, EnumVariant, Function, GenericDef, + ModuleDef, Static, TypeAlias, }; macro_rules! from_id { @@ -174,6 +175,22 @@ fn from(id: TypeAliasId) -> Self { } } +impl From for TypableDef { + fn from(id: FunctionId) -> Self { + Function::from(id).into() + } +} +impl From for TypableDef { + fn from(id: ConstId) -> Self { + Const::from(id).into() + } +} +impl From for TypableDef { + fn from(id: StaticId) -> Self { + Static::from(id).into() + } +} + impl From for GenericDefId { fn from(id: Adt) -> Self { match id { diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 899959532e6..770864ec5d2 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -8,8 +8,8 @@ generics::GenericParams, nameres::CrateDefMap, path::{Path, PathKind}, - AdtId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, GenericDefId, ImplId, ModuleDefId, - StructId, TraitId, TypeAliasId, + AdtId, ConstId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, + ImplId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, }; use hir_expand::name::{self, Name}; use rustc_hash::FxHashSet; @@ -18,8 +18,8 @@ code_model::Crate, db::{DefDatabase, HirDatabase}, expr::{ExprScopes, PatId, ScopeId}, - Adt, Const, Container, DefWithBody, EnumVariant, Function, GenericDef, HasBody, ImplBlock, - Local, MacroDef, Module, ModuleDef, PerNs, Static, Struct, Trait, TypeAlias, + Adt, Const, Container, DefWithBody, Function, GenericDef, ImplBlock, Local, MacroDef, Module, + ModuleDef, PerNs, Static, Trait, TypeAlias, }; #[derive(Debug, Clone, Default)] @@ -79,11 +79,11 @@ pub(crate) enum ResolveValueResult { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub(crate) enum ValueNs { LocalBinding(PatId), - Function(Function), - Const(Const), - Static(Static), - Struct(Struct), - EnumVariant(EnumVariant), + FunctionId(FunctionId), + ConstId(ConstId), + StaticId(StaticId), + StructId(StructId), + EnumVariantId(EnumVariantId), } impl Resolver { @@ -266,13 +266,11 @@ pub(crate) fn resolve_path_in_value_ns<'p>( return match idx { None => { let value = match module_def.take_values()? { - ModuleDefId::FunctionId(it) => ValueNs::Function(it.into()), - ModuleDefId::AdtId(AdtId::StructId(it)) => { - ValueNs::Struct(it.into()) - } - ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariant(it.into()), - ModuleDefId::ConstId(it) => ValueNs::Const(it.into()), - ModuleDefId::StaticId(it) => ValueNs::Static(it.into()), + ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it), + ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it), + ModuleDefId::EnumVariantId(it) => ValueNs::EnumVariantId(it), + ModuleDefId::ConstId(it) => ValueNs::ConstId(it), + ModuleDefId::StaticId(it) => ValueNs::StaticId(it), ModuleDefId::AdtId(AdtId::EnumId(_)) | ModuleDefId::AdtId(AdtId::UnionId(_)) @@ -496,23 +494,23 @@ fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef // needs arbitrary_self_types to be a method... or maybe move to the def? pub(crate) fn resolver_for_expr( db: &impl HirDatabase, - owner: DefWithBody, + owner: DefWithBodyId, expr_id: ExprId, ) -> Resolver { - let scopes = owner.expr_scopes(db); + let scopes = db.expr_scopes(owner); resolver_for_scope(db, owner, scopes.scope_for(expr_id)) } pub(crate) fn resolver_for_scope( db: &impl HirDatabase, - owner: DefWithBody, + owner: DefWithBodyId, scope_id: Option, ) -> Resolver { - let mut r = owner.resolver(db); - let scopes = owner.expr_scopes(db); + let mut r = DefWithBody::from(owner).resolver(db); + let scopes = db.expr_scopes(owner); let scope_chain = scopes.scope_chain(scope_id).collect::>(); for scope in scope_chain.into_iter().rev() { - r = r.push_expr_scope(owner.into(), Arc::clone(&scopes), scope); + r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); } r } diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 29c928d51bb..09df4f0aaa1 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -160,7 +160,7 @@ pub fn new( None => scope_for(&scopes, &source_map, node), Some(offset) => scope_for_offset(&scopes, &source_map, node.with_value(offset)), }; - let resolver = resolver_for_scope(db, def, scope); + let resolver = resolver_for_scope(db, def.into(), scope); SourceAnalyzer { resolver, body_owner: Some(def), @@ -260,11 +260,11 @@ pub fn resolve_hir_path( let var = Local { parent: self.body_owner?, pat_id }; PathResolution::Local(var) } - ValueNs::Function(it) => PathResolution::Def(it.into()), - ValueNs::Const(it) => PathResolution::Def(it.into()), - ValueNs::Static(it) => PathResolution::Def(it.into()), - ValueNs::Struct(it) => PathResolution::Def(it.into()), - ValueNs::EnumVariant(it) => PathResolution::Def(it.into()), + ValueNs::FunctionId(it) => PathResolution::Def(Function::from(it).into()), + ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()), + ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), + ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), + ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), }; Some(res) }); diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 414b06ba16f..1ac2709f59c 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -187,7 +187,7 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { } Expr::Path(p) => { // FIXME this could be more efficient... - let resolver = resolver_for_expr(self.db, self.owner, tgt_expr); + let resolver = resolver_for_expr(self.db, self.owner.into(), tgt_expr); self.infer_path(&resolver, p, tgt_expr.into()).unwrap_or(Ty::Unknown) } Expr::Continue => Ty::simple(TypeCtor::Never), diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index f36a2792934..55a5dbec764 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -8,7 +8,7 @@ generics::HasGenericParams, resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs}, ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, - AssocItem, Container, Name, Path, + AssocItem, Container, Function, Name, Path, }; impl<'a, D: HirDatabase> InferenceContext<'a, D> { @@ -60,11 +60,11 @@ fn resolve_value_path( let ty = self.resolve_ty_as_possible(&mut vec![], ty); return Some(ty); } - ValueNs::Function(it) => it.into(), - ValueNs::Const(it) => it.into(), - ValueNs::Static(it) => it.into(), - ValueNs::Struct(it) => it.into(), - ValueNs::EnumVariant(it) => it.into(), + ValueNs::FunctionId(it) => it.into(), + ValueNs::ConstId(it) => it.into(), + ValueNs::StaticId(it) => it.into(), + ValueNs::StructId(it) => it.into(), + ValueNs::EnumVariantId(it) => it.into(), }; let mut ty = self.db.type_for_def(typable, Namespace::Values); @@ -160,8 +160,8 @@ fn resolve_trait_assoc_item( AssocItem::TypeAlias(_) => None, })?; let def = match item { - AssocItem::Function(f) => ValueNs::Function(f), - AssocItem::Const(c) => ValueNs::Const(c), + AssocItem::Function(f) => ValueNs::FunctionId(f.id), + AssocItem::Const(c) => ValueNs::ConstId(c.id), AssocItem::TypeAlias(_) => unreachable!(), }; let substs = Substs::build_for_def(self.db, item) @@ -193,8 +193,8 @@ fn resolve_ty_assoc_item( method_resolution::LookupMode::Path, move |_ty, item| { let def = match item { - AssocItem::Function(f) => ValueNs::Function(f), - AssocItem::Const(c) => ValueNs::Const(c), + AssocItem::Function(f) => ValueNs::FunctionId(f.id), + AssocItem::Const(c) => ValueNs::ConstId(c.id), AssocItem::TypeAlias(_) => unreachable!(), }; let substs = match item.container(self.db) { @@ -224,7 +224,8 @@ fn resolve_ty_assoc_item( } fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option { - if let ValueNs::Function(func) = def { + if let ValueNs::FunctionId(func) = def { + let func = Function::from(*func); // We only do the infer if parent has generic params let gen = func.generic_params(self.db); if gen.count_parent_params() == 0 { From 061e6c77b5fdb63aa1cad63f1420a7fc810fa17d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 14:13:49 +0300 Subject: [PATCH 04/21] Decouple --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/expr.rs | 2 +- crates/ra_hir/src/impl_block.rs | 4 +- crates/ra_hir/src/resolve.rs | 154 +++++++++++++++++------------ crates/ra_hir/src/source_binder.rs | 8 +- crates/ra_hir/src/ty/lower.rs | 16 +-- 6 files changed, 108 insertions(+), 78 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 550ab1a985c..c4935c0d7e7 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -829,7 +829,7 @@ pub fn items(self, db: &impl DefDatabase) -> Vec { } fn direct_super_traits(self, db: &impl HirDatabase) -> Vec { - let resolver = self.resolver(db); + let resolver = self.id.resolver(db); // returning the iterator directly doesn't easily work because of // lifetime problems, but since there usually shouldn't be more than a // few direct traits this should be fine (we could even use some kind of diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 3ca0a4de5ea..9cdc0c645f5 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -122,7 +122,7 @@ fn validate_results_in_tail_expr( let std_result_path = known::std_result_result(); - let resolver = self.func.resolver(db); + let resolver = self.func.id.resolver(db); let std_result_enum = match resolver.resolve_known_enum(db, &std_result_path) { Some(it) => it, _ => return, diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 964a3da8c08..c84ceee62b9 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -27,12 +27,12 @@ pub fn target_type(&self, db: &impl DefDatabase) -> TypeRef { } pub fn target_ty(&self, db: &impl HirDatabase) -> Ty { - Ty::from_hir(db, &self.resolver(db), &self.target_type(db)) + Ty::from_hir(db, &self.id.resolver(db), &self.target_type(db)) } pub fn target_trait_ref(&self, db: &impl HirDatabase) -> Option { let target_ty = self.target_ty(db); - TraitRef::from_hir(db, &self.resolver(db), &self.target_trait(db)?, Some(target_ty)) + TraitRef::from_hir(db, &self.id.resolver(db), &self.target_trait(db)?, Some(target_ty)) } pub fn items(&self, db: &impl DefDatabase) -> Vec { diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 770864ec5d2..ed9fa04918f 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -8,18 +8,18 @@ generics::GenericParams, nameres::CrateDefMap, path::{Path, PathKind}, - AdtId, ConstId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, - ImplId, ModuleDefId, StaticId, StructId, TraitId, TypeAliasId, + AdtId, AstItemDef, ConstId, ContainerId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, + FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, + TypeAliasId, UnionId, }; use hir_expand::name::{self, Name}; use rustc_hash::FxHashSet; use crate::{ code_model::Crate, - db::{DefDatabase, HirDatabase}, + db::HirDatabase, expr::{ExprScopes, PatId, ScopeId}, - Adt, Const, Container, DefWithBody, Function, GenericDef, ImplBlock, Local, MacroDef, Module, - ModuleDef, PerNs, Static, Trait, TypeAlias, + Adt, DefWithBody, GenericDef, ImplBlock, Local, MacroDef, ModuleDef, PerNs, }; #[derive(Debug, Clone, Default)] @@ -506,7 +506,7 @@ pub(crate) fn resolver_for_scope( owner: DefWithBodyId, scope_id: Option, ) -> Resolver { - let mut r = DefWithBody::from(owner).resolver(db); + let mut r = owner.resolver(db); let scopes = db.expr_scopes(owner); let scope_chain = scopes.scope_chain(scope_id).collect::>(); for scope in scope_chain.into_iter().rev() { @@ -517,100 +517,130 @@ pub(crate) fn resolver_for_scope( pub(crate) trait HasResolver { /// Builds a resolver for type references inside this def. - fn resolver(self, db: &impl DefDatabase) -> Resolver; + fn resolver(self, db: &impl DefDatabase2) -> 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 ModuleId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + let def_map = db.crate_def_map(self.krate); + Resolver::default().push_module_scope(def_map, self.module_id) } } -impl HasResolver for Trait { - fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db).resolver(db).push_generic_params_scope(db, self.id.into()) +impl HasResolver for TraitId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + self.module(db).resolver(db).push_generic_params_scope(db, self.into()) } } -impl> HasResolver for T { - fn resolver(self, db: &impl DefDatabase) -> Resolver { - let def = self.into(); - def.module(db) +impl HasResolver for AdtId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + let module = match self { + AdtId::StructId(it) => it.0.module(db), + AdtId::UnionId(it) => it.0.module(db), + AdtId::EnumId(it) => it.module(db), + }; + + module .resolver(db) - .push_generic_params_scope(db, def.into()) - .push_scope(Scope::AdtScope(def.into())) + .push_generic_params_scope(db, self.into()) + .push_scope(Scope::AdtScope(self.into())) } } -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.id.into()) +impl HasResolver for StructId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + AdtId::from(self).resolver(db) } } -impl HasResolver for DefWithBody { - fn resolver(self, db: &impl DefDatabase) -> Resolver { +impl HasResolver for UnionId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + AdtId::from(self).resolver(db) + } +} + +impl HasResolver for EnumId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + AdtId::from(self).resolver(db) + } +} + +impl HasResolver for FunctionId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) + } +} + +impl HasResolver for DefWithBodyId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { match self { - DefWithBody::Const(c) => c.resolver(db), - DefWithBody::Function(f) => f.resolver(db), - DefWithBody::Static(s) => s.resolver(db), + DefWithBodyId::ConstId(c) => c.resolver(db), + DefWithBodyId::FunctionId(f) => f.resolver(db), + DefWithBodyId::StaticId(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 ConstId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + self.lookup(db).container.resolver(db) } } -impl HasResolver for Static { - fn resolver(self, db: &impl DefDatabase) -> Resolver { +impl HasResolver for StaticId { + fn resolver(self, db: &impl DefDatabase2) -> 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.id.into()) +impl HasResolver for TypeAliasId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) } } -impl HasResolver for Container { - fn resolver(self, db: &impl DefDatabase) -> Resolver { +impl HasResolver for ContainerId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { match self { - Container::Trait(trait_) => trait_.resolver(db), - Container::ImplBlock(impl_block) => impl_block.resolver(db), + ContainerId::TraitId(it) => it.resolver(db), + ContainerId::ImplId(it) => it.resolver(db), + ContainerId::ModuleId(it) => it.resolver(db), } } } +impl HasResolver for GenericDefId { + fn resolver(self, db: &impl DefDatabase2) -> crate::Resolver { + match self { + GenericDefId::FunctionId(inner) => inner.resolver(db), + GenericDefId::AdtId(adt) => adt.resolver(db), + GenericDefId::TraitId(inner) => inner.resolver(db), + GenericDefId::TypeAliasId(inner) => inner.resolver(db), + GenericDefId::ImplId(inner) => inner.resolver(db), + GenericDefId::EnumVariantId(inner) => inner.parent.resolver(db), + GenericDefId::ConstId(inner) => inner.resolver(db), + } + } +} + +impl HasResolver for ImplId { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_impl_block_scope(self) + } +} + 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), - } + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + GenericDefId::from(self).resolver(db) } } -impl HasResolver for ImplBlock { - fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db) - .resolver(db) - .push_generic_params_scope(db, self.id.into()) - .push_impl_block_scope(self.id) +impl HasResolver for DefWithBody { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { + DefWithBodyId::from(self).resolver(db) } } diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 09df4f0aaa1..8e379498a84 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -35,19 +35,19 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - match (node.value) { ast::Module(it) => { let src = node.with_value(it); - Some(crate::Module::from_declaration(db, src)?.resolver(db)) + Some(crate::Module::from_declaration(db, src)?.id.resolver(db)) }, ast::SourceFile(it) => { let src = node.with_value(crate::ModuleSource::SourceFile(it)); - Some(crate::Module::from_definition(db, src)?.resolver(db)) + Some(crate::Module::from_definition(db, src)?.id.resolver(db)) }, ast::StructDef(it) => { let src = node.with_value(it); - Some(Struct::from_source(db, src)?.resolver(db)) + Some(Struct::from_source(db, src)?.id.resolver(db)) }, ast::EnumDef(it) => { let src = node.with_value(it); - Some(Enum::from_source(db, src)?.resolver(db)) + Some(Enum::from_source(db, src)?.id.resolver(db)) }, _ => match node.value.kind() { FN_DEF | CONST_DEF | STATIC_DEF => { diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index d4fbddac020..8ea2806dd4e 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -553,8 +553,8 @@ pub(crate) fn callable_item_sig(db: &impl HirDatabase, def: CallableDef) -> FnSi pub(crate) fn type_for_field(db: &impl HirDatabase, field: StructField) -> Ty { let parent_def = field.parent_def(db); let resolver = match parent_def { - VariantDef::Struct(it) => it.resolver(db), - VariantDef::EnumVariant(it) => it.parent_enum(db).resolver(db), + VariantDef::Struct(it) => it.id.resolver(db), + VariantDef::EnumVariant(it) => it.parent.id.resolver(db), }; let var_data = parent_def.variant_data(db); let type_ref = &var_data.fields().unwrap()[field.id].type_ref; @@ -623,7 +623,7 @@ pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { let data = def.data(db); - let resolver = def.resolver(db); + let resolver = def.id.resolver(db); let params = data.params().iter().map(|tr| Ty::from_hir(db, &resolver, tr)).collect::>(); let ret = Ty::from_hir(db, &resolver, data.ret_type()); FnSig::from_params_and_return(params, ret) @@ -640,7 +640,7 @@ fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { /// Build the declared type of a const. fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { let data = def.data(db); - let resolver = def.resolver(db); + let resolver = def.id.resolver(db); Ty::from_hir(db, &resolver, data.type_ref()) } @@ -648,7 +648,7 @@ fn type_for_const(db: &impl HirDatabase, def: Const) -> Ty { /// Build the declared type of a static. fn type_for_static(db: &impl HirDatabase, def: Static) -> Ty { let data = def.data(db); - let resolver = def.resolver(db); + let resolver = def.id.resolver(db); Ty::from_hir(db, &resolver, data.type_ref()) } @@ -700,7 +700,7 @@ fn fn_sig_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> FnSig { Some(fields) => fields, None => panic!("fn_sig_for_struct_constructor called on unit struct"), }; - let resolver = def.resolver(db); + let resolver = def.id.resolver(db); let params = fields .iter() .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) @@ -726,7 +726,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) Some(fields) => fields, None => panic!("fn_sig_for_enum_variant_constructor called for unit variant"), }; - let resolver = def.parent_enum(db).resolver(db); + let resolver = def.parent.id.resolver(db); let params = fields .iter() .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) @@ -755,7 +755,7 @@ fn type_for_adt(db: &impl HirDatabase, adt: impl Into + HasGenericParams) - fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { let generics = t.generic_params(db); - let resolver = t.resolver(db); + let resolver = t.id.resolver(db); let type_ref = t.type_ref(db); let substs = Substs::identity(&generics); let inner = Ty::from_hir(db, &resolver, &type_ref.unwrap_or(TypeRef::Error)); From 1312c57d342730690a0181c53f82bb3e281114ff Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 14:21:26 +0300 Subject: [PATCH 05/21] Move ScopeDef --- crates/ra_hir/src/code_model.rs | 26 +++++++++++++++++++++++++- crates/ra_hir/src/lib.rs | 5 ++--- crates/ra_hir/src/resolve.rs | 25 +------------------------ crates/ra_hir/src/source_binder.rs | 6 +++--- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index c4935c0d7e7..39b01d5102f 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -10,6 +10,7 @@ adt::VariantData, body::scope::ExprScopes, builtin_type::BuiltinType, + nameres::per_ns::PerNs, traits::TraitData, type_ref::{Mutability, TypeRef}, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, @@ -32,7 +33,7 @@ }, resolve::{HasResolver, TypeNs}, ty::{InferenceResult, Namespace, TraitRef}, - Either, HasSource, ImportId, Name, ScopeDef, Source, Ty, + Either, HasSource, ImportId, Name, Source, Ty, }; /// hir::Crate describes a single crate. It's the main interface with which @@ -1064,3 +1065,26 @@ pub struct GenericParam { pub struct ImplBlock { pub(crate) id: ImplId, } + +/// For IDE only +pub enum ScopeDef { + ModuleDef(ModuleDef), + MacroDef(MacroDef), + GenericParam(u32), + ImplSelfType(ImplBlock), + AdtSelfType(Adt), + Local(Local), + Unknown, +} + +impl From for ScopeDef { + fn from(def: PerNs) -> Self { + def.take_types() + .or_else(|| def.take_values()) + .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) + .or_else(|| { + def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) + }) + .unwrap_or(ScopeDef::Unknown) + } +} diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 31da74d2f3b..095d4964f4e 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -61,14 +61,13 @@ fn from(it: $sv) -> $e { src::{HasBodySource, HasSource}, Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, - MacroDef, Module, ModuleDef, ModuleSource, Static, Struct, StructField, Trait, TypeAlias, - Union, VariantDef, + MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait, + TypeAlias, Union, VariantDef, }, expr::ExprScopes, from_source::FromSource, generics::GenericDef, ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, - resolve::ScopeDef, source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, ty::{ display::HirDisplay, diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index ed9fa04918f..5e04ca9b6e8 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -19,7 +19,7 @@ code_model::Crate, db::HirDatabase, expr::{ExprScopes, PatId, ScopeId}, - Adt, DefWithBody, GenericDef, ImplBlock, Local, MacroDef, ModuleDef, PerNs, + DefWithBody, GenericDef, Local, MacroDef, PerNs, ScopeDef, }; #[derive(Debug, Clone, Default)] @@ -420,29 +420,6 @@ pub(crate) fn push_expr_scope( } } -/// For IDE only -pub enum ScopeDef { - ModuleDef(ModuleDef), - MacroDef(MacroDef), - GenericParam(u32), - ImplSelfType(ImplBlock), - AdtSelfType(Adt), - Local(Local), - Unknown, -} - -impl From for ScopeDef { - fn from(def: PerNs) -> Self { - def.take_types() - .or_else(|| def.take_values()) - .map(|module_def_id| ScopeDef::ModuleDef(module_def_id.into())) - .or_else(|| { - def.get_macros().map(|macro_def_id| ScopeDef::MacroDef(macro_def_id.into())) - }) - .unwrap_or(ScopeDef::Unknown) - } -} - impl Scope { fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { match self { diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 8e379498a84..467e46d8cba 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -23,11 +23,11 @@ db::HirDatabase, expr::{BodySourceMap, ExprScopes, ScopeId}, ids::LocationCtx, - resolve::{resolver_for_scope, HasResolver, ScopeDef, TypeNs, ValueNs}, + resolve::{resolver_for_scope, HasResolver, TypeNs, ValueNs}, ty::method_resolution::{self, implements_trait}, Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, - GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, Static, - Struct, Trait, Ty, TypeAlias, + GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, ScopeDef, + Static, Struct, Trait, Ty, TypeAlias, }; fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option { From ca1af86e7bb104533f9878f84a7a3a39e5107c30 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 14:22:30 +0300 Subject: [PATCH 06/21] Use GenericParam in ScopeDef --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/resolve.rs | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 39b01d5102f..3c891547e5c 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -1070,7 +1070,7 @@ pub struct ImplBlock { pub enum ScopeDef { ModuleDef(ModuleDef), MacroDef(MacroDef), - GenericParam(u32), + GenericParam(GenericParam), ImplSelfType(ImplBlock), AdtSelfType(Adt), Local(Local), diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 5e04ca9b6e8..a029513b574 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -19,7 +19,7 @@ code_model::Crate, db::HirDatabase, expr::{ExprScopes, PatId, ScopeId}, - DefWithBody, GenericDef, Local, MacroDef, PerNs, ScopeDef, + DefWithBody, GenericDef, GenericParam, Local, MacroDef, PerNs, ScopeDef, }; #[derive(Debug, Clone, Default)] @@ -447,9 +447,15 @@ fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef }); } } - Scope::GenericParams { params, .. } => { + Scope::GenericParams { params, def } => { for param in params.params.iter() { - f(param.name.clone(), ScopeDef::GenericParam(param.idx)) + f( + param.name.clone(), + ScopeDef::GenericParam(GenericParam { + parent: (*def).into(), + idx: param.idx, + }), + ) } } Scope::ImplBlockScope(i) => { From eb53aa37a336b6c9369ea931812f6c491e8f4a71 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 15:13:46 +0300 Subject: [PATCH 07/21] Split internal and user-visible ScopeDef --- crates/ra_hir/src/resolve.rs | 38 ++++++++++++++++++------------ crates/ra_hir/src/source_binder.rs | 19 +++++++++++++-- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index a029513b574..7ff0c43aef4 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -19,7 +19,7 @@ code_model::Crate, db::HirDatabase, expr::{ExprScopes, PatId, ScopeId}, - DefWithBody, GenericDef, GenericParam, Local, MacroDef, PerNs, ScopeDef, + DefWithBody, GenericDef, MacroDef, PerNs, }; #[derive(Debug, Clone, Default)] @@ -377,6 +377,13 @@ pub(crate) fn generic_def(&self) -> Option { _ => None, }) } + + pub(crate) fn body_owner(&self) -> Option { + self.scopes.iter().find_map(|scope| match scope { + Scope::ExprScope(it) => Some(it.owner), + _ => None, + }) + } } impl Resolver { @@ -420,6 +427,14 @@ pub(crate) fn push_expr_scope( } } +pub(crate) enum ScopeDef { + PerNs(PerNs), + ImplSelfType(ImplId), + AdtSelfType(AdtId), + GenericParam(u32), + Local(PatId), +} + impl Scope { fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { match self { @@ -432,30 +447,24 @@ fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef // }), // ); m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { - f(name.clone(), res.def.into()); + f(name.clone(), ScopeDef::PerNs(res.def)); }); m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { - f(name.clone(), ScopeDef::MacroDef(macro_.into())); + f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); }); m.crate_def_map.extern_prelude().iter().for_each(|(name, &def)| { - f(name.clone(), ScopeDef::ModuleDef(def.into())); + f(name.clone(), ScopeDef::PerNs(PerNs::types(def.into()))); }); if let Some(prelude) = m.crate_def_map.prelude() { let prelude_def_map = db.crate_def_map(prelude.krate); prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| { - f(name.clone(), res.def.into()); + f(name.clone(), ScopeDef::PerNs(res.def)); }); } } - Scope::GenericParams { params, def } => { + Scope::GenericParams { params, .. } => { for param in params.params.iter() { - f( - param.name.clone(), - ScopeDef::GenericParam(GenericParam { - parent: (*def).into(), - idx: param.idx, - }), - ) + f(param.name.clone(), ScopeDef::GenericParam(param.idx)) } } Scope::ImplBlockScope(i) => { @@ -466,8 +475,7 @@ fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef } Scope::ExprScope(scope) => { scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { - let local = Local { parent: scope.owner.into(), pat_id: e.pat() }; - f(e.name().clone(), ScopeDef::Local(local)); + f(e.name().clone(), ScopeDef::Local(e.pat())); }); } } diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 467e46d8cba..f13d43740f9 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -23,7 +23,7 @@ db::HirDatabase, expr::{BodySourceMap, ExprScopes, ScopeId}, ids::LocationCtx, - resolve::{resolver_for_scope, HasResolver, TypeNs, ValueNs}, + resolve::{self, resolver_for_scope, HasResolver, TypeNs, ValueNs}, ty::method_resolution::{self, implements_trait}, Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, ScopeDef, @@ -310,7 +310,22 @@ fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option it.into(), + resolve::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), + resolve::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), + resolve::ScopeDef::GenericParam(idx) => { + let parent = self.resolver.generic_def().unwrap().into(); + ScopeDef::GenericParam(GenericParam { parent, idx }) + } + resolve::ScopeDef::Local(pat_id) => { + let parent = self.resolver.body_owner().unwrap().into(); + ScopeDef::Local(Local { parent, pat_id }) + } + }; + f(name, def) + }) } // FIXME: we only use this in `inline_local_variable` assist, ideally, we From 00684d708b64fe81a0264795f27594d450a8d08d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 15:24:51 +0300 Subject: [PATCH 08/21] Decouple --- crates/ra_hir/src/from_id.rs | 8 ++++- crates/ra_hir/src/resolve.rs | 42 ++++++++--------------- crates/ra_hir/src/source_binder.rs | 13 ++++--- crates/ra_hir/src/ty/autoderef.rs | 4 +-- crates/ra_hir/src/ty/infer.rs | 9 ++--- crates/ra_hir/src/ty/infer/coerce.rs | 4 +-- crates/ra_hir/src/ty/lower.rs | 7 ++-- crates/ra_hir/src/ty/method_resolution.rs | 15 +++++--- 8 files changed, 53 insertions(+), 49 deletions(-) diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index e294e957bcb..a3e9d8525f2 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -9,10 +9,16 @@ }; use crate::{ - ty::TypableDef, Adt, AssocItem, Const, DefWithBody, EnumVariant, Function, GenericDef, + ty::TypableDef, Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef, Static, TypeAlias, }; +impl From for Crate { + fn from(crate_id: ra_db::CrateId) -> Self { + Crate { crate_id } + } +} + macro_rules! from_id { ($(($id:path, $ty:path)),*) => {$( impl From<$id> for $ty { diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs index 7ff0c43aef4..a616f0ea572 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir/src/resolve.rs @@ -2,25 +2,23 @@ use std::sync::Arc; use hir_def::{ + body::scope::{ExprScopes, ScopeId}, builtin_type::BuiltinType, db::DefDatabase2, - expr::ExprId, + expr::{ExprId, PatId}, generics::GenericParams, - nameres::CrateDefMap, + nameres::{per_ns::PerNs, CrateDefMap}, path::{Path, PathKind}, AdtId, AstItemDef, ConstId, ContainerId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, }; -use hir_expand::name::{self, Name}; -use rustc_hash::FxHashSet; - -use crate::{ - code_model::Crate, - db::HirDatabase, - expr::{ExprScopes, PatId, ScopeId}, - DefWithBody, GenericDef, MacroDef, PerNs, +use hir_expand::{ + name::{self, Name}, + MacroDefId, }; +use ra_db::CrateId; +use rustc_hash::FxHashSet; #[derive(Debug, Clone, Default)] pub(crate) struct Resolver { @@ -318,9 +316,9 @@ pub(crate) fn resolve_path_as_macro( &self, db: &impl DefDatabase2, path: &Path, - ) -> Option { + ) -> Option { let (item_map, module) = self.module()?; - item_map.resolve_path(db, module, path).0.get_macros().map(MacroDef::from) + item_map.resolve_path(db, module, path).0.get_macros() } pub(crate) fn process_all_names( @@ -355,8 +353,8 @@ fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { }) } - pub(crate) fn krate(&self) -> Option { - self.module().map(|t| Crate { crate_id: t.0.krate() }) + pub(crate) fn krate(&self) -> Option { + self.module().map(|t| t.0.krate()) } pub(crate) fn where_predicates_in_scope<'a>( @@ -484,7 +482,7 @@ fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef // needs arbitrary_self_types to be a method... or maybe move to the def? pub(crate) fn resolver_for_expr( - db: &impl HirDatabase, + db: &impl DefDatabase2, owner: DefWithBodyId, expr_id: ExprId, ) -> Resolver { @@ -493,7 +491,7 @@ pub(crate) fn resolver_for_expr( } pub(crate) fn resolver_for_scope( - db: &impl HirDatabase, + db: &impl DefDatabase2, owner: DefWithBodyId, scope_id: Option, ) -> Resolver { @@ -623,15 +621,3 @@ fn resolver(self, db: &impl DefDatabase2) -> Resolver { .push_impl_block_scope(self) } } - -impl HasResolver for GenericDef { - fn resolver(self, db: &impl DefDatabase2) -> Resolver { - GenericDefId::from(self).resolver(db) - } -} - -impl HasResolver for DefWithBody { - fn resolver(self, db: &impl DefDatabase2) -> Resolver { - DefWithBodyId::from(self).resolver(db) - } -} diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index f13d43740f9..898b823c0b0 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -10,6 +10,7 @@ use hir_def::{ expr::{ExprId, PatId}, path::known, + DefWithBodyId, }; use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; use ra_syntax::{ @@ -51,7 +52,9 @@ fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) - }, _ => match node.value.kind() { FN_DEF | CONST_DEF | STATIC_DEF => { - Some(def_with_body_from_child_node(db, node)?.resolver(db)) + let def = def_with_body_from_child_node(db, node)?; + let def = DefWithBodyId::from(def); + Some(def.resolver(db)) } // FIXME add missing cases _ => None @@ -232,7 +235,7 @@ pub fn resolve_macro_call( ) -> Option { // This must be a normal source file rather than macro file. let path = macro_call.path().and_then(Path::from_ast)?; - self.resolver.resolve_path_as_macro(db, &path) + self.resolver.resolve_path_as_macro(db, &path).map(|it| it.into()) } pub fn resolve_hir_path( @@ -275,7 +278,9 @@ pub fn resolve_hir_path( .take_types() .map(|it| PathResolution::Def(it.into())); types.or(values).or(items).or_else(|| { - self.resolver.resolve_path_as_macro(db, &path).map(|def| PathResolution::Macro(def)) + self.resolver + .resolve_path_as_macro(db, &path) + .map(|def| PathResolution::Macro(def.into())) }) } @@ -420,7 +425,7 @@ pub fn impls_future(&self, db: &impl HirDatabase, ty: Ty) -> bool { }; let canonical_ty = crate::ty::Canonical { value: ty, num_vars: 0 }; - implements_trait(&canonical_ty, db, &self.resolver, krate, std_future_trait) + implements_trait(&canonical_ty, db, &self.resolver, krate.into(), std_future_trait) } pub fn expand( diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 872a4517d13..f774921701c 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -39,7 +39,7 @@ fn deref_by_trait( ty: &Canonical, ) -> Option> { let krate = resolver.krate()?; - let deref_trait = match db.lang_item(krate, "deref".into())? { + let deref_trait = match db.lang_item(krate.into(), "deref".into())? { crate::lang_item::LangItemTarget::Trait(t) => t, _ => return None, }; @@ -71,7 +71,7 @@ fn deref_by_trait( let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; - let solution = db.trait_solve(krate, canonical)?; + let solution = db.trait_solve(krate.into(), canonical)?; match &solution { Solution::Unique(vars) => { diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 684d6694610..c3d65afa688 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -24,7 +24,7 @@ use hir_def::{ path::known, type_ref::{Mutability, TypeRef}, - AdtId, + AdtId, DefWithBodyId, }; use hir_expand::{diagnostics::DiagnosticSink, name}; use ra_arena::map::ArenaMap; @@ -65,7 +65,7 @@ macro_rules! ty_app { /// The entry point of type inference. pub fn infer_query(db: &impl HirDatabase, def: DefWithBody) -> Arc { let _p = profile("infer_query"); - let resolver = def.resolver(db); + let resolver = DefWithBodyId::from(def).resolver(db); let mut ctx = InferenceContext::new(db, def, resolver); match def { @@ -378,8 +378,9 @@ fn resolve_obligations_as_possible(&mut self) { for obligation in obligations { let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); - let solution = - self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); + let solution = self + .db + .trait_solve(self.resolver.krate().unwrap().into(), canonicalized.value.clone()); match solution { Some(Solution::Unique(substs)) => { diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 6ea135126a5..6d297c268e2 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -49,8 +49,8 @@ pub(super) fn init_coerce_unsized_map( resolver: &Resolver, ) -> FxHashMap<(TypeCtor, TypeCtor), usize> { let krate = resolver.krate().unwrap(); - let impls = match db.lang_item(krate, "coerce_unsized".into()) { - Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate, trait_), + let impls = match db.lang_item(krate.into(), "coerce_unsized".into()) { + Some(LangItemTarget::Trait(trait_)) => db.impls_for_trait(krate.into(), trait_), _ => return FxHashMap::default(), }; diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index 8ea2806dd4e..e477b2439aa 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -12,6 +12,7 @@ builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, path::{GenericArg, PathSegment}, type_ref::{TypeBound, TypeRef}, + GenericDefId, }; use super::{ @@ -574,7 +575,7 @@ pub(crate) fn generic_predicates_for_param_query( def: GenericDef, param_idx: u32, ) -> Arc<[GenericPredicate]> { - let resolver = def.resolver(db); + let resolver = GenericDefId::from(def).resolver(db); resolver .where_predicates_in_scope() // we have to filter out all other predicates *first*, before attempting to lower them @@ -600,7 +601,7 @@ pub(crate) fn generic_predicates_query( db: &impl HirDatabase, def: GenericDef, ) -> Arc<[GenericPredicate]> { - let resolver = def.resolver(db); + let resolver = GenericDefId::from(def).resolver(db); resolver .where_predicates_in_scope() .flat_map(|pred| GenericPredicate::from_where_predicate(db, &resolver, pred)) @@ -609,7 +610,7 @@ pub(crate) fn generic_predicates_query( /// Resolve the default type params from generics pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { - let resolver = def.resolver(db); + let resolver = GenericDefId::from(def).resolver(db); let generic_params = def.generic_params(db); let defaults = generic_params diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 26dd06171c3..5ad72ef9f57 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -172,9 +172,14 @@ pub(crate) fn iterate_method_candidates( // rustc does an autoderef and then autoref again). for derefed_ty in autoderef::autoderef(db, resolver, ty.clone()) { - if let Some(result) = - iterate_inherent_methods(&derefed_ty, db, name, mode, krate, &mut callback) - { + if let Some(result) = iterate_inherent_methods( + &derefed_ty, + db, + name, + mode, + krate.into(), + &mut callback, + ) { return Some(result); } if let Some(result) = iterate_trait_method_candidates( @@ -192,7 +197,7 @@ pub(crate) fn iterate_method_candidates( LookupMode::Path => { // No autoderef for path lookups if let Some(result) = - iterate_inherent_methods(&ty, db, name, mode, krate, &mut callback) + iterate_inherent_methods(&ty, db, name, mode, krate.into(), &mut callback) { return Some(result); } @@ -240,7 +245,7 @@ fn iterate_trait_method_candidates( } if !known_implemented { let goal = generic_implements_goal(db, env.clone(), t, ty.clone()); - if db.trait_solve(krate, goal).is_none() { + if db.trait_solve(krate.into(), goal).is_none() { continue 'traits; } } From 6d64798a2300858c74b1cc0a22f6d3df578288b3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 15:39:09 +0300 Subject: [PATCH 09/21] Move resolver to hir_def --- crates/ra_hir/src/code_model.rs | 2 +- crates/ra_hir/src/expr.rs | 3 +- crates/ra_hir/src/impl_block.rs | 5 +- crates/ra_hir/src/lib.rs | 3 - crates/ra_hir/src/source_binder.rs | 16 ++-- crates/ra_hir/src/ty/autoderef.rs | 3 +- crates/ra_hir/src/ty/infer.rs | 2 +- crates/ra_hir/src/ty/infer/coerce.rs | 6 +- crates/ra_hir/src/ty/infer/expr.rs | 5 +- crates/ra_hir/src/ty/infer/path.rs | 9 ++- crates/ra_hir/src/ty/lower.rs | 2 +- crates/ra_hir/src/ty/method_resolution.rs | 2 +- crates/ra_hir_def/src/lib.rs | 1 + .../resolve.rs => ra_hir_def/src/resolver.rs} | 81 ++++++++----------- 14 files changed, 63 insertions(+), 77 deletions(-) rename crates/{ra_hir/src/resolve.rs => ra_hir_def/src/resolver.rs} (92%) diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 3c891547e5c..92860fb598d 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -11,6 +11,7 @@ body::scope::ExprScopes, builtin_type::BuiltinType, nameres::per_ns::PerNs, + resolver::{HasResolver, TypeNs}, traits::TraitData, type_ref::{Mutability, TypeRef}, ContainerId, CrateModuleId, HasModule, ImplId, LocalEnumVariantId, LocalStructFieldId, Lookup, @@ -31,7 +32,6 @@ AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, TypeAliasId, }, - resolve::{HasResolver, TypeNs}, ty::{InferenceResult, Namespace, TraitRef}, Either, HasSource, ImportId, Name, Source, Ty, }; diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 9cdc0c645f5..6b703d8b4be 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -2,7 +2,7 @@ use std::sync::Arc; -use hir_def::path::known; +use hir_def::{path::known, resolver::HasResolver}; use hir_expand::diagnostics::DiagnosticSink; use ra_syntax::ast; use ra_syntax::AstPtr; @@ -11,7 +11,6 @@ use crate::{ db::HirDatabase, diagnostics::{MissingFields, MissingOkInTailExpr}, - resolve::HasResolver, ty::{ApplicationTy, InferenceResult, Ty, TypeCtor}, Adt, Function, Name, Path, }; diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index c84ceee62b9..774fa1d9640 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs @@ -1,11 +1,10 @@ //! FIXME: write short doc here -use hir_def::{type_ref::TypeRef, AstItemDef}; -use ra_syntax::ast::{self}; +use hir_def::{resolver::HasResolver, type_ref::TypeRef, AstItemDef}; +use ra_syntax::ast; use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, - resolve::HasResolver, ty::Ty, AssocItem, Crate, HasSource, ImplBlock, Module, Source, TraitRef, }; diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 095d4964f4e..76c96bdcfb3 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -38,7 +38,6 @@ fn from(it: $sv) -> $e { mod expr; mod lang_item; pub mod generics; -mod resolve; pub mod diagnostics; mod util; @@ -52,8 +51,6 @@ fn from(it: $sv) -> $e { #[cfg(test)] mod marks; -use crate::resolve::Resolver; - pub use crate::{ code_model::{ attrs::{AttrDef, Attrs}, diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 898b823c0b0..c42ceabdfc3 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -10,6 +10,7 @@ use hir_def::{ expr::{ExprId, PatId}, path::known, + resolver::{self, resolver_for_scope, HasResolver, Resolver, TypeNs, ValueNs}, DefWithBodyId, }; use hir_expand::{name::AsName, AstId, MacroCallId, MacroCallLoc, MacroFileKind, Source}; @@ -24,11 +25,10 @@ db::HirDatabase, expr::{BodySourceMap, ExprScopes, ScopeId}, ids::LocationCtx, - resolve::{self, resolver_for_scope, HasResolver, TypeNs, ValueNs}, ty::method_resolution::{self, implements_trait}, Adt, AssocItem, Const, DefWithBody, Either, Enum, EnumVariant, FromSource, Function, - GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, Resolver, ScopeDef, - Static, Struct, Trait, Ty, TypeAlias, + GenericParam, HasBody, HirFileId, Local, MacroDef, Module, Name, Path, ScopeDef, Static, + Struct, Trait, Ty, TypeAlias, }; fn try_get_resolver_for_node(db: &impl HirDatabase, node: Source<&SyntaxNode>) -> Option { @@ -317,14 +317,14 @@ fn resolve_local_name(&self, name_ref: &ast::NameRef) -> Option it.into(), - resolve::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), - resolve::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), - resolve::ScopeDef::GenericParam(idx) => { + resolver::ScopeDef::PerNs(it) => it.into(), + resolver::ScopeDef::ImplSelfType(it) => ScopeDef::ImplSelfType(it.into()), + resolver::ScopeDef::AdtSelfType(it) => ScopeDef::AdtSelfType(it.into()), + resolver::ScopeDef::GenericParam(idx) => { let parent = self.resolver.generic_def().unwrap().into(); ScopeDef::GenericParam(GenericParam { parent, idx }) } - resolve::ScopeDef::Local(pat_id) => { + resolver::ScopeDef::Local(pat_id) => { let parent = self.resolver.body_owner().unwrap().into(); ScopeDef::Local(Local { parent, pat_id }) } diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index f774921701c..5d8518041fd 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -5,11 +5,12 @@ use std::iter::successors; +use hir_def::resolver::Resolver; use hir_expand::name; use log::{info, warn}; use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; -use crate::{db::HirDatabase, generics::HasGenericParams, Resolver}; +use crate::{db::HirDatabase, generics::HasGenericParams}; const AUTODEREF_RECURSION_LIMIT: usize = 10; diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index c3d65afa688..69b13baefba 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs @@ -23,6 +23,7 @@ use hir_def::{ path::known, + resolver::{HasResolver, Resolver, TypeNs}, type_ref::{Mutability, TypeRef}, AdtId, DefWithBodyId, }; @@ -41,7 +42,6 @@ code_model::TypeAlias, db::HirDatabase, expr::{BindingAnnotation, Body, ExprId, PatId}, - resolve::{HasResolver, Resolver, TypeNs}, ty::infer::diagnostics::InferenceDiagnostic, Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path, StructField, Trait, VariantDef, diff --git a/crates/ra_hir/src/ty/infer/coerce.rs b/crates/ra_hir/src/ty/infer/coerce.rs index 6d297c268e2..0772b9df57a 100644 --- a/crates/ra_hir/src/ty/infer/coerce.rs +++ b/crates/ra_hir/src/ty/infer/coerce.rs @@ -4,19 +4,19 @@ //! //! See: https://doc.rust-lang.org/nomicon/coercions.html +use hir_def::resolver::Resolver; use rustc_hash::FxHashMap; - use test_utils::tested_by; -use super::{InferTy, InferenceContext, TypeVarValue}; use crate::{ db::HirDatabase, lang_item::LangItemTarget, - resolve::Resolver, ty::{autoderef, Substs, Ty, TypeCtor, TypeWalk}, Adt, Mutability, }; +use super::{InferTy, InferenceContext, TypeVarValue}; + impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// Unify two types, but may coerce the first one to the second one /// using "implicit coercion rules" if needed. diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index 1ac2709f59c..ac570075f00 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -6,15 +6,14 @@ use hir_def::{ builtin_type::Signedness, path::{GenericArg, GenericArgs}, + resolver::resolver_for_expr, }; use hir_expand::name; -use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; use crate::{ db::HirDatabase, expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, generics::{GenericParams, HasGenericParams}, - resolve::resolver_for_expr, ty::{ autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, @@ -23,6 +22,8 @@ Adt, Name, }; +use super::{BindingMode, Expectation, InferenceContext, InferenceDiagnostic, TypeMismatch}; + impl<'a, D: HirDatabase> InferenceContext<'a, D> { pub(super) fn infer_expr(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { let ty = self.infer_expr_inner(tgt_expr, expected); diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 55a5dbec764..70136e514e2 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -1,16 +1,19 @@ //! Path expression resolution. -use hir_def::path::PathSegment; +use hir_def::{ + path::PathSegment, + resolver::{ResolveValueResult, Resolver, TypeNs, ValueNs}, +}; -use super::{ExprOrPatId, InferenceContext, TraitRef}; use crate::{ db::HirDatabase, generics::HasGenericParams, - resolve::{ResolveValueResult, Resolver, TypeNs, ValueNs}, ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, AssocItem, Container, Function, Name, Path, }; +use super::{ExprOrPatId, InferenceContext, TraitRef}; + impl<'a, D: HirDatabase> InferenceContext<'a, D> { pub(super) fn infer_path( &mut self, diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index e477b2439aa..c6ad0811b96 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -11,6 +11,7 @@ use hir_def::{ builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, path::{GenericArg, PathSegment}, + resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, GenericDefId, }; @@ -23,7 +24,6 @@ db::HirDatabase, generics::HasGenericParams, generics::{GenericDef, WherePredicate}, - resolve::{HasResolver, Resolver, TypeNs}, ty::{ primitive::{FloatTy, IntTy, Uncertain}, Adt, diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 5ad72ef9f57..64adb814d3f 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -5,11 +5,11 @@ use std::sync::Arc; use arrayvec::ArrayVec; +use hir_def::resolver::Resolver; use rustc_hash::FxHashMap; use crate::{ db::HirDatabase, - resolve::Resolver, ty::primitive::{FloatBitness, Uncertain}, ty::{Ty, TypeCtor}, AssocItem, Crate, Function, ImplBlock, Module, Mutability, Name, Trait, diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 0af41de879b..d579f5c7ea5 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -19,6 +19,7 @@ pub mod body; pub mod generics; pub mod traits; +pub mod resolver; #[cfg(test)] mod test_db; diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir_def/src/resolver.rs similarity index 92% rename from crates/ra_hir/src/resolve.rs rename to crates/ra_hir_def/src/resolver.rs index a616f0ea572..840785baa42 100644 --- a/crates/ra_hir/src/resolve.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -1,7 +1,14 @@ -//! Name resolution. +//! Name resolution façade. use std::sync::Arc; -use hir_def::{ +use hir_expand::{ + name::{self, Name}, + MacroDefId, +}; +use ra_db::CrateId; +use rustc_hash::FxHashSet; + +use crate::{ body::scope::{ExprScopes, ScopeId}, builtin_type::BuiltinType, db::DefDatabase2, @@ -13,15 +20,9 @@ FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, }; -use hir_expand::{ - name::{self, Name}, - MacroDefId, -}; -use ra_db::CrateId; -use rustc_hash::FxHashSet; #[derive(Debug, Clone, Default)] -pub(crate) struct Resolver { +pub struct Resolver { scopes: Vec, } @@ -54,7 +55,7 @@ pub(crate) enum Scope { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub(crate) enum TypeNs { +pub enum TypeNs { SelfType(ImplId), GenericParam(u32), AdtId(AdtId), @@ -69,13 +70,13 @@ pub(crate) enum TypeNs { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub(crate) enum ResolveValueResult { +pub enum ResolveValueResult { ValueNs(ValueNs), Partial(TypeNs, usize), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub(crate) enum ValueNs { +pub enum ValueNs { LocalBinding(PatId), FunctionId(FunctionId), ConstId(ConstId), @@ -86,11 +87,7 @@ pub(crate) enum ValueNs { impl Resolver { /// Resolve known trait from std, like `std::futures::Future` - pub(crate) fn resolve_known_trait( - &self, - db: &impl DefDatabase2, - path: &Path, - ) -> Option { + pub fn resolve_known_trait(&self, db: &impl DefDatabase2, path: &Path) -> Option { let res = self.resolve_module_path(db, path).take_types()?; match res { ModuleDefId::TraitId(it) => Some(it), @@ -99,11 +96,7 @@ pub(crate) fn resolve_known_trait( } /// Resolve known struct from std, like `std::boxed::Box` - pub(crate) fn resolve_known_struct( - &self, - db: &impl DefDatabase2, - path: &Path, - ) -> Option { + pub fn resolve_known_struct(&self, db: &impl DefDatabase2, path: &Path) -> Option { let res = self.resolve_module_path(db, path).take_types()?; match res { ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), @@ -112,7 +105,7 @@ pub(crate) fn resolve_known_struct( } /// Resolve known enum from std, like `std::result::Result` - pub(crate) fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option { + pub fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> Option { let res = self.resolve_module_path(db, path).take_types()?; match res { ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), @@ -121,7 +114,7 @@ pub(crate) fn resolve_known_enum(&self, db: &impl DefDatabase2, path: &Path) -> } /// pub only for source-binder - pub(crate) fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs { + pub fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> PerNs { let (item_map, module) = match self.module() { Some(it) => it, None => return PerNs::none(), @@ -133,7 +126,7 @@ pub(crate) fn resolve_module_path(&self, db: &impl DefDatabase2, path: &Path) -> module_res } - pub(crate) fn resolve_path_in_type_ns( + pub fn resolve_path_in_type_ns( &self, db: &impl DefDatabase2, path: &Path, @@ -189,7 +182,7 @@ pub(crate) fn resolve_path_in_type_ns( None } - pub(crate) fn resolve_path_in_type_ns_fully( + pub fn resolve_path_in_type_ns_fully( &self, db: &impl DefDatabase2, path: &Path, @@ -201,7 +194,7 @@ pub(crate) fn resolve_path_in_type_ns_fully( Some(res) } - pub(crate) fn resolve_path_in_value_ns<'p>( + pub fn resolve_path_in_value_ns<'p>( &self, db: &impl DefDatabase2, path: &'p Path, @@ -301,7 +294,7 @@ pub(crate) fn resolve_path_in_value_ns<'p>( None } - pub(crate) fn resolve_path_in_value_ns_fully( + pub fn resolve_path_in_value_ns_fully( &self, db: &impl DefDatabase2, path: &Path, @@ -312,26 +305,18 @@ pub(crate) fn resolve_path_in_value_ns_fully( } } - pub(crate) fn resolve_path_as_macro( - &self, - db: &impl DefDatabase2, - path: &Path, - ) -> Option { + pub fn resolve_path_as_macro(&self, db: &impl DefDatabase2, path: &Path) -> Option { let (item_map, module) = self.module()?; item_map.resolve_path(db, module, path).0.get_macros() } - pub(crate) fn process_all_names( - &self, - db: &impl DefDatabase2, - f: &mut dyn FnMut(Name, ScopeDef), - ) { + pub fn process_all_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef)) { for scope in self.scopes.iter().rev() { scope.process_names(db, f); } } - pub(crate) fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet { + pub fn traits_in_scope(&self, db: &impl DefDatabase2) -> FxHashSet { let mut traits = FxHashSet::default(); for scope in &self.scopes { if let Scope::ModuleScope(m) = scope { @@ -353,11 +338,11 @@ fn module(&self) -> Option<(&CrateDefMap, CrateModuleId)> { }) } - pub(crate) fn krate(&self) -> Option { + pub fn krate(&self) -> Option { self.module().map(|t| t.0.krate()) } - pub(crate) fn where_predicates_in_scope<'a>( + pub fn where_predicates_in_scope<'a>( &'a self, ) -> impl Iterator + 'a { self.scopes @@ -369,14 +354,14 @@ pub(crate) fn where_predicates_in_scope<'a>( .flat_map(|params| params.where_predicates.iter()) } - pub(crate) fn generic_def(&self) -> Option { + pub fn generic_def(&self) -> Option { self.scopes.iter().find_map(|scope| match scope { Scope::GenericParams { def, .. } => Some(*def), _ => None, }) } - pub(crate) fn body_owner(&self) -> Option { + pub fn body_owner(&self) -> Option { self.scopes.iter().find_map(|scope| match scope { Scope::ExprScope(it) => Some(it.owner), _ => None, @@ -425,7 +410,7 @@ pub(crate) fn push_expr_scope( } } -pub(crate) enum ScopeDef { +pub enum ScopeDef { PerNs(PerNs), ImplSelfType(ImplId), AdtSelfType(AdtId), @@ -481,7 +466,7 @@ fn process_names(&self, db: &impl DefDatabase2, f: &mut dyn FnMut(Name, ScopeDef } // needs arbitrary_self_types to be a method... or maybe move to the def? -pub(crate) fn resolver_for_expr( +pub fn resolver_for_expr( db: &impl DefDatabase2, owner: DefWithBodyId, expr_id: ExprId, @@ -490,7 +475,7 @@ pub(crate) fn resolver_for_expr( resolver_for_scope(db, owner, scopes.scope_for(expr_id)) } -pub(crate) fn resolver_for_scope( +pub fn resolver_for_scope( db: &impl DefDatabase2, owner: DefWithBodyId, scope_id: Option, @@ -504,7 +489,7 @@ pub(crate) fn resolver_for_scope( r } -pub(crate) trait HasResolver { +pub trait HasResolver { /// Builds a resolver for type references inside this def. fn resolver(self, db: &impl DefDatabase2) -> Resolver; } @@ -600,7 +585,7 @@ fn resolver(self, db: &impl DefDatabase2) -> Resolver { } impl HasResolver for GenericDefId { - fn resolver(self, db: &impl DefDatabase2) -> crate::Resolver { + fn resolver(self, db: &impl DefDatabase2) -> Resolver { match self { GenericDefId::FunctionId(inner) => inner.resolver(db), GenericDefId::AdtId(adt) => adt.resolver(db), From c37d1c5b381365ce2d07dfe4b871e43995ccea2d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 15:49:24 +0300 Subject: [PATCH 10/21] Restore a mark --- crates/ra_hir_def/src/body/lower.rs | 2 ++ crates/ra_hir_def/src/body/scope.rs | 18 +++++++++++++++++- crates/ra_hir_def/src/marks.rs | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index a5bb60e8576..77f09128871 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -12,6 +12,7 @@ }, AstNode, AstPtr, }; +use test_utils::tested_by; use crate::{ body::{Body, BodySourceMap, Expander, PatPtr}, @@ -153,6 +154,7 @@ fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { None => self.collect_expr_opt(condition.expr()), // if let -- desugar to match Some(pat) => { + tested_by!(infer_resolve_while_let); let pat = self.collect_pat(pat); let match_expr = self.collect_expr_opt(condition.expr()); let placeholder_pat = self.missing_pat(); diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index aeb71ff229f..5d7d1723118 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs @@ -174,7 +174,7 @@ mod tests { use hir_expand::{name::AsName, Source}; use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; - use test_utils::{assert_eq_text, extract_offset}; + use test_utils::{assert_eq_text, covers, extract_offset}; use crate::{db::DefDatabase2, test_db::TestDB, FunctionId, ModuleDefId}; @@ -382,4 +382,20 @@ fn foo() { 53, ); } + + #[test] + fn infer_resolve_while_let() { + covers!(infer_resolve_while_let); + do_check_local_name( + r#" +fn test() { + let foo: Option = None; + while let Option::Some(spam) = foo { + spam<|> + } +} +"#, + 75, + ); + } } diff --git a/crates/ra_hir_def/src/marks.rs b/crates/ra_hir_def/src/marks.rs index 0b99eac7174..65239ca0a48 100644 --- a/crates/ra_hir_def/src/marks.rs +++ b/crates/ra_hir_def/src/marks.rs @@ -11,4 +11,5 @@ prelude_is_macro_use macro_dollar_crate_self macro_dollar_crate_other + infer_resolve_while_let ); From 36758f2767f173863039963c44791ac6c4080ab2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 15:56:27 +0300 Subject: [PATCH 11/21] Resimplify --- crates/ra_hir_def/src/resolver.rs | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 840785baa42..1bc9c176076 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -18,7 +18,7 @@ path::{Path, PathKind}, AdtId, AstItemDef, ConstId, ContainerId, CrateModuleId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, ImplId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, - TypeAliasId, UnionId, + TypeAliasId, }; #[derive(Debug, Clone, Default)] @@ -507,9 +507,10 @@ fn resolver(self, db: &impl DefDatabase2) -> Resolver { } } -impl HasResolver for AdtId { +impl> HasResolver for T { fn resolver(self, db: &impl DefDatabase2) -> Resolver { - let module = match self { + let def = self.into(); + let module = match def { AdtId::StructId(it) => it.0.module(db), AdtId::UnionId(it) => it.0.module(db), AdtId::EnumId(it) => it.module(db), @@ -517,26 +518,8 @@ fn resolver(self, db: &impl DefDatabase2) -> Resolver { module .resolver(db) - .push_generic_params_scope(db, self.into()) - .push_scope(Scope::AdtScope(self.into())) - } -} - -impl HasResolver for StructId { - fn resolver(self, db: &impl DefDatabase2) -> Resolver { - AdtId::from(self).resolver(db) - } -} - -impl HasResolver for UnionId { - fn resolver(self, db: &impl DefDatabase2) -> Resolver { - AdtId::from(self).resolver(db) - } -} - -impl HasResolver for EnumId { - fn resolver(self, db: &impl DefDatabase2) -> Resolver { - AdtId::from(self).resolver(db) + .push_generic_params_scope(db, def.into()) + .push_scope(Scope::AdtScope(def)) } } From 4f8f3393bc3dd9a480319a1b9d66c0778ab30b1e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 16:00:57 +0300 Subject: [PATCH 12/21] Reduce visibility --- crates/ra_hir_def/src/resolver.rs | 78 +++++++++++++++---------------- 1 file changed, 37 insertions(+), 41 deletions(-) diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 1bc9c176076..7b5c3ec0618 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -369,47 +369,6 @@ pub fn body_owner(&self) -> Option { } } -impl Resolver { - pub(crate) fn push_scope(mut self, scope: Scope) -> Resolver { - self.scopes.push(scope); - self - } - - pub(crate) fn push_generic_params_scope( - self, - db: &impl DefDatabase2, - def: GenericDefId, - ) -> Resolver { - let params = db.generic_params(def); - if params.params.is_empty() { - self - } else { - self.push_scope(Scope::GenericParams { def, params }) - } - } - - pub(crate) fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver { - self.push_scope(Scope::ImplBlockScope(impl_block)) - } - - pub(crate) fn push_module_scope( - self, - crate_def_map: Arc, - module_id: CrateModuleId, - ) -> Resolver { - self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) - } - - pub(crate) fn push_expr_scope( - self, - owner: DefWithBodyId, - expr_scopes: Arc, - scope_id: ScopeId, - ) -> Resolver { - self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) - } -} - pub enum ScopeDef { PerNs(PerNs), ImplSelfType(ImplId), @@ -489,6 +448,43 @@ pub fn resolver_for_scope( r } +impl Resolver { + fn push_scope(mut self, scope: Scope) -> Resolver { + self.scopes.push(scope); + self + } + + fn push_generic_params_scope(self, db: &impl DefDatabase2, def: GenericDefId) -> Resolver { + let params = db.generic_params(def); + if params.params.is_empty() { + self + } else { + self.push_scope(Scope::GenericParams { def, params }) + } + } + + fn push_impl_block_scope(self, impl_block: ImplId) -> Resolver { + self.push_scope(Scope::ImplBlockScope(impl_block)) + } + + fn push_module_scope( + self, + crate_def_map: Arc, + module_id: CrateModuleId, + ) -> Resolver { + self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) + } + + fn push_expr_scope( + self, + owner: DefWithBodyId, + expr_scopes: Arc, + scope_id: ScopeId, + ) -> Resolver { + self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) + } +} + pub trait HasResolver { /// Builds a resolver for type references inside this def. fn resolver(self, db: &impl DefDatabase2) -> Resolver; From 4daf931111029cee9bb43691f88c32f0aa47a802 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 16:23:02 +0300 Subject: [PATCH 13/21] Remove old hir::generics module --- crates/ra_hir/src/code_model.rs | 46 +++++++++++++++++------- crates/ra_hir/src/db.rs | 5 ++- crates/ra_hir/src/from_id.rs | 17 +++++++-- crates/ra_hir/src/generics.rs | 54 ---------------------------- crates/ra_hir/src/lib.rs | 3 +- crates/ra_hir/src/ty.rs | 22 ++++++------ crates/ra_hir/src/ty/autoderef.rs | 4 +-- crates/ra_hir/src/ty/infer/expr.rs | 8 +++-- crates/ra_hir/src/ty/infer/path.rs | 3 +- crates/ra_hir/src/ty/lower.rs | 33 ++++++++--------- crates/ra_hir/src/ty/traits/chalk.rs | 13 ++++--- 11 files changed, 94 insertions(+), 114 deletions(-) delete mode 100644 crates/ra_hir/src/generics.rs diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 92860fb598d..5690040a757 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs @@ -27,7 +27,6 @@ use crate::{ db::{AstDatabase, DefDatabase, HirDatabase}, expr::{BindingAnnotation, Body, BodySourceMap, ExprValidator, Pat, PatId}, - generics::{GenericDef, HasGenericParams}, ids::{ AstItemDef, ConstId, EnumId, FunctionId, MacroDefId, StaticId, StructId, TraitId, TypeAliasId, @@ -835,7 +834,7 @@ fn direct_super_traits(self, db: &impl HirDatabase) -> Vec { // lifetime problems, but since there usually shouldn't be more than a // few direct traits this should be fine (we could even use some kind of // SmallVec if performance is a concern) - self.generic_params(db) + db.generic_params(self.id.into()) .where_predicates .iter() .filter_map(|pred| match &pred.type_ref { @@ -975,16 +974,6 @@ pub enum AssocItem { // casting them, and somehow making the constructors private, which would be annoying. impl_froms!(AssocItem: Function, Const, TypeAlias); -impl From for crate::generics::GenericDef { - fn from(item: AssocItem) -> Self { - match item { - AssocItem::Function(f) => f.into(), - AssocItem::Const(c) => c.into(), - AssocItem::TypeAlias(t) => t.into(), - } - } -} - impl AssocItem { pub fn module(self, db: &impl DefDatabase) -> Module { match self { @@ -1004,6 +993,39 @@ pub fn container(self, db: &impl DefDatabase) -> Container { } } +#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] +pub enum GenericDef { + Function(Function), + Adt(Adt), + Trait(Trait), + TypeAlias(TypeAlias), + ImplBlock(ImplBlock), + // enum variants cannot have generics themselves, but their parent enums + // can, and this makes some code easier to write + EnumVariant(EnumVariant), + // consts can have type parameters from their parents (i.e. associated consts of traits) + Const(Const), +} +impl_froms!( + GenericDef: Function, + Adt(Struct, Enum, Union), + Trait, + TypeAlias, + ImplBlock, + EnumVariant, + Const +); + +impl From for GenericDef { + fn from(item: AssocItem) -> Self { + match item { + AssocItem::Function(f) => f.into(), + AssocItem::Const(c) => c.into(), + AssocItem::TypeAlias(t) => t.into(), + } + } +} + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct Local { pub(crate) parent: DefWithBody, diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index a9982a70f6d..ed0d680011e 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs @@ -8,7 +8,6 @@ use crate::{ debug::HirDebugDatabase, - generics::GenericDef, ids, lang_item::{LangItemTarget, LangItems}, ty::{ @@ -18,8 +17,8 @@ TypeCtor, }, type_alias::TypeAliasData, - Const, ConstData, Crate, DefWithBody, FnData, Function, ImplBlock, Module, Static, StructField, - Trait, TypeAlias, + Const, ConstData, Crate, DefWithBody, FnData, Function, GenericDef, ImplBlock, Module, Static, + StructField, Trait, TypeAlias, }; pub use hir_def::db::{ diff --git a/crates/ra_hir/src/from_id.rs b/crates/ra_hir/src/from_id.rs index a3e9d8525f2..e8ed04056a7 100644 --- a/crates/ra_hir/src/from_id.rs +++ b/crates/ra_hir/src/from_id.rs @@ -9,8 +9,9 @@ }; use crate::{ - ty::TypableDef, Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, - ModuleDef, Static, TypeAlias, + ty::{CallableDef, TypableDef}, + Adt, AssocItem, Const, Crate, DefWithBody, EnumVariant, Function, GenericDef, ModuleDef, + Static, TypeAlias, }; impl From for Crate { @@ -206,3 +207,15 @@ fn from(id: Adt) -> Self { } } } + +impl From for GenericDefId { + fn from(def: CallableDef) -> Self { + match def { + CallableDef::Function(it) => it.id.into(), + CallableDef::Struct(it) => it.id.into(), + CallableDef::EnumVariant(it) => { + EnumVariantId { parent: it.parent.id, local_id: it.id }.into() + } + } + } +} diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs deleted file mode 100644 index f1bf2ee9d19..00000000000 --- a/crates/ra_hir/src/generics.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! Temp module to wrap hir_def::generics -use std::sync::Arc; - -use crate::{ - db::DefDatabase, Adt, Const, Container, Enum, EnumVariant, Function, ImplBlock, Struct, Trait, - TypeAlias, Union, -}; - -pub use hir_def::generics::{GenericParam, GenericParams, WherePredicate}; - -#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] -pub enum GenericDef { - Function(Function), - Adt(Adt), - Trait(Trait), - TypeAlias(TypeAlias), - ImplBlock(ImplBlock), - // enum variants cannot have generics themselves, but their parent enums - // can, and this makes some code easier to write - EnumVariant(EnumVariant), - // consts can have type parameters from their parents (i.e. associated consts of traits) - Const(Const), -} -impl_froms!( - GenericDef: Function, - Adt(Struct, Enum, Union), - Trait, - TypeAlias, - ImplBlock, - EnumVariant, - Const -); - -impl From for GenericDef { - fn from(c: Container) -> Self { - match c { - Container::Trait(trait_) => trait_.into(), - Container::ImplBlock(impl_block) => impl_block.into(), - } - } -} - -pub trait HasGenericParams: Copy { - fn generic_params(self, db: &impl DefDatabase) -> Arc; -} - -impl HasGenericParams for T -where - T: Into + Copy, -{ - fn generic_params(self, db: &impl DefDatabase) -> Arc { - db.generic_params(self.into().into()) - } -} diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 76c96bdcfb3..4be49856ca6 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -37,7 +37,6 @@ fn from(it: $sv) -> $e { mod impl_block; mod expr; mod lang_item; -pub mod generics; pub mod diagnostics; mod util; @@ -60,10 +59,10 @@ fn from(it: $sv) -> $e { EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef, + GenericDef }, expr::ExprScopes, from_source::FromSource, - generics::GenericDef, ids::{HirFileId, MacroCallId, MacroCallLoc, MacroDefId, MacroFile}, source_binder::{PathResolution, ScopeEntryWithSyntax, SourceAnalyzer}, ty::{ diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 36ece723f23..95b8df18105 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -17,12 +17,11 @@ use std::sync::Arc; use std::{fmt, iter, mem}; +use hir_def::{generics::GenericParams, AdtId}; + use crate::{ - db::HirDatabase, - expr::ExprId, - generics::{GenericParams, HasGenericParams}, - util::make_mut_slice, - Adt, Crate, DefWithBody, FloatTy, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, + db::HirDatabase, expr::ExprId, util::make_mut_slice, Adt, Crate, DefWithBody, FloatTy, + GenericDef, IntTy, Mutability, Name, Trait, TypeAlias, Uncertain, }; use display::{HirDisplay, HirFormatter}; @@ -131,15 +130,15 @@ pub fn num_ty_params(self, db: &impl HirDatabase) -> usize { | TypeCtor::Closure { .. } // 1 param representing the signature of the closure => 1, TypeCtor::Adt(adt) => { - let generic_params = adt.generic_params(db); + let generic_params = db.generic_params(AdtId::from(adt).into()); generic_params.count_params_including_parent() } TypeCtor::FnDef(callable) => { - let generic_params = callable.generic_params(db); + let generic_params = db.generic_params(callable.into()); generic_params.count_params_including_parent() } TypeCtor::AssociatedType(type_alias) => { - let generic_params = type_alias.generic_params(db); + let generic_params = db.generic_params(type_alias.id.into()); generic_params.count_params_including_parent() } TypeCtor::FnPtr { num_args } => num_args as usize + 1, @@ -168,7 +167,7 @@ pub fn krate(self, db: &impl HirDatabase) -> Option { } } - pub fn as_generic_def(self) -> Option { + pub fn as_generic_def(self) -> Option { match self { TypeCtor::Bool | TypeCtor::Char @@ -348,8 +347,9 @@ pub fn bound_vars(generic_params: &GenericParams) -> Substs { ) } - pub fn build_for_def(db: &impl HirDatabase, def: impl HasGenericParams) -> SubstsBuilder { - let params = def.generic_params(db); + pub fn build_for_def(db: &impl HirDatabase, def: impl Into) -> SubstsBuilder { + let def = def.into(); + let params = db.generic_params(def.into()); let param_count = params.count_params_including_parent(); Substs::builder(param_count) } diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 5d8518041fd..33ac782fe99 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -10,7 +10,7 @@ use log::{info, warn}; use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; -use crate::{db::HirDatabase, generics::HasGenericParams}; +use crate::{db::HirDatabase}; const AUTODEREF_RECURSION_LIMIT: usize = 10; @@ -46,7 +46,7 @@ fn deref_by_trait( }; let target = deref_trait.associated_type_by_name(db, &name::TARGET_TYPE)?; - let generic_params = target.generic_params(db); + let generic_params = db.generic_params(target.id.into()); if generic_params.count_params_including_parent() != 1 { // the Target type + Deref trait should only have one generic parameter, // namely Deref's Self type diff --git a/crates/ra_hir/src/ty/infer/expr.rs b/crates/ra_hir/src/ty/infer/expr.rs index ac570075f00..20a7e93525e 100644 --- a/crates/ra_hir/src/ty/infer/expr.rs +++ b/crates/ra_hir/src/ty/infer/expr.rs @@ -5,6 +5,7 @@ use hir_def::{ builtin_type::Signedness, + generics::GenericParams, path::{GenericArg, GenericArgs}, resolver::resolver_for_expr, }; @@ -13,7 +14,6 @@ use crate::{ db::HirDatabase, expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, - generics::{GenericParams, HasGenericParams}, ty::{ autoderef, method_resolution, op, CallableDef, InferTy, IntTy, Mutability, Namespace, Obligation, ProjectionPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk, @@ -534,7 +534,7 @@ fn infer_method_call( ( ty, self.db.type_for_def(func.into(), Namespace::Values), - Some(func.generic_params(self.db)), + Some(self.db.generic_params(func.id.into())), ) } None => (receiver_ty, Ty::Unknown, None), @@ -645,7 +645,9 @@ fn register_obligations_for_call(&mut self, callable_ty: &Ty) { if let Some(trait_) = f.parent_trait(self.db) { // construct a TraitDef let substs = a_ty.parameters.prefix( - trait_.generic_params(self.db).count_params_including_parent(), + self.db + .generic_params(trait_.id.into()) + .count_params_including_parent(), ); self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); } diff --git a/crates/ra_hir/src/ty/infer/path.rs b/crates/ra_hir/src/ty/infer/path.rs index 70136e514e2..ee54d821738 100644 --- a/crates/ra_hir/src/ty/infer/path.rs +++ b/crates/ra_hir/src/ty/infer/path.rs @@ -7,7 +7,6 @@ use crate::{ db::HirDatabase, - generics::HasGenericParams, ty::{method_resolution, Namespace, Substs, Ty, TypableDef, TypeWalk}, AssocItem, Container, Function, Name, Path, }; @@ -230,7 +229,7 @@ fn find_self_types(&self, def: &ValueNs, actual_def_ty: Ty) -> Option { if let ValueNs::FunctionId(func) = def { let func = Function::from(*func); // We only do the infer if parent has generic params - let gen = func.generic_params(self.db); + let gen = self.db.generic_params(func.id.into()); if gen.count_parent_params() == 0 { return None; } diff --git a/crates/ra_hir/src/ty/lower.rs b/crates/ra_hir/src/ty/lower.rs index c6ad0811b96..75c55256929 100644 --- a/crates/ra_hir/src/ty/lower.rs +++ b/crates/ra_hir/src/ty/lower.rs @@ -10,10 +10,11 @@ use hir_def::{ builtin_type::{BuiltinFloat, BuiltinInt, BuiltinType}, + generics::WherePredicate, path::{GenericArg, PathSegment}, resolver::{HasResolver, Resolver, TypeNs}, type_ref::{TypeBound, TypeRef}, - GenericDefId, + AdtId, GenericDefId, }; use super::{ @@ -22,15 +23,13 @@ }; use crate::{ db::HirDatabase, - generics::HasGenericParams, - generics::{GenericDef, WherePredicate}, ty::{ primitive::{FloatTy, IntTy, Uncertain}, Adt, }, util::make_mut_slice, - Const, Enum, EnumVariant, Function, ImplBlock, ModuleDef, Path, Static, Struct, StructField, - Trait, TypeAlias, Union, VariantDef, + Const, Enum, EnumVariant, Function, GenericDef, ImplBlock, ModuleDef, Path, Static, Struct, + StructField, Trait, TypeAlias, Union, VariantDef, }; // FIXME: this is only really used in `type_for_def`, which contains a bunch of @@ -342,7 +341,7 @@ pub(super) fn substs_from_path_segment( add_self_param: bool, ) -> Substs { let mut substs = Vec::new(); - let def_generics = def_generic.map(|def| def.generic_params(db)); + let def_generics = def_generic.map(|def| db.generic_params(def.into())); let (parent_param_count, param_count) = def_generics.map_or((0, 0), |g| (g.count_parent_params(), g.params.len())); @@ -443,7 +442,7 @@ fn substs_from_path( } pub(crate) fn for_trait(db: &impl HirDatabase, trait_: Trait) -> TraitRef { - let substs = Substs::identity(&trait_.generic_params(db)); + let substs = Substs::identity(&db.generic_params(trait_.id.into())); TraitRef { trait_, substs } } @@ -611,7 +610,7 @@ pub(crate) fn generic_predicates_query( /// Resolve the default type params from generics pub(crate) fn generic_defaults_query(db: &impl HirDatabase, def: GenericDef) -> Substs { let resolver = GenericDefId::from(def).resolver(db); - let generic_params = def.generic_params(db); + let generic_params = db.generic_params(def.into()); let defaults = generic_params .params_including_parent() @@ -633,7 +632,7 @@ fn fn_sig_for_fn(db: &impl HirDatabase, def: Function) -> FnSig { /// Build the declared type of a function. This should not need to look at the /// function body. fn type_for_fn(db: &impl HirDatabase, def: Function) -> Ty { - let generics = def.generic_params(db); + let generics = db.generic_params(def.id.into()); let substs = Substs::identity(&generics); Ty::apply(TypeCtor::FnDef(def.into()), substs) } @@ -716,7 +715,7 @@ fn type_for_struct_constructor(db: &impl HirDatabase, def: Struct) -> Ty { if struct_data.variant_data.fields().is_none() { return type_for_adt(db, def); // Unit struct } - let generics = def.generic_params(db); + let generics = db.generic_params(def.id.into()); let substs = Substs::identity(&generics); Ty::apply(TypeCtor::FnDef(def.into()), substs) } @@ -732,7 +731,7 @@ fn fn_sig_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) .iter() .map(|(_, field)| Ty::from_hir(db, &resolver, &field.type_ref)) .collect::>(); - let generics = def.parent_enum(db).generic_params(db); + let generics = db.generic_params(def.parent_enum(db).id.into()); let substs = Substs::identity(&generics); let ret = type_for_adt(db, def.parent_enum(db)).subst(&substs); FnSig::from_params_and_return(params, ret) @@ -744,18 +743,20 @@ fn type_for_enum_variant_constructor(db: &impl HirDatabase, def: EnumVariant) -> if var_data.fields().is_none() { return type_for_adt(db, def.parent_enum(db)); // Unit variant } - let generics = def.parent_enum(db).generic_params(db); + let generics = db.generic_params(def.parent_enum(db).id.into()); let substs = Substs::identity(&generics); Ty::apply(TypeCtor::FnDef(def.into()), substs) } -fn type_for_adt(db: &impl HirDatabase, adt: impl Into + HasGenericParams) -> Ty { - let generics = adt.generic_params(db); - Ty::apply(TypeCtor::Adt(adt.into()), Substs::identity(&generics)) +fn type_for_adt(db: &impl HirDatabase, adt: impl Into) -> Ty { + let adt = adt.into(); + let adt_id: AdtId = adt.into(); + let generics = db.generic_params(adt_id.into()); + Ty::apply(TypeCtor::Adt(adt), Substs::identity(&generics)) } fn type_for_type_alias(db: &impl HirDatabase, t: TypeAlias) -> Ty { - let generics = t.generic_params(db); + let generics = db.generic_params(t.id.into()); let resolver = t.id.resolver(db); let type_ref = t.type_ref(db); let substs = Substs::identity(&generics); diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 9bf93981a08..88785f30503 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs @@ -16,10 +16,9 @@ use super::{AssocTyValue, Canonical, ChalkContext, Impl, Obligation}; use crate::{ db::HirDatabase, - generics::{GenericDef, HasGenericParams}, ty::display::HirDisplay, ty::{ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor, TypeWalk}, - Crate, HasBody, ImplBlock, Trait, TypeAlias, + Crate, GenericDef, HasBody, ImplBlock, Trait, TypeAlias, }; /// This represents a trait whose name we could not resolve. @@ -509,7 +508,7 @@ pub(crate) fn associated_ty_data_query( Some(crate::Container::Trait(t)) => t, _ => panic!("associated type not in trait"), }; - let generic_params = type_alias.generic_params(db); + let generic_params = db.generic_params(type_alias.id.into()); let bound_data = chalk_rust_ir::AssociatedTyDatumBound { // FIXME add bounds and where clauses bounds: vec![], @@ -550,7 +549,7 @@ pub(crate) fn trait_datum_query( } let trait_: Trait = from_chalk(db, trait_id); debug!("trait {:?} = {:?}", trait_id, trait_.name(db)); - let generic_params = trait_.generic_params(db); + let generic_params = db.generic_params(trait_.id.into()); let bound_vars = Substs::bound_vars(&generic_params); let flags = chalk_rust_ir::TraitFlags { auto: trait_.is_auto(db), @@ -594,7 +593,7 @@ pub(crate) fn struct_datum_query( let where_clauses = type_ctor .as_generic_def() .map(|generic_def| { - let generic_params = generic_def.generic_params(db); + let generic_params = db.generic_params(generic_def.into()); let bound_vars = Substs::bound_vars(&generic_params); convert_where_clauses(db, generic_def, &bound_vars) }) @@ -634,7 +633,7 @@ fn impl_block_datum( impl_id: ImplId, impl_block: ImplBlock, ) -> Option>> { - let generic_params = impl_block.generic_params(db); + let generic_params = db.generic_params(impl_block.id.into()); let bound_vars = Substs::bound_vars(&generic_params); let trait_ref = impl_block.target_trait_ref(db)?.subst(&bound_vars); let trait_ = trait_ref.trait_; @@ -786,7 +785,7 @@ fn type_alias_associated_ty_value( let assoc_ty = trait_ .associated_type_by_name(db, &type_alias.name(db)) .expect("assoc ty value should not exist"); // validated when building the impl data as well - let generic_params = impl_block.generic_params(db); + let generic_params = db.generic_params(impl_block.id.into()); let bound_vars = Substs::bound_vars(&generic_params); let ty = db.type_for_def(type_alias.into(), crate::ty::Namespace::Types).subst(&bound_vars); let value_bound = chalk_rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) }; From 952405cb4180993af0f5c939d5276dbdf2a19152 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 16:31:48 +0300 Subject: [PATCH 14/21] reformat --- crates/ra_hir/src/lib.rs | 7 +++---- crates/ra_hir/src/ty/autoderef.rs | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 4be49856ca6..8c6834392df 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs @@ -56,10 +56,9 @@ fn from(it: $sv) -> $e { docs::{DocDef, Docs, Documentation}, src::{HasBodySource, HasSource}, Adt, AssocItem, Const, ConstData, Container, Crate, CrateDependency, DefWithBody, Enum, - EnumVariant, FieldSource, FnData, Function, GenericParam, HasBody, ImplBlock, Local, - MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, Trait, - TypeAlias, Union, VariantDef, - GenericDef + EnumVariant, FieldSource, FnData, Function, GenericDef, GenericParam, HasBody, ImplBlock, + Local, MacroDef, Module, ModuleDef, ModuleSource, ScopeDef, Static, Struct, StructField, + Trait, TypeAlias, Union, VariantDef, }, expr::ExprScopes, from_source::FromSource, diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 33ac782fe99..b60e4bb3119 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs @@ -10,7 +10,7 @@ use log::{info, warn}; use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; -use crate::{db::HirDatabase}; +use crate::db::HirDatabase; const AUTODEREF_RECURSION_LIMIT: usize = 10; From aa20740944b7466a2f77781115ce948c3bf1866a Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Thu, 21 Nov 2019 08:40:33 -0500 Subject: [PATCH 15/21] Update crates --- Cargo.lock | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef373519726..8f7783deb9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,7 +10,7 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.19" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -274,14 +274,6 @@ dependencies = [ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-queue" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-queue" version = "0.2.0" @@ -290,15 +282,6 @@ dependencies = [ "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crossbeam-utils" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "crossbeam-utils" version = "0.7.0" @@ -1092,7 +1075,7 @@ dependencies = [ "ra_syntax 0.1.0", "ra_text_edit 0.1.0", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "test_utils 0.1.0", @@ -1371,22 +1354,22 @@ dependencies = [ [[package]] name = "rayon" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rayon-core" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1833,7 +1816,7 @@ dependencies = [ name = "xtask" version = "0.1.0" dependencies = [ - "anyhow 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)", + "anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)", "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1857,7 +1840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" -"checksum anyhow 1.0.19 (registry+https://github.com/rust-lang/crates.io-index)" = "57114fc2a6cc374bce195d3482057c846e706d252ff3604363449695684d7a0d" +"checksum anyhow 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "e19f23ab207147bbdbcdfa7f7e4ca5e84963d79bae3937074682177ab9150968" "checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" "checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" @@ -1887,9 +1870,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" "checksum crossbeam-deque 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3aa945d63861bfe624b55d153a39684da1e8c0bc8fba932f7ee3a3c16cea3ca" "checksum crossbeam-epoch 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac" -"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b" "checksum crossbeam-queue 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" -"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6" "checksum crossbeam-utils 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4" "checksum derive-new 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" @@ -1984,8 +1965,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" "checksum rand_pcg 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rayon 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "83a27732a533a1be0a0035a111fe76db89ad312f6f0347004c220c57f209a123" -"checksum rayon-core 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "98dcf634205083b17d0861252431eb2acbfb698ab7478a2d20de07954f47ec7b" +"checksum rayon 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd" +"checksum rayon-core 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791" "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" From a1346bba5c457d1aa0a35f44231bed8b494b7d60 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 21 Nov 2019 17:09:38 +0300 Subject: [PATCH 16/21] Fix test mark placement --- crates/ra_hir_def/src/body/lower.rs | 2 +- crates/ra_hir_def/src/body/scope.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 77f09128871..d8e911aa521 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -154,7 +154,6 @@ fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { None => self.collect_expr_opt(condition.expr()), // if let -- desugar to match Some(pat) => { - tested_by!(infer_resolve_while_let); let pat = self.collect_pat(pat); let match_expr = self.collect_expr_opt(condition.expr()); let placeholder_pat = self.missing_pat(); @@ -192,6 +191,7 @@ fn collect_expr(&mut self, expr: ast::Expr) -> ExprId { None => self.collect_expr_opt(condition.expr()), // if let -- desugar to match Some(pat) => { + tested_by!(infer_resolve_while_let); let pat = self.collect_pat(pat); let match_expr = self.collect_expr_opt(condition.expr()); let placeholder_pat = self.missing_pat(); diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 5d7d1723118..58740b679dc 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs @@ -384,7 +384,7 @@ fn foo() { } #[test] - fn infer_resolve_while_let() { + fn while_let_desugaring() { covers!(infer_resolve_while_let); do_check_local_name( r#" From bf537eefb5dd05894344d49abf8598e5f67f3abf Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 21 Nov 2019 23:56:01 +0800 Subject: [PATCH 17/21] Fixed mbe trival subtree --- crates/ra_mbe/src/syntax_bridge.rs | 68 ++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index d1c49c0b3f3..1de399fee45 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs @@ -5,6 +5,7 @@ ast, AstNode, AstToken, NodeOrToken, Parse, SmolStr, SyntaxKind, SyntaxKind::*, SyntaxNode, SyntaxTreeBuilder, TextRange, TextUnit, T, }; +use std::iter::successors; use tt::buffer::{Cursor, TokenBuffer}; use crate::subtree_source::SubtreeTokenSource; @@ -160,6 +161,31 @@ fn go(&mut self, tt: &SyntaxNode) -> Option { let first_child = tt.first_child_or_token()?; let last_child = tt.last_child_or_token()?; + + // ignore trivial first_child and last_child + let first_child = successors(Some(first_child), |it| { + if it.kind().is_trivia() { + it.next_sibling_or_token() + } else { + None + } + }) + .last() + .unwrap(); + if first_child.kind().is_trivia() { + return Some(tt::Subtree { token_trees: vec![], delimiter: tt::Delimiter::None }); + } + + let last_child = successors(Some(last_child), |it| { + if it.kind().is_trivia() { + it.prev_sibling_or_token() + } else { + None + } + }) + .last() + .unwrap(); + let (delimiter, skip_first) = match (first_child.kind(), last_child.kind()) { (T!['('], T![')']) => (tt::Delimiter::Parenthesis, true), (T!['{'], T!['}']) => (tt::Delimiter::Brace, true), @@ -363,6 +389,7 @@ mod tests { use super::*; use crate::tests::{create_rules, expand}; use ra_parser::TokenSource; + use ra_syntax::algo::{insert_children, InsertPosition}; #[test] fn convert_tt_token_source() { @@ -423,4 +450,45 @@ macro_rules! stmts { let expansion = expand(&rules, "stmts!();"); assert!(token_tree_to_syntax_node(&expansion, FragmentKind::Expr).is_err()); } + + #[test] + fn test_token_tree_last_child_is_white_space() { + let source_file = ast::SourceFile::parse("f!({} );").ok().unwrap(); + let macro_call = source_file.syntax().descendants().find_map(ast::MacroCall::cast).unwrap(); + let token_tree = macro_call.token_tree().unwrap(); + + // Token Tree now is : + // TokenTree + // - T!['('] + // - TokenTree + // - T!['{'] + // - T!['}'] + // - WHITE_SPACE + // - T![')'] + + let rbrace = + token_tree.syntax().descendants_with_tokens().find(|it| it.kind() == T!['}']).unwrap(); + let space = token_tree + .syntax() + .descendants_with_tokens() + .find(|it| it.kind() == SyntaxKind::WHITESPACE) + .unwrap(); + + // reorder th white space, such that the white is inside the inner token-tree. + let token_tree = insert_children( + &rbrace.parent().unwrap(), + InsertPosition::Last, + &mut std::iter::once(space), + ); + + // Token Tree now is : + // TokenTree + // - T!['{'] + // - T!['}'] + // - WHITE_SPACE + let token_tree = ast::TokenTree::cast(token_tree).unwrap(); + let tt = ast_to_token_tree(&token_tree).unwrap().0; + + assert_eq!(tt.delimiter, tt::Delimiter::Brace); + } } From 4ff400833f860fb5db8adb1b999343b1fb4e3ccb Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 22 Nov 2019 02:34:06 +0800 Subject: [PATCH 18/21] Add MacroFileKind::Statements --- crates/ra_hir_expand/src/db.rs | 1 + crates/ra_hir_expand/src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index 3c11c8a2281..e1d93a8ef53 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs @@ -151,6 +151,7 @@ pub(crate) fn parse_macro( let fragment_kind = match macro_file.macro_file_kind { MacroFileKind::Items => FragmentKind::Items, MacroFileKind::Expr => FragmentKind::Expr, + MacroFileKind::Statements => FragmentKind::Statements, }; let (parse, rev_token_map) = mbe::token_tree_to_syntax_node(&tt, fragment_kind).ok()?; Some((parse, Arc::new(rev_token_map))) diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 1389f64ce96..126d12fbbed 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs @@ -109,6 +109,7 @@ pub struct MacroFile { pub enum MacroFileKind { Items, Expr, + Statements, } /// `MacroCallId` identifies a particular macro invocation, like From 59e7234546590d9fe639ecebab4a768c02ca6389 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 22 Nov 2019 02:34:49 +0800 Subject: [PATCH 19/21] Add to_macro_file_kind --- crates/ra_hir/src/source_binder.rs | 40 ++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index c42ceabdfc3..797f90d501b 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs @@ -131,6 +131,7 @@ pub struct ReferenceDescriptor { } pub struct Expansion { + macro_file_kind: MacroFileKind, macro_call_id: MacroCallId, } @@ -145,7 +146,7 @@ pub fn map_token_down( } pub fn file_id(&self) -> HirFileId { - self.macro_call_id.as_file(MacroFileKind::Items) + self.macro_call_id.as_file(self.macro_file_kind) } } @@ -439,7 +440,10 @@ pub fn expand( db.ast_id_map(macro_call.file_id).ast_id(macro_call.value), ); let macro_call_loc = MacroCallLoc { def, ast_id }; - Some(Expansion { macro_call_id: db.intern_macro(macro_call_loc) }) + Some(Expansion { + macro_call_id: db.intern_macro(macro_call_loc), + macro_file_kind: to_macro_file_kind(macro_call.value), + }) } #[cfg(test)] @@ -538,3 +542,35 @@ fn adjust( }) .map(|(_ptr, scope)| *scope) } + +/// Given a `ast::MacroCall`, return what `MacroKindFile` it belongs to. +/// FIXME: Not completed +fn to_macro_file_kind(macro_call: &ast::MacroCall) -> MacroFileKind { + let syn = macro_call.syntax(); + let parent = match syn.parent() { + Some(it) => it, + None => { + // FIXME: + // If it is root, which means the parent HirFile + // MacroKindFile must be non-items + // return expr now. + return MacroFileKind::Expr; + } + }; + + match parent.kind() { + MACRO_ITEMS | SOURCE_FILE => MacroFileKind::Items, + LET_STMT => { + // FIXME: Handle Pattern + MacroFileKind::Expr + } + EXPR_STMT => MacroFileKind::Statements, + BLOCK => MacroFileKind::Statements, + ARG_LIST => MacroFileKind::Expr, + TRY_EXPR => MacroFileKind::Expr, + _ => { + // Unknown , Just guess it is `Items` + MacroFileKind::Items + } + } +} From 67a58e4af16996c79eacabd5f6d80792f0c17cfd Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 22 Nov 2019 02:35:30 +0800 Subject: [PATCH 20/21] Add test for match_ast --- crates/ra_ide_api/src/expand_macro.rs | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 7f39262dc93..789d6cbde9c 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs @@ -173,6 +173,49 @@ fn some_thing() -> u32 { let a = 0; a+10 } +"###); + } + + #[test] + fn macro_expand_match_ast() { + let res = check_expand_macro( + r#" + //- /lib.rs + macro_rules! match_ast { + (match $node:ident { $($tt:tt)* }) => { match_ast!(match ($node) { $($tt)* }) }; + + (match ($node:expr) { + $( ast::$ast:ident($it:ident) => $res:block, )* + _ => $catch_all:expr $(,)? + }) => {{ + $( if let Some($it) = ast::$ast::cast($node.clone()) $res else )* + { $catch_all } + }}; + } + + fn main() { + mat<|>ch_ast! { + match container { + ast::TraitDef(it) => {}, + ast::ImplBlock(it) => {}, + _ => { continue }, + } + } + } + "#, + ); + + assert_eq!(res.name, "match_ast"); + assert_snapshot!(res.expansion, @r###" +{ + if let Some(it) = ast::TraitDef::cast(container.clone()){} + else if let Some(it) = ast::ImplBlock::cast(container.clone()){} + else { + { + continue + } + } +} "###); } } From 144dc6652c1bdb0a8a522d86d5bb4be612968675 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Fri, 22 Nov 2019 02:35:49 +0800 Subject: [PATCH 21/21] Fix insert_whitespaces --- crates/ra_ide_api/src/expand_macro.rs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/crates/ra_ide_api/src/expand_macro.rs b/crates/ra_ide_api/src/expand_macro.rs index 789d6cbde9c..7dbf33a16d4 100644 --- a/crates/ra_ide_api/src/expand_macro.rs +++ b/crates/ra_ide_api/src/expand_macro.rs @@ -84,24 +84,19 @@ fn insert_whitespaces(syn: SyntaxNode) -> String { }; res += &match token.kind() { - k @ _ - if (k.is_keyword() || k.is_literal() || k == IDENT) - && is_next(|it| !it.is_punct(), true) => - { + k @ _ if is_text(k) && is_next(|it| !it.is_punct(), true) => { token.text().to_string() + " " } L_CURLY if is_next(|it| it != R_CURLY, true) => { indent += 1; - format!(" {{\n{}", " ".repeat(indent)) + let leading_space = if is_last(|it| is_text(it), false) { " " } else { "" }; + format!("{}{{\n{}", leading_space, " ".repeat(indent)) } R_CURLY if is_last(|it| it != L_CURLY, true) => { indent = indent.checked_sub(1).unwrap_or(0); - format!("\n}}{}", " ".repeat(indent)) - } - R_CURLY => { - indent = indent.checked_sub(1).unwrap_or(0); - format!("}}\n{}", " ".repeat(indent)) + format!("\n{}}}", " ".repeat(indent)) } + R_CURLY => format!("}}\n{}", " ".repeat(indent)), T![;] => format!(";\n{}", " ".repeat(indent)), T![->] => " -> ".to_string(), T![=] => " = ".to_string(), @@ -112,7 +107,11 @@ fn insert_whitespaces(syn: SyntaxNode) -> String { last = Some(token.kind()); } - res + return res; + + fn is_text(k: SyntaxKind) -> bool { + k.is_keyword() || k.is_literal() || k == IDENT + } } #[cfg(test)]