From ccd1b0800a5de5e046e6e9a4b6f49030c1ce3639 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 28 Nov 2019 12:50:26 +0300 Subject: Rename Source -> InFile --- crates/ra_hir_def/src/adt.rs | 6 +++--- crates/ra_hir_def/src/attr.rs | 6 +++--- crates/ra_hir_def/src/body.rs | 14 +++++++------- crates/ra_hir_def/src/body/scope.rs | 6 +++--- crates/ra_hir_def/src/diagnostics.rs | 6 +++--- crates/ra_hir_def/src/lib.rs | 26 +++++++++++++------------- crates/ra_hir_def/src/nameres.rs | 14 +++++++------- crates/ra_hir_def/src/nameres/raw.rs | 6 +++--- crates/ra_hir_def/src/path.rs | 4 ++-- 9 files changed, 44 insertions(+), 44 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 3666529b0..3d21dedee 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use hir_expand::{ either::Either, name::{AsName, Name}, - Source, + InFile, }; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; @@ -88,7 +88,7 @@ impl EnumData { impl HasChildSource for EnumId { type ChildId = LocalEnumVariantId; type Value = ast::EnumVariant; - fn child_source(&self, db: &impl DefDatabase) -> Source> { + fn child_source(&self, db: &impl DefDatabase) -> InFile> { let src = self.source(db); let mut trace = Trace::new_for_map(); lower_enum(&mut trace, &src.value); @@ -145,7 +145,7 @@ impl HasChildSource for VariantId { type ChildId = LocalStructFieldId; type Value = Either; - fn child_source(&self, db: &impl DefDatabase) -> Source> { + fn child_source(&self, db: &impl DefDatabase) -> InFile> { let src = match self { VariantId::EnumVariantId(it) => { // I don't really like the fact that we call into parent source diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index fffb22201..83783ac7a 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -2,7 +2,7 @@ use std::{ops, sync::Arc}; -use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source}; +use hir_expand::{either::Either, hygiene::Hygiene, AstId, InFile}; use mbe::ast_to_token_tree; use ra_syntax::{ ast::{self, AstNode, AttrsOwner}, @@ -68,7 +68,7 @@ impl Attrs { } } - fn from_attrs_owner(db: &impl DefDatabase, owner: Source<&dyn AttrsOwner>) -> Attrs { + fn from_attrs_owner(db: &impl DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs { let hygiene = Hygiene::new(db, owner.file_id); Attrs::new(owner.value, &hygiene) } @@ -157,7 +157,7 @@ where N: ast::AttrsOwner, D: DefDatabase, { - let src = Source::new(src.file_id(), src.to_node(db)); + let src = InFile::new(src.file_id(), src.to_node(db)); Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) } diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index a57a0176d..f21937f10 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -6,7 +6,7 @@ pub mod scope; use std::{ops::Index, sync::Arc}; use hir_expand::{ - either::Either, hygiene::Hygiene, AstId, HirFileId, MacroDefId, MacroFileKind, Source, + either::Either, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId, MacroFileKind, }; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstNode, AstPtr}; @@ -73,8 +73,8 @@ impl Expander { std::mem::forget(mark); } - fn to_source(&self, value: T) -> Source { - Source { file_id: self.current_file_id, value } + fn to_source(&self, value: T) -> InFile { + InFile { file_id: self.current_file_id, value } } fn parse_path(&mut self, path: ast::Path) -> Option { @@ -115,10 +115,10 @@ pub struct Body { } pub type ExprPtr = Either, AstPtr>; -pub type ExprSource = Source; +pub type ExprSource = InFile; pub type PatPtr = Either, AstPtr>; -pub type PatSource = Source; +pub type PatSource = InFile; /// An item body together with the mapping from syntax nodes to HIR expression /// IDs. This is needed to go from e.g. a position in a file to the HIR @@ -205,7 +205,7 @@ impl BodySourceMap { self.expr_map_back.get(expr).copied() } - pub fn node_expr(&self, node: Source<&ast::Expr>) -> Option { + pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option { let src = node.map(|it| Either::A(AstPtr::new(it))); self.expr_map.get(&src).cloned() } @@ -214,7 +214,7 @@ impl BodySourceMap { self.pat_map_back.get(pat).copied() } - pub fn node_pat(&self, node: Source<&ast::Pat>) -> Option { + pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option { let src = node.map(|it| Either::A(AstPtr::new(it))); self.pat_map.get(&src).cloned() } diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index 625aa39dd..ab6599b23 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs @@ -171,7 +171,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope #[cfg(test)] mod tests { - use hir_expand::{name::AsName, Source}; + use hir_expand::{name::AsName, InFile}; use ra_db::{fixture::WithFixture, FileId, SourceDatabase}; use ra_syntax::{algo::find_node_at_offset, ast, AstNode}; use test_utils::{assert_eq_text, covers, extract_offset}; @@ -211,7 +211,7 @@ mod tests { let (_body, source_map) = db.body_with_source_map(function.into()); let expr_id = source_map - .node_expr(Source { file_id: file_id.into(), value: &marker.into() }) + .node_expr(InFile { file_id: file_id.into(), value: &marker.into() }) .unwrap(); let scope = scopes.scope_for(expr_id); @@ -318,7 +318,7 @@ mod tests { let expr_scope = { let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap(); let expr_id = - source_map.node_expr(Source { file_id: file_id.into(), value: &expr_ast }).unwrap(); + source_map.node_expr(InFile { file_id: file_id.into(), value: &expr_ast }).unwrap(); scopes.scope_for(expr_id).unwrap() }; diff --git a/crates/ra_hir_def/src/diagnostics.rs b/crates/ra_hir_def/src/diagnostics.rs index eda9b2269..095498429 100644 --- a/crates/ra_hir_def/src/diagnostics.rs +++ b/crates/ra_hir_def/src/diagnostics.rs @@ -6,7 +6,7 @@ use hir_expand::diagnostics::Diagnostic; use ra_db::RelativePathBuf; use ra_syntax::{ast, AstPtr, SyntaxNodePtr}; -use hir_expand::{HirFileId, Source}; +use hir_expand::{HirFileId, InFile}; #[derive(Debug)] pub struct UnresolvedModule { @@ -19,8 +19,8 @@ impl Diagnostic for UnresolvedModule { fn message(&self) -> String { "unresolved module".to_string() } - fn source(&self) -> Source { - Source { file_id: self.file, value: self.decl.into() } + fn source(&self) -> InFile { + InFile { file_id: self.file, value: self.decl.into() } } fn as_any(&self) -> &(dyn Any + Send + 'static) { self diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index bc5530896..9d89692bf 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -36,7 +36,7 @@ mod marks; use std::hash::{Hash, Hasher}; -use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, MacroDefId, Source}; +use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, InFile, MacroDefId}; use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; use ra_db::{impl_intern_key, salsa, CrateId}; use ra_syntax::{ast, AstNode}; @@ -105,10 +105,10 @@ pub trait AstItemDef: salsa::InternKey + Clone { let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) }; Self::intern(ctx.db, loc) } - fn source(self, db: &(impl AstDatabase + InternDatabase)) -> Source { + fn source(self, db: &(impl AstDatabase + InternDatabase)) -> InFile { let loc = self.lookup_intern(db); let value = loc.ast_id.to_node(db); - Source { file_id: loc.ast_id.file_id(), value } + InFile { file_id: loc.ast_id.file_id(), value } } fn module(self, db: &impl InternDatabase) -> ModuleId { let loc = self.lookup_intern(db); @@ -517,42 +517,42 @@ impl HasModule for StaticLoc { pub trait HasSource { type Value; - fn source(&self, db: &impl db::DefDatabase) -> Source; + fn source(&self, db: &impl db::DefDatabase) -> InFile; } impl HasSource for FunctionLoc { type Value = ast::FnDef; - fn source(&self, db: &impl db::DefDatabase) -> Source { + fn source(&self, db: &impl db::DefDatabase) -> InFile { let node = self.ast_id.to_node(db); - Source::new(self.ast_id.file_id(), node) + InFile::new(self.ast_id.file_id(), node) } } impl HasSource for TypeAliasLoc { type Value = ast::TypeAliasDef; - fn source(&self, db: &impl db::DefDatabase) -> Source { + fn source(&self, db: &impl db::DefDatabase) -> InFile { let node = self.ast_id.to_node(db); - Source::new(self.ast_id.file_id(), node) + InFile::new(self.ast_id.file_id(), node) } } impl HasSource for ConstLoc { type Value = ast::ConstDef; - fn source(&self, db: &impl db::DefDatabase) -> Source { + fn source(&self, db: &impl db::DefDatabase) -> InFile { let node = self.ast_id.to_node(db); - Source::new(self.ast_id.file_id(), node) + InFile::new(self.ast_id.file_id(), node) } } impl HasSource for StaticLoc { type Value = ast::StaticDef; - fn source(&self, db: &impl db::DefDatabase) -> Source { + fn source(&self, db: &impl db::DefDatabase) -> InFile { let node = self.ast_id.to_node(db); - Source::new(self.ast_id.file_id(), node) + InFile::new(self.ast_id.file_id(), node) } } @@ -562,5 +562,5 @@ pub trait HasChildSource { fn child_source( &self, db: &impl db::DefDatabase, - ) -> Source>; + ) -> InFile>; } diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 2359386c2..1b369ea11 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -58,8 +58,8 @@ mod tests; use std::sync::Arc; use hir_expand::{ - ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, MacroDefId, - Source, + ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, InFile, + MacroDefId, }; use once_cell::sync::Lazy; use ra_arena::Arena; @@ -261,21 +261,21 @@ impl ModuleData { pub fn definition_source( &self, db: &impl DefDatabase, - ) -> Source> { + ) -> InFile> { if let Some(file_id) = self.definition { let sf = db.parse(file_id).tree(); - return Source::new(file_id.into(), Either::A(sf)); + return InFile::new(file_id.into(), Either::A(sf)); } let decl = self.declaration.unwrap(); - Source::new(decl.file_id(), Either::B(decl.to_node(db))) + InFile::new(decl.file_id(), Either::B(decl.to_node(db))) } /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. /// `None` for the crate root. - pub fn declaration_source(&self, db: &impl DefDatabase) -> Option> { + pub fn declaration_source(&self, db: &impl DefDatabase) -> Option> { let decl = self.declaration?; let value = decl.to_node(db); - Some(Source { file_id: decl.file_id(), value }) + Some(InFile { file_id: decl.file_id(), value }) } } diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 6eb106094..5196b67ca 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -22,8 +22,8 @@ use ra_syntax::{ use test_utils::tested_by; use crate::{ - attr::Attrs, db::DefDatabase, path::Path, trace::Trace, FileAstId, HirFileId, LocalImportId, - Source, + attr::Attrs, db::DefDatabase, path::Path, trace::Trace, FileAstId, HirFileId, InFile, + LocalImportId, }; /// `RawItems` is a set of top-level items in a file (except for impls). @@ -313,7 +313,7 @@ impl RawItemsCollector { let mut buf = Vec::new(); Path::expand_use_item( - Source { value: use_item, file_id: self.file_id }, + InFile { value: use_item, file_id: self.file_id }, &self.hygiene, |path, use_tree, is_glob, alias| { let import_data = ImportData { diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 6810a26db..10688df4d 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -13,7 +13,7 @@ use ra_syntax::{ AstNode, }; -use crate::{type_ref::TypeRef, Source}; +use crate::{type_ref::TypeRef, InFile}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Path { @@ -67,7 +67,7 @@ pub enum PathKind { impl Path { /// Calls `cb` with all paths, represented by this use item. pub(crate) fn expand_use_item( - item_src: Source, + item_src: InFile, hygiene: &Hygiene, mut cb: impl FnMut(Path, &ast::UseTree, bool, Option), ) { -- cgit v1.2.3 From e823c578c9f6886fe9db9767cb81e75a6c56bf15 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 28 Nov 2019 16:00:03 +0300 Subject: Use InFile for AstId --- crates/ra_hir_def/src/attr.rs | 2 +- crates/ra_hir_def/src/lib.rs | 10 +++++----- crates/ra_hir_def/src/nameres.rs | 6 +++--- crates/ra_hir_def/src/nameres/tests/mod_resolution.rs | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 83783ac7a..346019f88 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -157,7 +157,7 @@ where N: ast::AttrsOwner, D: DefDatabase, { - let src = InFile::new(src.file_id(), src.to_node(db)); + let src = InFile::new(src.file_id, src.to_node(db)); Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 9d89692bf..6daf7d3a3 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -108,7 +108,7 @@ pub trait AstItemDef: salsa::InternKey + Clone { fn source(self, db: &(impl AstDatabase + InternDatabase)) -> InFile { let loc = self.lookup_intern(db); let value = loc.ast_id.to_node(db); - InFile { file_id: loc.ast_id.file_id(), value } + InFile { file_id: loc.ast_id.file_id, value } } fn module(self, db: &impl InternDatabase) -> ModuleId { let loc = self.lookup_intern(db); @@ -525,7 +525,7 @@ impl HasSource for FunctionLoc { fn source(&self, db: &impl db::DefDatabase) -> InFile { let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id(), node) + InFile::new(self.ast_id.file_id, node) } } @@ -534,7 +534,7 @@ impl HasSource for TypeAliasLoc { fn source(&self, db: &impl db::DefDatabase) -> InFile { let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id(), node) + InFile::new(self.ast_id.file_id, node) } } @@ -543,7 +543,7 @@ impl HasSource for ConstLoc { fn source(&self, db: &impl db::DefDatabase) -> InFile { let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id(), node) + InFile::new(self.ast_id.file_id, node) } } @@ -552,7 +552,7 @@ impl HasSource for StaticLoc { fn source(&self, db: &impl db::DefDatabase) -> InFile { let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id(), node) + InFile::new(self.ast_id.file_id, node) } } diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 1b369ea11..df42ea84a 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -267,7 +267,7 @@ impl ModuleData { return InFile::new(file_id.into(), Either::A(sf)); } let decl = self.declaration.unwrap(); - InFile::new(decl.file_id(), Either::B(decl.to_node(db))) + InFile::new(decl.file_id, Either::B(decl.to_node(db))) } /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. @@ -275,7 +275,7 @@ impl ModuleData { pub fn declaration_source(&self, db: &impl DefDatabase) -> Option> { let decl = self.declaration?; let value = decl.to_node(db); - Some(InFile { file_id: decl.file_id(), value }) + Some(InFile { file_id: decl.file_id, value }) } } @@ -309,7 +309,7 @@ mod diagnostics { } let decl = declaration.to_node(db); sink.push(UnresolvedModule { - file: declaration.file_id(), + file: declaration.file_id, decl: AstPtr::new(&decl), candidate: candidate.clone(), }) diff --git a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs index e11530062..e800cc68e 100644 --- a/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir_def/src/nameres/tests/mod_resolution.rs @@ -668,7 +668,7 @@ fn unresolved_module_diagnostics() { module: LocalModuleId( 0, ), - declaration: AstId { + declaration: InFile { file_id: HirFileId( FileId( FileId( @@ -676,7 +676,7 @@ fn unresolved_module_diagnostics() { ), ), ), - file_ast_id: FileAstId { + value: FileAstId { raw: ErasedFileAstId( 1, ), -- cgit v1.2.3 From 8f1f5a783a3ffd0afbf5b1fdf22ff9caf7fda928 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 28 Nov 2019 18:05:28 +0300 Subject: Move source-related traits to a separate module --- crates/ra_hir_def/src/adt.rs | 2 +- crates/ra_hir_def/src/attr.rs | 3 ++- crates/ra_hir_def/src/body.rs | 3 ++- crates/ra_hir_def/src/data.rs | 5 ++-- crates/ra_hir_def/src/docs.rs | 6 ++++- crates/ra_hir_def/src/generics.rs | 3 ++- crates/ra_hir_def/src/lib.rs | 54 +++------------------------------------ crates/ra_hir_def/src/src.rs | 54 +++++++++++++++++++++++++++++++++++++++ 8 files changed, 72 insertions(+), 58 deletions(-) create mode 100644 crates/ra_hir_def/src/src.rs (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 3d21dedee..9ab829aab 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -11,7 +11,7 @@ use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; use crate::{ - db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, + db::DefDatabase, src::HasChildSource, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId, }; diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 346019f88..bc7ade921 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -11,7 +11,8 @@ use ra_syntax::{ use tt::Subtree; use crate::{ - db::DefDatabase, path::Path, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup, + db::DefDatabase, path::Path, src::HasChildSource, src::HasSource, AdtId, AstItemDef, AttrDefId, + Lookup, }; #[derive(Default, Debug, Clone, PartialEq, Eq)] diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index f21937f10..69508dd8a 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -17,7 +17,8 @@ use crate::{ expr::{Expr, ExprId, Pat, PatId}, nameres::CrateDefMap, path::Path, - DefWithBodyId, HasModule, HasSource, Lookup, ModuleId, + src::HasSource, + DefWithBodyId, HasModule, Lookup, ModuleId, }; struct Expander { diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index fee10b237..095d7064a 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -10,9 +10,10 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; use crate::{ db::DefDatabase, + src::HasSource, type_ref::{Mutability, TypeRef}, - AssocItemId, AstItemDef, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, HasSource, - ImplId, Intern, Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, + AssocItemId, AstItemDef, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, + Intern, Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index 34ed9b7a5..ec944373d 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -8,7 +8,11 @@ use std::sync::Arc; use hir_expand::either::Either; use ra_syntax::ast; -use crate::{db::DefDatabase, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup}; +use crate::{ + db::DefDatabase, + src::{HasChildSource, HasSource}, + AdtId, AstItemDef, AttrDefId, Lookup, +}; /// Holds documentation #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 3f94e40e4..5f648ffc3 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -9,8 +9,9 @@ use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; use crate::{ db::DefDatabase, + src::HasSource, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, ContainerId, GenericDefId, HasSource, Lookup, + AdtId, AstItemDef, ContainerId, GenericDefId, Lookup, }; /// Data about a generic parameter (to a function, struct, impl, ...). diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 6daf7d3a3..cfeacfded 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -29,6 +29,8 @@ pub mod resolver; mod trace; pub mod nameres; +pub mod src; + #[cfg(test)] mod test_db; #[cfg(test)] @@ -37,7 +39,7 @@ mod marks; use std::hash::{Hash, Hasher}; use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, InFile, MacroDefId}; -use ra_arena::{impl_arena_id, map::ArenaMap, RawId}; +use ra_arena::{impl_arena_id, RawId}; use ra_db::{impl_intern_key, salsa, CrateId}; use ra_syntax::{ast, AstNode}; @@ -514,53 +516,3 @@ impl HasModule for StaticLoc { self.container } } - -pub trait HasSource { - type Value; - fn source(&self, db: &impl db::DefDatabase) -> InFile; -} - -impl HasSource for FunctionLoc { - type Value = ast::FnDef; - - fn source(&self, db: &impl db::DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for TypeAliasLoc { - type Value = ast::TypeAliasDef; - - fn source(&self, db: &impl db::DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for ConstLoc { - type Value = ast::ConstDef; - - fn source(&self, db: &impl db::DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for StaticLoc { - type Value = ast::StaticDef; - - fn source(&self, db: &impl db::DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -pub trait HasChildSource { - type ChildId; - type Value; - fn child_source( - &self, - db: &impl db::DefDatabase, - ) -> InFile>; -} diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs new file mode 100644 index 000000000..27caa02cc --- /dev/null +++ b/crates/ra_hir_def/src/src.rs @@ -0,0 +1,54 @@ +//! Utilities for mapping between hir IDs and the surface syntax. + +use hir_expand::InFile; +use ra_arena::map::ArenaMap; +use ra_syntax::ast; + +use crate::{db::DefDatabase, ConstLoc, FunctionLoc, StaticLoc, TypeAliasLoc}; + +pub trait HasSource { + type Value; + fn source(&self, db: &impl DefDatabase) -> InFile; +} + +impl HasSource for FunctionLoc { + type Value = ast::FnDef; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + +impl HasSource for TypeAliasLoc { + type Value = ast::TypeAliasDef; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + +impl HasSource for ConstLoc { + type Value = ast::ConstDef; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + +impl HasSource for StaticLoc { + type Value = ast::StaticDef; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + +pub trait HasChildSource { + type ChildId; + type Value; + fn child_source(&self, db: &impl DefDatabase) -> InFile>; +} -- cgit v1.2.3 From 4992d2bf79e9da6db759eb8e1715f90f31ec7eb9 Mon Sep 17 00:00:00 2001 From: oxalica Date: Fri, 29 Nov 2019 03:10:16 +0800 Subject: Infer range types --- crates/ra_hir_def/src/body/lower.rs | 22 ++++++++++++++++++++-- crates/ra_hir_def/src/expr.rs | 28 ++++++++++++++++++++++++++-- crates/ra_hir_def/src/path.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 331736cb2..d18964d54 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -8,7 +8,7 @@ use hir_expand::{ use ra_arena::Arena; use ra_syntax::{ ast::{ - self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, + self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, RangeOp, TypeAscriptionOwner, }, AstNode, AstPtr, @@ -429,10 +429,28 @@ where let index = self.collect_expr_opt(e.index()); self.alloc_expr(Expr::Index { base, index }, syntax_ptr) } + ast::Expr::RangeExpr(e) => { + let lhs = e.start().map(|lhs| self.collect_expr(lhs)); + let rhs = e.end().map(|rhs| self.collect_expr(rhs)); + match (lhs, e.op_kind(), rhs) { + (None, _, None) => self.alloc_expr(Expr::RangeFull, syntax_ptr), + (Some(lhs), _, None) => self.alloc_expr(Expr::RangeFrom { lhs }, syntax_ptr), + (None, Some(RangeOp::Inclusive), Some(rhs)) => { + self.alloc_expr(Expr::RangeToInclusive { rhs }, syntax_ptr) + } + (Some(lhs), Some(RangeOp::Inclusive), Some(rhs)) => { + self.alloc_expr(Expr::RangeInclusive { lhs, rhs }, syntax_ptr) + } + // If RangeOp is missing, fallback to exclusive range. + (None, _, Some(rhs)) => self.alloc_expr(Expr::RangeTo { rhs }, syntax_ptr), + (Some(lhs), _, Some(rhs)) => { + self.alloc_expr(Expr::Range { lhs, rhs }, syntax_ptr) + } + } + } // FIXME implement HIR for these: ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), - ast::Expr::RangeExpr(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { Some((mark, expansion)) => { let id = self.collect_expr(expansion); diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index 04c1d8f69..115090218 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs @@ -130,6 +130,24 @@ pub enum Expr { rhs: ExprId, op: Option, }, + RangeFull, + RangeFrom { + lhs: ExprId, + }, + RangeTo { + rhs: ExprId, + }, + Range { + lhs: ExprId, + rhs: ExprId, + }, + RangeToInclusive { + rhs: ExprId, + }, + RangeInclusive { + lhs: ExprId, + rhs: ExprId, + }, Index { base: ExprId, index: ExprId, @@ -284,7 +302,9 @@ impl Expr { Expr::Lambda { body, .. } => { f(*body); } - Expr::BinaryOp { lhs, rhs, .. } => { + Expr::BinaryOp { lhs, rhs, .. } + | Expr::Range { lhs, rhs } + | Expr::RangeInclusive { lhs, rhs } => { f(*lhs); f(*rhs); } @@ -292,7 +312,11 @@ impl Expr { f(*base); f(*index); } - Expr::Field { expr, .. } + Expr::RangeFull => {} + Expr::RangeFrom { lhs: expr } + | Expr::RangeTo { rhs: expr } + | Expr::RangeToInclusive { rhs: expr } + | Expr::Field { expr, .. } | Expr::Await { expr } | Expr::Try { expr } | Expr::Cast { expr, .. } diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 10688df4d..ff252fe44 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -409,6 +409,36 @@ pub mod known { Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::TRY_TYPE]) } + pub fn std_ops_range() -> Path { + Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TYPE]) + } + + pub fn std_ops_range_from() -> Path { + Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FROM_TYPE]) + } + + pub fn std_ops_range_full() -> Path { + Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FULL_TYPE]) + } + + pub fn std_ops_range_inclusive() -> Path { + Path::from_simple_segments( + PathKind::Abs, + vec![name::STD, name::OPS, name::RANGE_INCLUSIVE_TYPE], + ) + } + + pub fn std_ops_range_to() -> Path { + Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TO_TYPE]) + } + + pub fn std_ops_range_to_inclusive() -> Path { + Path::from_simple_segments( + PathKind::Abs, + vec![name::STD, name::OPS, name::RANGE_TO_INCLUSIVE_TYPE], + ) + } + pub fn std_result_result() -> Path { Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE]) } -- cgit v1.2.3 From 2cb684bbce1c487b2efb5a8154afe66e4907ceac Mon Sep 17 00:00:00 2001 From: oxalica Date: Fri, 29 Nov 2019 14:49:12 +0800 Subject: Reduce variants of Expr --- crates/ra_hir_def/src/body/lower.rs | 19 +++++-------------- crates/ra_hir_def/src/expr.rs | 38 ++++++++++++++----------------------- 2 files changed, 19 insertions(+), 38 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index d18964d54..be1eaa523 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -8,7 +8,7 @@ use hir_expand::{ use ra_arena::Arena; use ra_syntax::{ ast::{ - self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, RangeOp, + self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, TypeAscriptionOwner, }, AstNode, AstPtr, @@ -432,20 +432,11 @@ where ast::Expr::RangeExpr(e) => { let lhs = e.start().map(|lhs| self.collect_expr(lhs)); let rhs = e.end().map(|rhs| self.collect_expr(rhs)); - match (lhs, e.op_kind(), rhs) { - (None, _, None) => self.alloc_expr(Expr::RangeFull, syntax_ptr), - (Some(lhs), _, None) => self.alloc_expr(Expr::RangeFrom { lhs }, syntax_ptr), - (None, Some(RangeOp::Inclusive), Some(rhs)) => { - self.alloc_expr(Expr::RangeToInclusive { rhs }, syntax_ptr) - } - (Some(lhs), Some(RangeOp::Inclusive), Some(rhs)) => { - self.alloc_expr(Expr::RangeInclusive { lhs, rhs }, syntax_ptr) - } - // If RangeOp is missing, fallback to exclusive range. - (None, _, Some(rhs)) => self.alloc_expr(Expr::RangeTo { rhs }, syntax_ptr), - (Some(lhs), _, Some(rhs)) => { - self.alloc_expr(Expr::Range { lhs, rhs }, syntax_ptr) + match e.op_kind() { + Some(range_type) => { + self.alloc_expr(Expr::Range { lhs, rhs, range_type }, syntax_ptr) } + None => self.alloc_expr(Expr::Missing, syntax_ptr), } } diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index 115090218..6fad80a8d 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs @@ -14,6 +14,7 @@ use hir_expand::name::Name; use ra_arena::{impl_arena_id, RawId}; +use ra_syntax::ast::RangeOp; use crate::{ builtin_type::{BuiltinFloat, BuiltinInt}, @@ -130,23 +131,10 @@ pub enum Expr { rhs: ExprId, op: Option, }, - RangeFull, - RangeFrom { - lhs: ExprId, - }, - RangeTo { - rhs: ExprId, - }, Range { - lhs: ExprId, - rhs: ExprId, - }, - RangeToInclusive { - rhs: ExprId, - }, - RangeInclusive { - lhs: ExprId, - rhs: ExprId, + lhs: Option, + rhs: Option, + range_type: RangeOp, }, Index { base: ExprId, @@ -302,21 +290,23 @@ impl Expr { Expr::Lambda { body, .. } => { f(*body); } - Expr::BinaryOp { lhs, rhs, .. } - | Expr::Range { lhs, rhs } - | Expr::RangeInclusive { lhs, rhs } => { + Expr::BinaryOp { lhs, rhs, .. } => { f(*lhs); f(*rhs); } + Expr::Range { lhs, rhs, .. } => { + if let Some(lhs) = rhs { + f(*lhs); + } + if let Some(rhs) = lhs { + f(*rhs); + } + } Expr::Index { base, index } => { f(*base); f(*index); } - Expr::RangeFull => {} - Expr::RangeFrom { lhs: expr } - | Expr::RangeTo { rhs: expr } - | Expr::RangeToInclusive { rhs: expr } - | Expr::Field { expr, .. } + Expr::Field { expr, .. } | Expr::Await { expr } | Expr::Try { expr } | Expr::Cast { expr, .. } -- cgit v1.2.3 From bb601e7eafa00e471a5306ac920f0be6c809aab0 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 30 Nov 2019 23:29:21 +0800 Subject: Add BuiltinShadowMode --- crates/ra_hir_def/src/body.rs | 7 ++- crates/ra_hir_def/src/nameres.rs | 30 +++++++++- crates/ra_hir_def/src/nameres/collector.rs | 4 +- crates/ra_hir_def/src/nameres/path_resolution.rs | 71 +++++++++++++++++++----- crates/ra_hir_def/src/resolver.rs | 38 +++++++++---- 5 files changed, 120 insertions(+), 30 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 69508dd8a..239f35229 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -15,7 +15,7 @@ use rustc_hash::FxHashMap; use crate::{ db::DefDatabase, expr::{Expr, ExprId, Pat, PatId}, - nameres::CrateDefMap, + nameres::{BuiltinShadowMode, CrateDefMap}, path::Path, src::HasSource, DefWithBodyId, HasModule, Lookup, ModuleId, @@ -83,7 +83,10 @@ impl Expander { } fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option { - self.crate_def_map.resolve_path(db, self.module.local_id, path).0.take_macros() + self.crate_def_map + .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other) + .0 + .take_macros() } } diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index df42ea84a..9aaf7736b 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -149,6 +149,16 @@ static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { .collect() }); +/// Shadow mode for builtin type +/// Builtin type can be shadowed by same name mode +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum BuiltinShadowMode { + // Prefer Module + Module, + // Prefer Other Types + Other, +} + /// Legacy macros can only be accessed through special methods like `get_legacy_macros`. /// Other methods will only resolve values, types and module scoped macros only. impl ModuleScope { @@ -178,8 +188,20 @@ impl ModuleScope { } /// Get a name from current module scope, legacy macros are not included - pub fn get(&self, name: &Name) -> Option<&Resolution> { - self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)) + pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> { + match shadow { + BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)), + BuiltinShadowMode::Other => { + let item = self.items.get(name); + if let Some(res) = item { + if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() { + return BUILTIN_SCOPE.get(name).or(item); + } + } + + item.or_else(|| BUILTIN_SCOPE.get(name)) + } + } } pub fn traits<'a>(&'a self) -> impl Iterator + 'a { @@ -250,8 +272,10 @@ impl CrateDefMap { db: &impl DefDatabase, original_module: LocalModuleId, path: &Path, + shadow: BuiltinShadowMode, ) -> (PerNs, Option) { - let res = self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path); + let res = + self.resolve_path_fp_with_macro(db, ResolveMode::Other, original_module, path, shadow); (res.resolved_def, res.segment_index) } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index fd8245113..d4bfcae1d 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -19,7 +19,7 @@ use crate::{ db::DefDatabase, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, - raw, CrateDefMap, ModuleData, Resolution, ResolveMode, + raw, BuiltinShadowMode, CrateDefMap, ModuleData, Resolution, ResolveMode, }, path::{Path, PathKind}, per_ns::PerNs, @@ -299,6 +299,7 @@ where ResolveMode::Import, module_id, &import.path, + BuiltinShadowMode::Module, ); (res.resolved_def, res.reached_fixedpoint) @@ -477,6 +478,7 @@ where ResolveMode::Other, *module_id, path, + BuiltinShadowMode::Module, ); if let Some(def) = resolved_res.resolved_def.take_macros() { diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index b72c55bd1..174ae9d38 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -16,7 +16,7 @@ use test_utils::tested_by; use crate::{ db::DefDatabase, - nameres::CrateDefMap, + nameres::{BuiltinShadowMode, CrateDefMap}, path::{Path, PathKind}, per_ns::PerNs, AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, @@ -68,8 +68,10 @@ impl CrateDefMap { mode: ResolveMode, original_module: LocalModuleId, path: &Path, + shadow: BuiltinShadowMode, ) -> ResolvePathResult { - let mut segments = path.segments.iter().enumerate(); + let mut segments = path.segments.iter().enumerate().peekable(); + let mut curr_per_ns: PerNs = match path.kind { PathKind::DollarCrate(krate) => { if krate == self.krate { @@ -101,7 +103,11 @@ impl CrateDefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_crate_root_or_extern_prelude(&segment.name) + + self.resolve_name_in_crate_root_or_extern_prelude( + &segment.name, + prefer_module(&mut segments, shadow), + ) } PathKind::Plain => { let segment = match segments.next() { @@ -109,7 +115,12 @@ impl CrateDefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; log::debug!("resolving {:?} in module", segment); - self.resolve_name_in_module(db, original_module, &segment.name) + self.resolve_name_in_module( + db, + original_module, + &segment.name, + prefer_module(&mut segments, shadow), + ) } PathKind::Super => { if let Some(p) = self.modules[original_module].parent { @@ -139,7 +150,7 @@ impl CrateDefMap { } }; - for (i, segment) in segments { + while let Some((i, segment)) = segments.next() { let curr = match curr_per_ns.take_types() { Some(r) => r, None => { @@ -160,7 +171,7 @@ impl CrateDefMap { Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; log::debug!("resolving {:?} in other crate", path); let defp_map = db.crate_def_map(module.krate); - let (def, s) = defp_map.resolve_path(db, module.local_id, &path); + let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); return ResolvePathResult::with( def, ReachedFixedPoint::Yes, @@ -169,7 +180,10 @@ impl CrateDefMap { } // Since it is a qualified path here, it should not contains legacy macros - match self[module.local_id].scope.get(&segment.name) { + match self[module.local_id] + .scope + .get(&segment.name, prefer_module(&mut segments, shadow)) + { Some(res) => res.def, _ => { log::debug!("path segment {:?} not found", segment.name); @@ -212,7 +226,22 @@ impl CrateDefMap { } }; } - ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) + return ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None); + + // if it is not the last segment, we prefer builtin as module + fn prefer_module( + segments: &mut std::iter::Peekable, + shadow: BuiltinShadowMode, + ) -> BuiltinShadowMode + where + I: Iterator, + { + if segments.peek().is_some() { + BuiltinShadowMode::Module + } else { + shadow + } + } } fn resolve_name_in_module( @@ -220,6 +249,7 @@ impl CrateDefMap { db: &impl DefDatabase, module: LocalModuleId, name: &Name, + shadow: BuiltinShadowMode, ) -> PerNs { // Resolve in: // - legacy scope of macro @@ -228,23 +258,33 @@ impl CrateDefMap { // - std prelude let from_legacy_macro = self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); - let from_scope = self[module].scope.get(name).map_or_else(PerNs::none, |res| res.def); + let from_scope = + self[module].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def); let from_extern_prelude = self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); - let from_prelude = self.resolve_in_prelude(db, name); + let from_prelude = self.resolve_in_prelude(db, name, shadow); from_legacy_macro.or(from_scope).or(from_extern_prelude).or(from_prelude) } - fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> PerNs { + fn resolve_name_in_crate_root_or_extern_prelude( + &self, + name: &Name, + shadow: BuiltinShadowMode, + ) -> PerNs { let from_crate_root = - self[self.root].scope.get(name).map_or_else(PerNs::none, |res| res.def); + self[self.root].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def); let from_extern_prelude = self.resolve_name_in_extern_prelude(name); from_crate_root.or(from_extern_prelude) } - fn resolve_in_prelude(&self, db: &impl DefDatabase, name: &Name) -> PerNs { + fn resolve_in_prelude( + &self, + db: &impl DefDatabase, + name: &Name, + shadow: BuiltinShadowMode, + ) -> PerNs { if let Some(prelude) = self.prelude { let keep; let def_map = if prelude.krate == self.krate { @@ -254,7 +294,10 @@ impl CrateDefMap { keep = db.crate_def_map(prelude.krate); &keep }; - def_map[prelude.local_id].scope.get(name).map_or_else(PerNs::none, |res| res.def) + def_map[prelude.local_id] + .scope + .get(name, shadow) + .map_or_else(PerNs::none, |res| res.def) } else { PerNs::none() } diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 0847f6dcf..7d4df222e 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -14,7 +14,7 @@ use crate::{ db::DefDatabase, expr::{ExprId, PatId}, generics::GenericParams, - nameres::CrateDefMap, + nameres::{BuiltinShadowMode, CrateDefMap}, path::{Path, PathKind}, per_ns::PerNs, AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, @@ -91,7 +91,7 @@ pub enum ValueNs { impl Resolver { /// Resolve known trait from std, like `std::futures::Future` pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option { - let res = self.resolve_module_path(db, path).take_types()?; + let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; match res { ModuleDefId::TraitId(it) => Some(it), _ => None, @@ -100,7 +100,7 @@ impl Resolver { /// Resolve known struct from std, like `std::boxed::Box` pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option { - let res = self.resolve_module_path(db, path).take_types()?; + let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; match res { ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), _ => None, @@ -109,26 +109,34 @@ impl Resolver { /// Resolve known enum from std, like `std::result::Result` pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option { - let res = self.resolve_module_path(db, path).take_types()?; + let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; match res { ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), _ => None, } } - /// pub only for source-binder - pub fn resolve_module_path(&self, db: &impl DefDatabase, path: &Path) -> PerNs { + fn resolve_module_path( + &self, + db: &impl DefDatabase, + path: &Path, + shadow: BuiltinShadowMode, + ) -> PerNs { let (item_map, module) = match self.module() { Some(it) => it, None => return PerNs::none(), }; - let (module_res, segment_index) = item_map.resolve_path(db, module, path); + let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow); if segment_index.is_some() { return PerNs::none(); } module_res } + pub fn resolve_module_path_in_items(&self, db: &impl DefDatabase, path: &Path) -> PerNs { + self.resolve_module_path(db, path, BuiltinShadowMode::Module) + } + pub fn resolve_path_in_type_ns( &self, db: &impl DefDatabase, @@ -163,7 +171,12 @@ impl Resolver { } } Scope::ModuleScope(m) => { - let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); + let (module_def, idx) = m.crate_def_map.resolve_path( + db, + m.module_id, + path, + BuiltinShadowMode::Other, + ); let res = match module_def.take_types()? { ModuleDefId::AdtId(it) => TypeNs::AdtId(it), ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), @@ -256,7 +269,12 @@ impl Resolver { Scope::ImplBlockScope(_) | Scope::AdtScope(_) => continue, Scope::ModuleScope(m) => { - let (module_def, idx) = m.crate_def_map.resolve_path(db, m.module_id, path); + let (module_def, idx) = m.crate_def_map.resolve_path( + db, + m.module_id, + path, + BuiltinShadowMode::Other, + ); return match idx { None => { let value = match module_def.take_values()? { @@ -310,7 +328,7 @@ impl Resolver { pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option { let (item_map, module) = self.module()?; - item_map.resolve_path(db, module, path).0.take_macros() + item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros() } pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { -- cgit v1.2.3 From 5f1111773301a084ec8d0b6a2c81be5a756241ab Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 1 Dec 2019 12:14:12 +0800 Subject: Fix comment --- crates/ra_hir_def/src/nameres.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 9aaf7736b..3e1521870 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -149,8 +149,7 @@ static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { .collect() }); -/// Shadow mode for builtin type -/// Builtin type can be shadowed by same name mode +/// Shadow mode for builtin type which can be shadowed by module. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum BuiltinShadowMode { // Prefer Module -- cgit v1.2.3 From 13c54685ffbc153d4d675f13222dfb02b0f30926 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 1 Dec 2019 12:14:35 +0800 Subject: Use index instead of peekable --- crates/ra_hir_def/src/nameres/path_resolution.rs | 54 +++++++++--------------- 1 file changed, 19 insertions(+), 35 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 174ae9d38..19d57baae 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -70,7 +70,16 @@ impl CrateDefMap { path: &Path, shadow: BuiltinShadowMode, ) -> ResolvePathResult { - let mut segments = path.segments.iter().enumerate().peekable(); + // if it is not the last segment, we prefer the module to the builtin + let prefer_module = |index| { + if index == path.segments.len() - 1 { + shadow + } else { + BuiltinShadowMode::Module + } + }; + + let mut segments = path.segments.iter().enumerate(); let mut curr_per_ns: PerNs = match path.kind { PathKind::DollarCrate(krate) => { @@ -98,29 +107,21 @@ impl CrateDefMap { if self.edition == Edition::Edition2015 && (path.kind == PathKind::Abs || mode == ResolveMode::Import) => { - let segment = match segments.next() { - Some((_, segment)) => segment, + let (idx, segment) = match segments.next() { + Some((idx, segment)) => (idx, segment), None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_crate_root_or_extern_prelude( - &segment.name, - prefer_module(&mut segments, shadow), - ) + self.resolve_name_in_crate_root_or_extern_prelude(&segment.name, prefer_module(idx)) } PathKind::Plain => { - let segment = match segments.next() { - Some((_, segment)) => segment, + let (idx, segment) = match segments.next() { + Some((idx, segment)) => (idx, segment), None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; log::debug!("resolving {:?} in module", segment); - self.resolve_name_in_module( - db, - original_module, - &segment.name, - prefer_module(&mut segments, shadow), - ) + self.resolve_name_in_module(db, original_module, &segment.name, prefer_module(idx)) } PathKind::Super => { if let Some(p) = self.modules[original_module].parent { @@ -150,7 +151,7 @@ impl CrateDefMap { } }; - while let Some((i, segment)) = segments.next() { + for (i, segment) in segments { let curr = match curr_per_ns.take_types() { Some(r) => r, None => { @@ -180,10 +181,7 @@ impl CrateDefMap { } // Since it is a qualified path here, it should not contains legacy macros - match self[module.local_id] - .scope - .get(&segment.name, prefer_module(&mut segments, shadow)) - { + match self[module.local_id].scope.get(&segment.name, prefer_module(i)) { Some(res) => res.def, _ => { log::debug!("path segment {:?} not found", segment.name); @@ -226,22 +224,8 @@ impl CrateDefMap { } }; } - return ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None); - // if it is not the last segment, we prefer builtin as module - fn prefer_module( - segments: &mut std::iter::Peekable, - shadow: BuiltinShadowMode, - ) -> BuiltinShadowMode - where - I: Iterator, - { - if segments.peek().is_some() { - BuiltinShadowMode::Module - } else { - shadow - } - } + ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) } fn resolve_name_in_module( -- cgit v1.2.3 From cfc6e9e36646aa3b961018be875a7c3474aa7577 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 1 Dec 2019 12:17:52 +0800 Subject: Remove some empty lines --- crates/ra_hir_def/src/nameres/path_resolution.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 19d57baae..42a75226b 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -80,7 +80,6 @@ impl CrateDefMap { }; let mut segments = path.segments.iter().enumerate(); - let mut curr_per_ns: PerNs = match path.kind { PathKind::DollarCrate(krate) => { if krate == self.krate { @@ -112,7 +111,6 @@ impl CrateDefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_crate_root_or_extern_prelude(&segment.name, prefer_module(idx)) } PathKind::Plain => { -- cgit v1.2.3 From 009437f5d9949d2276aa26040e03af0ab328acf3 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Tue, 3 Dec 2019 11:07:56 -0500 Subject: Replace `ra_hir_expand::either` with crate --- crates/ra_hir_def/src/adt.rs | 6 +++--- crates/ra_hir_def/src/attr.rs | 7 ++++--- crates/ra_hir_def/src/body.rs | 9 ++++----- crates/ra_hir_def/src/body/lower.rs | 16 +++++++--------- crates/ra_hir_def/src/docs.rs | 6 +++--- crates/ra_hir_def/src/nameres.rs | 8 ++++---- crates/ra_hir_def/src/nameres/raw.rs | 6 +++--- crates/ra_hir_def/src/path.rs | 10 +++++----- 8 files changed, 33 insertions(+), 35 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 9ab829aab..db3e63ef8 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -2,8 +2,8 @@ use std::sync::Arc; +use either::Either; use hir_expand::{ - either::Either, name::{AsName, Name}, InFile, }; @@ -184,7 +184,7 @@ fn lower_struct( ast::StructKind::Tuple(fl) => { for (i, fd) in fl.fields().enumerate() { trace.alloc( - || Either::A(fd.clone()), + || Either::Left(fd.clone()), || StructFieldData { name: Name::new_tuple_field(i), type_ref: TypeRef::from_ast_opt(fd.type_ref()), @@ -196,7 +196,7 @@ fn lower_struct( ast::StructKind::Record(fl) => { for fd in fl.fields() { trace.alloc( - || Either::B(fd.clone()), + || Either::Right(fd.clone()), || StructFieldData { name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing), type_ref: TypeRef::from_ast_opt(fd.ascribed_type()), diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index bc7ade921..7f9a6e7ca 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -2,7 +2,8 @@ use std::{ops, sync::Arc}; -use hir_expand::{either::Either, hygiene::Hygiene, AstId, InFile}; +use either::Either; +use hir_expand::{hygiene::Hygiene, AstId, InFile}; use mbe::ast_to_token_tree; use ra_syntax::{ ast::{self, AstNode, AttrsOwner}, @@ -45,8 +46,8 @@ impl Attrs { AttrDefId::StructFieldId(it) => { let src = it.parent.child_source(db); match &src.value[it.local_id] { - Either::A(_tuple) => Attrs::default(), - Either::B(record) => Attrs::from_attrs_owner(db, src.with_value(record)), + Either::Left(_tuple) => Attrs::default(), + Either::Right(record) => Attrs::from_attrs_owner(db, src.with_value(record)), } } AttrDefId::EnumVariantId(var_id) => { diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 239f35229..ef1816836 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -5,9 +5,8 @@ pub mod scope; use std::{ops::Index, sync::Arc}; -use hir_expand::{ - either::Either, hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId, MacroFileKind, -}; +use either::Either; +use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId, MacroFileKind}; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstNode, AstPtr}; use rustc_hash::FxHashMap; @@ -210,7 +209,7 @@ impl BodySourceMap { } pub fn node_expr(&self, node: InFile<&ast::Expr>) -> Option { - let src = node.map(|it| Either::A(AstPtr::new(it))); + let src = node.map(|it| Either::Left(AstPtr::new(it))); self.expr_map.get(&src).cloned() } @@ -219,7 +218,7 @@ impl BodySourceMap { } pub fn node_pat(&self, node: InFile<&ast::Pat>) -> Option { - let src = node.map(|it| Either::A(AstPtr::new(it))); + let src = node.map(|it| Either::Left(AstPtr::new(it))); self.pat_map.get(&src).cloned() } diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index be1eaa523..71c08f024 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -1,10 +1,8 @@ //! Transforms `ast::Expr` into an equivalent `hir_def::expr::Expr` //! representation. -use hir_expand::{ - either::Either, - name::{self, AsName, Name}, -}; +use either::Either; +use hir_expand::name::{self, AsName, Name}; use ra_arena::Arena; use ra_syntax::{ ast::{ @@ -74,7 +72,7 @@ where mode: BindingAnnotation::Unannotated, subpat: None, }, - Either::B(ptr), + Either::Right(ptr), ); self.body.params.push(param_pat); } @@ -94,7 +92,7 @@ where } fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { - let ptr = Either::A(ptr); + let ptr = Either::Left(ptr); let id = self.body.exprs.alloc(expr); let src = self.expander.to_source(ptr); self.source_map.expr_map.insert(src, id); @@ -107,7 +105,7 @@ where self.body.exprs.alloc(expr) } fn alloc_expr_field_shorthand(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { - let ptr = Either::B(ptr); + let ptr = Either::Right(ptr); let id = self.body.exprs.alloc(expr); let src = self.expander.to_source(ptr); self.source_map.expr_map.insert(src, id); @@ -277,7 +275,7 @@ where ast::Expr::ParenExpr(e) => { let inner = self.collect_expr_opt(e.expr()); // make the paren expr point to the inner expression as well - let src = self.expander.to_source(Either::A(syntax_ptr)); + let src = self.expander.to_source(Either::Left(syntax_ptr)); self.source_map.expr_map.insert(src, inner); inner } @@ -550,7 +548,7 @@ where ast::Pat::SlicePat(_) | ast::Pat::RangePat(_) => Pat::Missing, }; let ptr = AstPtr::new(&pat); - self.alloc_pat(pattern, Either::A(ptr)) + self.alloc_pat(pattern, Either::Left(ptr)) } fn collect_pat_opt(&mut self, pat: Option) -> PatId { diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index ec944373d..3fc6d6934 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -5,7 +5,7 @@ use std::sync::Arc; -use hir_expand::either::Either; +use either::Either; use ra_syntax::ast; use crate::{ @@ -46,8 +46,8 @@ impl Documentation { AttrDefId::StructFieldId(it) => { let src = it.parent.child_source(db); match &src.value[it.local_id] { - Either::A(_tuple) => None, - Either::B(record) => docs_from_ast(record), + Either::Left(_tuple) => None, + Either::Right(record) => docs_from_ast(record), } } AttrDefId::AdtId(it) => match it { diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 3e1521870..faf3566f4 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -57,9 +57,9 @@ mod tests; use std::sync::Arc; +use either::Either; use hir_expand::{ - ast_id_map::FileAstId, diagnostics::DiagnosticSink, either::Either, name::Name, InFile, - MacroDefId, + ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId, }; use once_cell::sync::Lazy; use ra_arena::Arena; @@ -287,10 +287,10 @@ impl ModuleData { ) -> InFile> { if let Some(file_id) = self.definition { let sf = db.parse(file_id).tree(); - return InFile::new(file_id.into(), Either::A(sf)); + return InFile::new(file_id.into(), Either::Left(sf)); } let decl = self.declaration.unwrap(); - InFile::new(decl.file_id, Either::B(decl.to_node(db))) + InFile::new(decl.file_id, Either::Right(decl.to_node(db))) } /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 5196b67ca..de4e706c2 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -7,10 +7,10 @@ use std::{ops::Index, sync::Arc}; +use either::Either; use hir_expand::{ ast_id_map::AstIdMap, db::AstDatabase, - either::Either, hygiene::Hygiene, name::{AsName, Name}, }; @@ -324,7 +324,7 @@ impl RawItemsCollector { is_extern_crate: false, is_macro_use: false, }; - buf.push((import_data, Either::A(AstPtr::new(use_tree)))); + buf.push((import_data, Either::Left(AstPtr::new(use_tree)))); }, ); for (import_data, ptr) in buf { @@ -355,7 +355,7 @@ impl RawItemsCollector { current_module, attrs, import_data, - Either::B(AstPtr::new(&extern_crate)), + Either::Right(AstPtr::new(&extern_crate)), ); } } diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index ff252fe44..3030dcdf6 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -2,8 +2,8 @@ use std::{iter, sync::Arc}; +use either::Either; use hir_expand::{ - either::Either, hygiene::Hygiene, name::{self, AsName, Name}, }; @@ -111,7 +111,7 @@ impl Path { ast::PathSegmentKind::Name(name_ref) => { // FIXME: this should just return name match hygiene.name_ref_to_name(name_ref) { - Either::A(name) => { + Either::Left(name) => { let args = segment .type_arg_list() .and_then(GenericArgs::from_ast) @@ -125,7 +125,7 @@ impl Path { let segment = PathSegment { name, args_and_bindings: args }; segments.push(segment); } - Either::B(crate_id) => { + Either::Right(crate_id) => { kind = PathKind::DollarCrate(crate_id); break; } @@ -347,7 +347,7 @@ fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> Opt let res = match segment.kind()? { ast::PathSegmentKind::Name(name_ref) => { match hygiene.name_ref_to_name(name_ref) { - Either::A(name) => { + Either::Left(name) => { // no type args in use let mut res = prefix.unwrap_or_else(|| Path { kind: PathKind::Plain, @@ -359,7 +359,7 @@ fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> Opt }); res } - Either::B(crate_id) => { + Either::Right(crate_id) => { return Some(Path::from_simple_segments( PathKind::DollarCrate(crate_id), iter::empty(), -- cgit v1.2.3 From 1bb59a7d08d10d247da265ef58835f9979ec36b7 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Tue, 3 Dec 2019 14:58:29 -0500 Subject: Three-state enum for module origin --- crates/ra_hir_def/src/nameres.rs | 91 ++++++++++++++++++++++++------ crates/ra_hir_def/src/nameres/collector.rs | 7 +-- 2 files changed, 78 insertions(+), 20 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index faf3566f4..cf2a83191 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -100,19 +100,83 @@ impl std::ops::Index for CrateDefMap { } } +#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] +pub enum ModuleOrigin { + /// It should not be `None` after collecting definitions. + Root(Option), + /// Note that non-inline modules, by definition, live inside non-macro file. + File(AstId, FileId), + Inline(AstId), + Block(AstId), +} + +impl Default for ModuleOrigin { + fn default() -> Self { + ModuleOrigin::Root(None) + } +} + +impl ModuleOrigin { + pub fn root(file_id: FileId) -> Self { + ModuleOrigin::Root(Some(file_id)) + } + + pub fn not_sure_file(file: Option, module: AstId) -> Self { + match file { + None => ModuleOrigin::Inline(module), + Some(file) => ModuleOrigin::File(module, file), + } + } + + pub fn not_sure_mod(file: FileId, module: Option>) -> Self { + match module { + None => ModuleOrigin::root(file), + Some(module) => ModuleOrigin::File(module, file), + } + } + + pub fn declaration(&self) -> Option> { + match self { + ModuleOrigin::File(m, _) | ModuleOrigin::Inline(m) => Some(*m), + ModuleOrigin::Root(_) | ModuleOrigin::Block(_) => None, + } + } + + pub fn file_id(&self) -> Option { + match self { + ModuleOrigin::File(_, file_id) | ModuleOrigin::Root(Some(file_id)) => Some(*file_id), + _ => None, + } + } + + /// Returns a node which defines this module. + /// That is, a file or a `mod foo {}` with items. + pub fn definition_source( + &self, + db: &impl DefDatabase, + ) -> InFile> { + match self { + ModuleOrigin::File(_, file_id) | ModuleOrigin::Root(Some(file_id)) => { + let file_id = *file_id; + let sf = db.parse(file_id).tree(); + return InFile::new(file_id.into(), Either::Left(sf)); + } + ModuleOrigin::Root(None) => unreachable!(), + ModuleOrigin::Inline(m) => InFile::new(m.file_id, Either::Right(m.to_node(db))), + // FIXME: right now it's never constructed, so it's fine to omit + ModuleOrigin::Block(b) => unimplemented!(), + } + } +} + #[derive(Default, Debug, PartialEq, Eq)] pub struct ModuleData { pub parent: Option, pub children: FxHashMap, pub scope: ModuleScope, - // FIXME: these can't be both null, we need a three-state enum here. - /// None for root - pub declaration: Option>, - /// None for inline modules. - /// - /// Note that non-inline modules, by definition, live inside non-macro file. - pub definition: Option, + /// Where does this module come from? + pub origin: ModuleOrigin, pub impls: Vec, } @@ -262,7 +326,7 @@ impl CrateDefMap { pub fn modules_for_file(&self, file_id: FileId) -> impl Iterator + '_ { self.modules .iter() - .filter(move |(_id, data)| data.definition == Some(file_id)) + .filter(move |(_id, data)| data.origin.file_id() == Some(file_id)) .map(|(id, _data)| id) } @@ -285,18 +349,13 @@ impl ModuleData { &self, db: &impl DefDatabase, ) -> InFile> { - if let Some(file_id) = self.definition { - let sf = db.parse(file_id).tree(); - return InFile::new(file_id.into(), Either::Left(sf)); - } - let decl = self.declaration.unwrap(); - InFile::new(decl.file_id, Either::Right(decl.to_node(db))) + self.origin.definition_source(db) } /// Returns a node which declares this module, either a `mod foo;` or a `mod foo {}`. - /// `None` for the crate root. + /// `None` for the crate root or block. pub fn declaration_source(&self, db: &impl DefDatabase) -> Option> { - let decl = self.declaration?; + let decl = self.origin.declaration()?; let value = decl.to_node(db); Some(InFile { file_id: decl.file_id, value }) } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index d4bfcae1d..6f4a3e42e 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -19,7 +19,7 @@ use crate::{ db::DefDatabase, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, - raw, BuiltinShadowMode, CrateDefMap, ModuleData, Resolution, ResolveMode, + raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode, }, path::{Path, PathKind}, per_ns::PerNs, @@ -131,7 +131,7 @@ where let file_id = crate_graph.crate_root(self.def_map.krate); let raw_items = self.db.raw_items(file_id.into()); let module_id = self.def_map.root; - self.def_map.modules[module_id].definition = Some(file_id); + self.def_map.modules[module_id].origin = ModuleOrigin::root(file_id); ModCollector { def_collector: &mut *self, module_id, @@ -669,8 +669,7 @@ where let modules = &mut self.def_collector.def_map.modules; let res = modules.alloc(ModuleData::default()); modules[res].parent = Some(self.module_id); - modules[res].declaration = Some(declaration); - modules[res].definition = definition; + modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration); modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone(); modules[self.module_id].children.insert(name.clone(), res); let resolution = Resolution { -- cgit v1.2.3 From 7cbedc50bcf048c87f141a85418581076d67fc7a Mon Sep 17 00:00:00 2001 From: ice1000 Date: Tue, 3 Dec 2019 15:23:21 -0500 Subject: Fix test compilation --- crates/ra_hir_def/src/nameres.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index cf2a83191..ca8cbcd42 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -164,7 +164,7 @@ impl ModuleOrigin { ModuleOrigin::Root(None) => unreachable!(), ModuleOrigin::Inline(m) => InFile::new(m.file_id, Either::Right(m.to_node(db))), // FIXME: right now it's never constructed, so it's fine to omit - ModuleOrigin::Block(b) => unimplemented!(), + ModuleOrigin::Block(_b) => unimplemented!(), } } } -- cgit v1.2.3 From 38853459e3d964cc7f635829cdc66f5faee33d85 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Tue, 3 Dec 2019 15:24:02 -0500 Subject: Add `ModuleSource::Block` --- crates/ra_hir_def/src/nameres.rs | 68 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index ca8cbcd42..feb2a4d32 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -63,9 +63,12 @@ use hir_expand::{ }; use once_cell::sync::Lazy; use ra_arena::Arena; -use ra_db::{CrateId, Edition, FileId}; +use ra_db::{CrateId, Edition, FileId, FilePosition}; use ra_prof::profile; -use ra_syntax::ast; +use ra_syntax::{ + ast::{self, AstNode}, + SyntaxNode, +}; use rustc_hash::FxHashMap; use crate::{ @@ -361,6 +364,67 @@ impl ModuleData { } } +pub enum ModuleSource { + SourceFile(ast::SourceFile), + Module(ast::Module), + Block(ast::Block), +} + +impl ModuleSource { + pub fn new( + db: &impl DefDatabase, + file_id: Option, + decl_id: Option>, + ) -> ModuleSource { + match (file_id, decl_id) { + (Some(file_id), _) => { + let source_file = db.parse(file_id).tree(); + ModuleSource::SourceFile(source_file) + } + (None, Some(item_id)) => { + let module = item_id.to_node(db); + assert!(module.item_list().is_some(), "expected inline module"); + ModuleSource::Module(module) + } + (None, None) => panic!(), + } + } + + // FIXME: this methods do not belong here + pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource { + let parse = db.parse(position.file_id); + match &ra_syntax::algo::find_node_at_offset::( + parse.tree().syntax(), + position.offset, + ) { + Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()), + _ => { + let source_file = parse.tree(); + ModuleSource::SourceFile(source_file) + } + } + } + + pub fn from_child_node(db: &impl DefDatabase, child: InFile<&SyntaxNode>) -> ModuleSource { + if let Some(m) = + child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) + { + ModuleSource::Module(m) + } else if let Some(b) = child.value.ancestors().filter_map(ast::Block::cast).next() { + ModuleSource::Block(b) + } else { + let file_id = child.file_id.original_file(db); + let source_file = db.parse(file_id).tree(); + ModuleSource::SourceFile(source_file) + } + } + + pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource { + let source_file = db.parse(file_id).tree(); + ModuleSource::SourceFile(source_file) + } +} + mod diagnostics { use hir_expand::diagnostics::DiagnosticSink; use ra_db::RelativePathBuf; -- cgit v1.2.3 From 5c5f90ba57c83499a44af33bf8b91b24254fb685 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Tue, 3 Dec 2019 15:28:40 -0500 Subject: Confluent `ModuleSource` usage --- crates/ra_hir_def/src/nameres.rs | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index feb2a4d32..e356515cb 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -57,7 +57,6 @@ mod tests; use std::sync::Arc; -use either::Either; use hir_expand::{ ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId, }; @@ -154,20 +153,16 @@ impl ModuleOrigin { /// Returns a node which defines this module. /// That is, a file or a `mod foo {}` with items. - pub fn definition_source( - &self, - db: &impl DefDatabase, - ) -> InFile> { + pub fn definition_source(&self, db: &impl DefDatabase) -> InFile { match self { ModuleOrigin::File(_, file_id) | ModuleOrigin::Root(Some(file_id)) => { let file_id = *file_id; let sf = db.parse(file_id).tree(); - return InFile::new(file_id.into(), Either::Left(sf)); + return InFile::new(file_id.into(), ModuleSource::SourceFile(sf)); } ModuleOrigin::Root(None) => unreachable!(), - ModuleOrigin::Inline(m) => InFile::new(m.file_id, Either::Right(m.to_node(db))), - // FIXME: right now it's never constructed, so it's fine to omit - ModuleOrigin::Block(_b) => unimplemented!(), + ModuleOrigin::Inline(m) => InFile::new(m.file_id, ModuleSource::Module(m.to_node(db))), + ModuleOrigin::Block(b) => InFile::new(b.file_id, ModuleSource::Block(b.to_node(db))), } } } @@ -348,10 +343,7 @@ impl CrateDefMap { impl ModuleData { /// Returns a node which defines this module. That is, a file or a `mod foo {}` with items. - pub fn definition_source( - &self, - db: &impl DefDatabase, - ) -> InFile> { + pub fn definition_source(&self, db: &impl DefDatabase) -> InFile { self.origin.definition_source(db) } -- cgit v1.2.3 From 032eb3d68e07f087ac531d48f956a79948baa4b9 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Tue, 3 Dec 2019 15:58:38 -0500 Subject: Remove almost unused `ModuleSource::new` --- crates/ra_hir_def/src/nameres.rs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index e356515cb..ce318571c 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -356,6 +356,7 @@ impl ModuleData { } } +#[derive(Debug, Clone, PartialEq, Eq)] pub enum ModuleSource { SourceFile(ast::SourceFile), Module(ast::Module), @@ -363,25 +364,6 @@ pub enum ModuleSource { } impl ModuleSource { - pub fn new( - db: &impl DefDatabase, - file_id: Option, - decl_id: Option>, - ) -> ModuleSource { - match (file_id, decl_id) { - (Some(file_id), _) => { - let source_file = db.parse(file_id).tree(); - ModuleSource::SourceFile(source_file) - } - (None, Some(item_id)) => { - let module = item_id.to_node(db); - assert!(module.item_list().is_some(), "expected inline module"); - ModuleSource::Module(module) - } - (None, None) => panic!(), - } - } - // FIXME: this methods do not belong here pub fn from_position(db: &impl DefDatabase, position: FilePosition) -> ModuleSource { let parse = db.parse(position.file_id); -- cgit v1.2.3 From 088f50c0ab351d5ac072547a47c1ce7eeae029f3 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Wed, 4 Dec 2019 13:35:24 -0500 Subject: No block at the moment --- crates/ra_hir_def/src/nameres.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index ce318571c..f70235c99 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -109,7 +109,6 @@ pub enum ModuleOrigin { /// Note that non-inline modules, by definition, live inside non-macro file. File(AstId, FileId), Inline(AstId), - Block(AstId), } impl Default for ModuleOrigin { @@ -140,7 +139,7 @@ impl ModuleOrigin { pub fn declaration(&self) -> Option> { match self { ModuleOrigin::File(m, _) | ModuleOrigin::Inline(m) => Some(*m), - ModuleOrigin::Root(_) | ModuleOrigin::Block(_) => None, + ModuleOrigin::Root(_) => None, } } @@ -162,7 +161,6 @@ impl ModuleOrigin { } ModuleOrigin::Root(None) => unreachable!(), ModuleOrigin::Inline(m) => InFile::new(m.file_id, ModuleSource::Module(m.to_node(db))), - ModuleOrigin::Block(b) => InFile::new(b.file_id, ModuleSource::Block(b.to_node(db))), } } } @@ -360,7 +358,6 @@ impl ModuleData { pub enum ModuleSource { SourceFile(ast::SourceFile), Module(ast::Module), - Block(ast::Block), } impl ModuleSource { @@ -384,8 +381,6 @@ impl ModuleSource { child.value.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) { ModuleSource::Module(m) - } else if let Some(b) = child.value.ancestors().filter_map(ast::Block::cast).next() { - ModuleSource::Block(b) } else { let file_id = child.file_id.original_file(db); let source_file = db.parse(file_id).tree(); -- cgit v1.2.3 From 762915826ac6893036f8b5cd5e63677ed862f6d9 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Thu, 5 Dec 2019 08:19:27 -0500 Subject: Reduce visibility, use struct instead of tuples --- crates/ra_hir_def/src/nameres.rs | 43 +++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index f70235c99..01d67777d 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -107,8 +107,13 @@ pub enum ModuleOrigin { /// It should not be `None` after collecting definitions. Root(Option), /// Note that non-inline modules, by definition, live inside non-macro file. - File(AstId, FileId), - Inline(AstId), + File { + declaration: AstId, + definition: FileId, + }, + Inline { + definition: AstId, + }, } impl Default for ModuleOrigin { @@ -118,49 +123,47 @@ impl Default for ModuleOrigin { } impl ModuleOrigin { - pub fn root(file_id: FileId) -> Self { + fn root(file_id: FileId) -> Self { ModuleOrigin::Root(Some(file_id)) } - pub fn not_sure_file(file: Option, module: AstId) -> Self { + pub(crate) fn not_sure_file(file: Option, declaration: AstId) -> Self { match file { - None => ModuleOrigin::Inline(module), - Some(file) => ModuleOrigin::File(module, file), + None => ModuleOrigin::Inline { definition: declaration }, + Some(definition) => ModuleOrigin::File { declaration, definition }, } } - pub fn not_sure_mod(file: FileId, module: Option>) -> Self { - match module { - None => ModuleOrigin::root(file), - Some(module) => ModuleOrigin::File(module, file), - } - } - - pub fn declaration(&self) -> Option> { + fn declaration(&self) -> Option> { match self { - ModuleOrigin::File(m, _) | ModuleOrigin::Inline(m) => Some(*m), + ModuleOrigin::File { declaration: module, .. } + | ModuleOrigin::Inline { definition: module, .. } => Some(*module), ModuleOrigin::Root(_) => None, } } - pub fn file_id(&self) -> Option { + pub(crate) fn file_id(&self) -> Option { match self { - ModuleOrigin::File(_, file_id) | ModuleOrigin::Root(Some(file_id)) => Some(*file_id), + ModuleOrigin::File { definition: file_id, .. } | ModuleOrigin::Root(Some(file_id)) => { + Some(*file_id) + } _ => None, } } /// Returns a node which defines this module. /// That is, a file or a `mod foo {}` with items. - pub fn definition_source(&self, db: &impl DefDatabase) -> InFile { + fn definition_source(&self, db: &impl DefDatabase) -> InFile { match self { - ModuleOrigin::File(_, file_id) | ModuleOrigin::Root(Some(file_id)) => { + ModuleOrigin::File { definition: file_id, .. } | ModuleOrigin::Root(Some(file_id)) => { let file_id = *file_id; let sf = db.parse(file_id).tree(); return InFile::new(file_id.into(), ModuleSource::SourceFile(sf)); } ModuleOrigin::Root(None) => unreachable!(), - ModuleOrigin::Inline(m) => InFile::new(m.file_id, ModuleSource::Module(m.to_node(db))), + ModuleOrigin::Inline { definition } => { + InFile::new(definition.file_id, ModuleSource::Module(definition.to_node(db))) + } } } } -- cgit v1.2.3 From 7702f690a9592605be71104ec9d0b732af940fcc Mon Sep 17 00:00:00 2001 From: ice1000 Date: Thu, 5 Dec 2019 08:28:31 -0500 Subject: One pub function less is good! --- crates/ra_hir_def/src/nameres.rs | 5 ----- 1 file changed, 5 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 01d67777d..0a2b32bbd 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -390,11 +390,6 @@ impl ModuleSource { ModuleSource::SourceFile(source_file) } } - - pub fn from_file_id(db: &impl DefDatabase, file_id: FileId) -> ModuleSource { - let source_file = db.parse(file_id).tree(); - ModuleSource::SourceFile(source_file) - } } mod diagnostics { -- cgit v1.2.3 From 006a583381ab66f229c4d49531cb50687343eea3 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Thu, 5 Dec 2019 08:33:29 -0500 Subject: Use placeholder instead of `Option` --- crates/ra_hir_def/src/nameres.rs | 22 +++++++++------------- crates/ra_hir_def/src/nameres/collector.rs | 2 +- 2 files changed, 10 insertions(+), 14 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 0a2b32bbd..98bab1bfe 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -104,8 +104,9 @@ impl std::ops::Index for CrateDefMap { #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)] pub enum ModuleOrigin { - /// It should not be `None` after collecting definitions. - Root(Option), + CrateRoot { + definition: FileId, + }, /// Note that non-inline modules, by definition, live inside non-macro file. File { declaration: AstId, @@ -118,15 +119,11 @@ pub enum ModuleOrigin { impl Default for ModuleOrigin { fn default() -> Self { - ModuleOrigin::Root(None) + ModuleOrigin::CrateRoot { definition: FileId(0) } } } impl ModuleOrigin { - fn root(file_id: FileId) -> Self { - ModuleOrigin::Root(Some(file_id)) - } - pub(crate) fn not_sure_file(file: Option, declaration: AstId) -> Self { match file { None => ModuleOrigin::Inline { definition: declaration }, @@ -138,14 +135,14 @@ impl ModuleOrigin { match self { ModuleOrigin::File { declaration: module, .. } | ModuleOrigin::Inline { definition: module, .. } => Some(*module), - ModuleOrigin::Root(_) => None, + ModuleOrigin::CrateRoot { .. } => None, } } pub(crate) fn file_id(&self) -> Option { match self { - ModuleOrigin::File { definition: file_id, .. } | ModuleOrigin::Root(Some(file_id)) => { - Some(*file_id) + ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => { + Some(*definition) } _ => None, } @@ -155,12 +152,11 @@ impl ModuleOrigin { /// That is, a file or a `mod foo {}` with items. fn definition_source(&self, db: &impl DefDatabase) -> InFile { match self { - ModuleOrigin::File { definition: file_id, .. } | ModuleOrigin::Root(Some(file_id)) => { - let file_id = *file_id; + ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => { + let file_id = *definition; let sf = db.parse(file_id).tree(); return InFile::new(file_id.into(), ModuleSource::SourceFile(sf)); } - ModuleOrigin::Root(None) => unreachable!(), ModuleOrigin::Inline { definition } => { InFile::new(definition.file_id, ModuleSource::Module(definition.to_node(db))) } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 6f4a3e42e..9d948d4f4 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -131,7 +131,7 @@ where let file_id = crate_graph.crate_root(self.def_map.krate); let raw_items = self.db.raw_items(file_id.into()); let module_id = self.def_map.root; - self.def_map.modules[module_id].origin = ModuleOrigin::root(file_id); + self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; ModCollector { def_collector: &mut *self, module_id, -- cgit v1.2.3 From d15f300268fa955f8e9c04d51ca1dc528766f742 Mon Sep 17 00:00:00 2001 From: ice1000 Date: Thu, 5 Dec 2019 08:37:39 -0500 Subject: Publicize `file_id` to make `test_db` compile --- crates/ra_hir_def/src/nameres.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 98bab1bfe..bd237a7b3 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -139,7 +139,7 @@ impl ModuleOrigin { } } - pub(crate) fn file_id(&self) -> Option { + pub fn file_id(&self) -> Option { match self { ModuleOrigin::File { definition, .. } | ModuleOrigin::CrateRoot { definition } => { Some(*definition) -- cgit v1.2.3 From 0c0ce1ae418a2f3f4fc125bd701cdb327f607002 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 5 Dec 2019 15:16:59 +0100 Subject: Introduce ChildFromSource --- crates/ra_hir_def/src/child_from_source.rs | 276 +++++++++++++++++++++++++++++ crates/ra_hir_def/src/lib.rs | 1 + 2 files changed, 277 insertions(+) create mode 100644 crates/ra_hir_def/src/child_from_source.rs (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/child_from_source.rs b/crates/ra_hir_def/src/child_from_source.rs new file mode 100644 index 000000000..37d4b7870 --- /dev/null +++ b/crates/ra_hir_def/src/child_from_source.rs @@ -0,0 +1,276 @@ +//! When *constructing* `hir`, we start at some parent syntax node and recursively +//! lower the children. +//! +//! This modules allows one to go in the opposite direction: start with a syntax +//! node for a *child*, and get its hir. + +use either::Either; +use hir_expand::InFile; +use ra_syntax::{ast, AstNode, AstPtr}; + +use crate::{ + db::DefDatabase, + src::{HasChildSource, HasSource}, + AssocItemId, ConstId, EnumId, EnumVariantId, FunctionId, ImplId, Lookup, ModuleDefId, ModuleId, + StaticId, StructFieldId, TraitId, TypeAliasId, VariantId, +}; + +pub trait ChildFromSource { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option; +} + +impl ChildFromSource for TraitId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let data = db.trait_data(*self); + data.items + .iter() + .filter_map(|(_, item)| match item { + AssocItemId::FunctionId(it) => Some(*it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }) + } +} + +impl ChildFromSource for ImplId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let data = db.impl_data(*self); + data.items + .iter() + .filter_map(|item| match item { + AssocItemId::FunctionId(it) => Some(*it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }) + } +} + +impl ChildFromSource for ModuleId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let crate_def_map = db.crate_def_map(self.krate); + let res = crate_def_map[self.local_id] + .scope + .declarations() + .filter_map(|item| match item { + ModuleDefId::FunctionId(it) => Some(it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }); + res + } +} + +impl ChildFromSource for TraitId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let data = db.trait_data(*self); + data.items + .iter() + .filter_map(|(_, item)| match item { + AssocItemId::ConstId(it) => Some(*it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }) + } +} + +impl ChildFromSource for ImplId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let data = db.impl_data(*self); + data.items + .iter() + .filter_map(|item| match item { + AssocItemId::ConstId(it) => Some(*it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }) + } +} + +impl ChildFromSource for ModuleId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let crate_def_map = db.crate_def_map(self.krate); + let res = crate_def_map[self.local_id] + .scope + .declarations() + .filter_map(|item| match item { + ModuleDefId::ConstId(it) => Some(it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }); + res + } +} + +impl ChildFromSource for TraitId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let data = db.trait_data(*self); + data.items + .iter() + .filter_map(|(_, item)| match item { + AssocItemId::TypeAliasId(it) => Some(*it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }) + } +} + +impl ChildFromSource for ImplId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let data = db.impl_data(*self); + data.items + .iter() + .filter_map(|item| match item { + AssocItemId::TypeAliasId(it) => Some(*it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }) + } +} + +impl ChildFromSource for ModuleId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let crate_def_map = db.crate_def_map(self.krate); + let res = crate_def_map[self.local_id] + .scope + .declarations() + .filter_map(|item| match item { + ModuleDefId::TypeAliasId(it) => Some(it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }); + res + } +} + +impl ChildFromSource for ModuleId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let crate_def_map = db.crate_def_map(self.krate); + let res = crate_def_map[self.local_id] + .scope + .declarations() + .filter_map(|item| match item { + ModuleDefId::StaticId(it) => Some(it), + _ => None, + }) + .find(|func| { + let source = func.lookup(db).source(db); + same_source(&source, &child_source) + }); + res + } +} + +impl ChildFromSource> for VariantId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile>, + ) -> Option { + let arena_map = self.child_source(db); + let (local_id, _) = arena_map.as_ref().value.iter().find(|(_local_id, source)| { + child_source.file_id == arena_map.file_id + && match (source, &child_source.value) { + (Either::Left(a), Either::Left(b)) => AstPtr::new(a) == AstPtr::new(b), + (Either::Right(a), Either::Right(b)) => AstPtr::new(a) == AstPtr::new(b), + _ => false, + } + })?; + Some(StructFieldId { parent: *self, local_id }) + } +} + +impl ChildFromSource for EnumId { + fn child_from_source( + &self, + db: &impl DefDatabase, + child_source: InFile, + ) -> Option { + let arena_map = self.child_source(db); + let (local_id, _) = arena_map.as_ref().value.iter().find(|(_local_id, source)| { + child_source.file_id == arena_map.file_id + && AstPtr::new(*source) == AstPtr::new(&child_source.value) + })?; + Some(EnumVariantId { parent: *self, local_id }) + } +} + +/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are +/// equal if they point to exactly the same object. +/// +/// In general, we do not guarantee that we have exactly one instance of a +/// syntax tree for each file. We probably should add such guarantee, but, for +/// the time being, we will use identity-less AstPtr comparison. +fn same_source(s1: &InFile, s2: &InFile) -> bool { + s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new) +} diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index cfeacfded..e02622f62 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -30,6 +30,7 @@ mod trace; pub mod nameres; pub mod src; +pub mod child_from_source; #[cfg(test)] mod test_db; -- cgit v1.2.3 From 18f6a995d0fc1f45099f3cc810a5d55d5401b41b Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Thu, 5 Dec 2019 15:10:33 +0100 Subject: Add expansion infrastructure for derive macros --- crates/ra_hir_def/src/attr.rs | 4 +- crates/ra_hir_def/src/body.rs | 6 ++- crates/ra_hir_def/src/docs.rs | 2 +- crates/ra_hir_def/src/nameres/collector.rs | 73 ++++++++++++++++++++++++--- crates/ra_hir_def/src/nameres/raw.rs | 15 ++++++ crates/ra_hir_def/src/nameres/tests/macros.rs | 24 +++++++++ crates/ra_hir_def/src/path.rs | 5 ++ 7 files changed, 118 insertions(+), 11 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 7f9a6e7ca..2f8f02d82 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -61,7 +61,9 @@ impl Attrs { AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), }, AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), - AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), + AttrDefId::MacroDefId(it) => { + it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db)) + } AttrDefId::ImplId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::StaticId(it) => attrs_from_loc(it.lookup(db), db), diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index ef1816836..7b385f3fd 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -6,7 +6,9 @@ pub mod scope; use std::{ops::Index, sync::Arc}; use either::Either; -use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroDefId, MacroFileKind}; +use hir_expand::{ + hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId, MacroFileKind, +}; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstNode, AstPtr}; use rustc_hash::FxHashMap; @@ -46,7 +48,7 @@ impl Expander { if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { if let Some(def) = self.resolve_path_as_macro(db, &path) { - let call_id = def.as_call_id(db, ast_id); + let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); let file_id = call_id.as_file(MacroFileKind::Expr); if let Some(node) = db.parse_or_expand(file_id) { if let Some(expr) = ast::Expr::cast(node) { diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index 3fc6d6934..61727bd26 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -60,7 +60,7 @@ impl Documentation { docs_from_ast(&src.value[it.local_id]) } AttrDefId::TraitId(it) => docs_from_ast(&it.source(db).value), - AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id.to_node(db)), + AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id?.to_node(db)), AttrDefId::ConstId(it) => docs_from_ast(&it.lookup(db).source(db).value), AttrDefId::StaticId(it) => docs_from_ast(&it.lookup(db).source(db).value), AttrDefId::FunctionId(it) => docs_from_ast(&it.lookup(db).source(db).value), diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 9d948d4f4..08693cb13 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -4,9 +4,10 @@ //! resolves imports and expands macros. use hir_expand::{ + builtin_derive::find_builtin_derive, builtin_macro::find_builtin_macro, name::{self, AsName, Name}, - HirFileId, MacroCallId, MacroDefId, MacroDefKind, MacroFileKind, + HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, MacroFileKind, }; use ra_cfg::CfgOptions; use ra_db::{CrateId, FileId}; @@ -58,6 +59,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C glob_imports: FxHashMap::default(), unresolved_imports: Vec::new(), unexpanded_macros: Vec::new(), + unexpanded_attribute_macros: Vec::new(), mod_dirs: FxHashMap::default(), macro_stack_monitor: MacroStackMonitor::default(), poison_macros: FxHashSet::default(), @@ -102,6 +104,7 @@ struct DefCollector<'a, DB> { glob_imports: FxHashMap>, unresolved_imports: Vec<(LocalModuleId, LocalImportId, raw::ImportData)>, unexpanded_macros: Vec<(LocalModuleId, AstId, Path)>, + unexpanded_attribute_macros: Vec<(LocalModuleId, AstId, Path)>, mod_dirs: FxHashMap, /// Some macro use `$tt:tt which mean we have to handle the macro perfectly @@ -470,6 +473,8 @@ where fn resolve_macros(&mut self) -> ReachedFixedPoint { let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); + let mut attribute_macros = + std::mem::replace(&mut self.unexpanded_attribute_macros, Vec::new()); let mut resolved = Vec::new(); let mut res = ReachedFixedPoint::Yes; macros.retain(|(module_id, ast_id, path)| { @@ -482,7 +487,19 @@ where ); if let Some(def) = resolved_res.resolved_def.take_macros() { - let call_id = def.as_call_id(self.db, *ast_id); + let call_id = def.as_call_id(self.db, MacroCallKind::FnLike(*ast_id)); + resolved.push((*module_id, call_id, def)); + res = ReachedFixedPoint::No; + return false; + } + + true + }); + attribute_macros.retain(|(module_id, ast_id, path)| { + let resolved_res = self.resolve_attribute_macro(path); + + if let Some(def) = resolved_res { + let call_id = def.as_call_id(self.db, MacroCallKind::Attr(*ast_id)); resolved.push((*module_id, call_id, def)); res = ReachedFixedPoint::No; return false; @@ -492,6 +509,7 @@ where }); self.unexpanded_macros = macros; + self.unexpanded_attribute_macros = attribute_macros; for (module_id, macro_call_id, macro_def_id) in resolved { self.collect_macro_expansion(module_id, macro_call_id, macro_def_id); @@ -500,6 +518,20 @@ where res } + fn resolve_attribute_macro(&self, path: &Path) -> Option { + // FIXME this is currently super hacky, just enough to support the + // built-in derives + if let Some(name) = path.as_ident() { + // FIXME this should actually be handled with the normal name + // resolution; the std lib defines built-in stubs for the derives, + // but these are new-style `macro`s, which we don't support yet + if let Some(def_id) = find_builtin_derive(name) { + return Some(def_id); + } + } + None + } + fn collect_macro_expansion( &mut self, module_id: LocalModuleId, @@ -587,7 +619,9 @@ where .def_collector .unresolved_imports .push((self.module_id, import_id, self.raw_items[import_id].clone())), - raw::RawItemKind::Def(def) => self.define_def(&self.raw_items[def]), + raw::RawItemKind::Def(def) => { + self.define_def(&self.raw_items[def], &item.attrs) + } raw::RawItemKind::Macro(mac) => self.collect_macro(&self.raw_items[mac]), raw::RawItemKind::Impl(imp) => { let module = ModuleId { @@ -682,10 +716,16 @@ where res } - fn define_def(&mut self, def: &raw::DefData) { + fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); + // FIXME: check attrs to see if this is an attribute macro invocation; + // in which case we don't add the invocation, just a single attribute + // macro invocation + + self.collect_derives(attrs, def); + let name = def.name.clone(); let def: PerNs = match def.kind { raw::DefKind::Function(ast_id) => { @@ -736,6 +776,23 @@ where self.def_collector.update(self.module_id, None, &[(name, resolution)]) } + fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { + for derive_subtree in attrs.by_key("derive").tt_values() { + // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree + for tt in &derive_subtree.token_trees { + let ident = match &tt { + tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident, + tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok + _ => continue, // anything else would be an error (which we currently ignore) + }; + let path = Path::from_tt_ident(ident); + + let ast_id = AstId::new(self.file_id, def.kind.ast_id()); + self.def_collector.unexpanded_attribute_macros.push((self.module_id, ast_id, path)); + } + } + } + fn collect_macro(&mut self, mac: &raw::MacroData) { let ast_id = AstId::new(self.file_id, mac.ast_id); @@ -759,8 +816,8 @@ where if is_macro_rules(&mac.path) { if let Some(name) = &mac.name { let macro_id = MacroDefId { - ast_id, - krate: self.def_collector.def_map.krate, + ast_id: Some(ast_id), + krate: Some(self.def_collector.def_map.krate), kind: MacroDefKind::Declarative, }; self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export); @@ -773,7 +830,8 @@ where if let Some(macro_def) = mac.path.as_ident().and_then(|name| { self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) }) { - let macro_call_id = macro_def.as_call_id(self.def_collector.db, ast_id); + let macro_call_id = + macro_def.as_call_id(self.def_collector.db, MacroCallKind::FnLike(ast_id)); self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_def); return; @@ -829,6 +887,7 @@ mod tests { glob_imports: FxHashMap::default(), unresolved_imports: Vec::new(), unexpanded_macros: Vec::new(), + unexpanded_attribute_macros: Vec::new(), mod_dirs: FxHashMap::default(), macro_stack_monitor: monitor, poison_macros: FxHashSet::default(), diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index de4e706c2..a2821e1c3 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -184,6 +184,21 @@ pub(super) enum DefKind { TypeAlias(FileAstId), } +impl DefKind { + pub fn ast_id(&self) -> FileAstId { + match self { + DefKind::Function(it) => it.upcast(), + DefKind::Struct(it) => it.upcast(), + DefKind::Union(it) => it.upcast(), + DefKind::Enum(it) => it.upcast(), + DefKind::Const(it) => it.upcast(), + DefKind::Static(it) => it.upcast(), + DefKind::Trait(it) => it.upcast(), + DefKind::TypeAlias(it) => it.upcast(), + } + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub(super) struct Macro(RawId); impl_arena_id!(Macro); diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs index 704065633..cfa4ecb1a 100644 --- a/crates/ra_hir_def/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs @@ -600,3 +600,27 @@ fn macro_dollar_crate_is_correct_in_indirect_deps() { â‹®bar: t v "###); } + +#[test] +fn expand_derive() { + let map = compute_crate_def_map( + " + //- /main.rs + #[derive(Clone)] + struct Foo; + ", + ); + assert_eq!(map.modules[map.root].impls.len(), 1); +} + +#[test] +fn expand_multiple_derive() { + let map = compute_crate_def_map( + " + //- /main.rs + #[derive(Copy, Clone)] + struct Foo; + ", + ); + assert_eq!(map.modules[map.root].impls.len(), 2); +} diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 3030dcdf6..e547b2f03 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -199,6 +199,11 @@ impl Path { name_ref.as_name().into() } + /// Converts an `tt::Ident` into a single-identifier `Path`. + pub(crate) fn from_tt_ident(ident: &tt::Ident) -> Path { + ident.as_name().into() + } + /// `true` is this path is a single identifier, like `foo` pub fn is_ident(&self) -> bool { self.kind == PathKind::Plain && self.segments.len() == 1 -- cgit v1.2.3 From 518b5bf92789000416f18de3163c962b31ead0af Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 5 Dec 2019 17:55:38 +0100 Subject: Remove obsolete comment --- crates/ra_hir_def/src/per_ns.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/per_ns.rs b/crates/ra_hir_def/src/per_ns.rs index 00e866bf9..3a5105028 100644 --- a/crates/ra_hir_def/src/per_ns.rs +++ b/crates/ra_hir_def/src/per_ns.rs @@ -11,8 +11,6 @@ use crate::ModuleDefId; pub struct PerNs { pub types: Option, pub values: Option, - /// Since macros has different type, many methods simply ignore it. - /// We can only use special method like `get_macros` to access it. pub macros: Option, } -- cgit v1.2.3 From 76ff5b7c15b2c4e85895a49e5859e546d1d6227e Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Tue, 3 Dec 2019 19:33:48 +0800 Subject: Add tests --- crates/ra_hir_def/src/nameres/tests.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 87fcd617c..61cdd768e 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -558,3 +558,35 @@ fn cfg_test() { â‹®Foo: t v "###); } + +#[test] +fn infer_multiple_namespace() { + let map = def_map( + r#" +//- /main.rs +mod a { + pub type T = (); + pub use crate::b::*; +} + +use crate::a::T; + +mod b { + pub const T: () = (); +} +"#, + ); + + assert_snapshot!(map, @r###" + â‹®crate + â‹®T: t v + â‹®a: t + â‹®b: t + â‹® + â‹®crate::b + â‹®T: v + â‹® + â‹®crate::a + â‹®T: t v +"###); +} -- cgit v1.2.3 From 8c86963d47953045f2f33ee6620d305a6589641e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 5 Dec 2019 23:34:12 +0100 Subject: DynMap This might, or might not help us to reduce boilerplate associated with plumbing values from analysis to the IDE layer --- crates/ra_hir_def/src/child_by_source.rs | 139 +++++++++++++++ crates/ra_hir_def/src/child_from_source.rs | 276 ----------------------------- crates/ra_hir_def/src/dyn_map.rs | 108 +++++++++++ crates/ra_hir_def/src/keys.rs | 48 +++++ crates/ra_hir_def/src/lib.rs | 5 +- 5 files changed, 299 insertions(+), 277 deletions(-) create mode 100644 crates/ra_hir_def/src/child_by_source.rs delete mode 100644 crates/ra_hir_def/src/child_from_source.rs create mode 100644 crates/ra_hir_def/src/dyn_map.rs create mode 100644 crates/ra_hir_def/src/keys.rs (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs new file mode 100644 index 000000000..a3574a9db --- /dev/null +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -0,0 +1,139 @@ +//! When *constructing* `hir`, we start at some parent syntax node and recursively +//! lower the children. +//! +//! This modules allows one to go in the opposite direction: start with a syntax +//! node for a *child*, and get its hir. + +use either::Either; + +use crate::{ + db::DefDatabase, + dyn_map::DynMap, + keys, + src::{HasChildSource, HasSource}, + AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, StructFieldId, + TraitId, VariantId, +}; + +pub trait ChildBySource { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap; +} + +impl ChildBySource for TraitId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let data = db.trait_data(*self); + for (_name, item) in data.items.iter() { + match *item { + AssocItemId::FunctionId(func) => { + let src = func.lookup(db).source(db); + res[keys::FUNCTION].insert(src, func) + } + AssocItemId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + res[keys::CONST].insert(src, konst) + } + AssocItemId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + res[keys::TYPE_ALIAS].insert(src, ty) + } + } + } + + res + } +} + +impl ChildBySource for ImplId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let data = db.impl_data(*self); + for &item in data.items.iter() { + match item { + AssocItemId::FunctionId(func) => { + let src = func.lookup(db).source(db); + res[keys::FUNCTION].insert(src, func) + } + AssocItemId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + res[keys::CONST].insert(src, konst) + } + AssocItemId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + res[keys::TYPE_ALIAS].insert(src, ty) + } + } + } + + res + } +} + +impl ChildBySource for ModuleId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let crate_def_map = db.crate_def_map(self.krate); + for item in crate_def_map[self.local_id].scope.declarations() { + match item { + ModuleDefId::FunctionId(func) => { + let src = func.lookup(db).source(db); + res[keys::FUNCTION].insert(src, func) + } + ModuleDefId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + res[keys::CONST].insert(src, konst) + } + ModuleDefId::StaticId(statik) => { + let src = statik.lookup(db).source(db); + res[keys::STATIC].insert(src, statik) + } + ModuleDefId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + res[keys::TYPE_ALIAS].insert(src, ty) + } + _ => (), + } + } + + res + } +} + +impl ChildBySource for VariantId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let arena_map = self.child_source(db); + let arena_map = arena_map.as_ref(); + for (local_id, source) in arena_map.value.iter() { + let id = StructFieldId { parent: *self, local_id }; + match source { + Either::Left(source) => { + res[keys::TUPLE_FIELD].insert(arena_map.with_value(source.clone()), id) + } + Either::Right(source) => { + res[keys::RECORD_FIELD].insert(arena_map.with_value(source.clone()), id) + } + } + } + res + } +} + +impl ChildBySource for EnumId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + + let arena_map = self.child_source(db); + let arena_map = arena_map.as_ref(); + for (local_id, source) in arena_map.value.iter() { + let id = EnumVariantId { parent: *self, local_id }; + res[keys::ENUM_VARIANT].insert(arena_map.with_value(source.clone()), id) + } + + res + } +} diff --git a/crates/ra_hir_def/src/child_from_source.rs b/crates/ra_hir_def/src/child_from_source.rs deleted file mode 100644 index 37d4b7870..000000000 --- a/crates/ra_hir_def/src/child_from_source.rs +++ /dev/null @@ -1,276 +0,0 @@ -//! When *constructing* `hir`, we start at some parent syntax node and recursively -//! lower the children. -//! -//! This modules allows one to go in the opposite direction: start with a syntax -//! node for a *child*, and get its hir. - -use either::Either; -use hir_expand::InFile; -use ra_syntax::{ast, AstNode, AstPtr}; - -use crate::{ - db::DefDatabase, - src::{HasChildSource, HasSource}, - AssocItemId, ConstId, EnumId, EnumVariantId, FunctionId, ImplId, Lookup, ModuleDefId, ModuleId, - StaticId, StructFieldId, TraitId, TypeAliasId, VariantId, -}; - -pub trait ChildFromSource { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option; -} - -impl ChildFromSource for TraitId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let data = db.trait_data(*self); - data.items - .iter() - .filter_map(|(_, item)| match item { - AssocItemId::FunctionId(it) => Some(*it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }) - } -} - -impl ChildFromSource for ImplId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let data = db.impl_data(*self); - data.items - .iter() - .filter_map(|item| match item { - AssocItemId::FunctionId(it) => Some(*it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }) - } -} - -impl ChildFromSource for ModuleId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let crate_def_map = db.crate_def_map(self.krate); - let res = crate_def_map[self.local_id] - .scope - .declarations() - .filter_map(|item| match item { - ModuleDefId::FunctionId(it) => Some(it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }); - res - } -} - -impl ChildFromSource for TraitId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let data = db.trait_data(*self); - data.items - .iter() - .filter_map(|(_, item)| match item { - AssocItemId::ConstId(it) => Some(*it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }) - } -} - -impl ChildFromSource for ImplId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let data = db.impl_data(*self); - data.items - .iter() - .filter_map(|item| match item { - AssocItemId::ConstId(it) => Some(*it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }) - } -} - -impl ChildFromSource for ModuleId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let crate_def_map = db.crate_def_map(self.krate); - let res = crate_def_map[self.local_id] - .scope - .declarations() - .filter_map(|item| match item { - ModuleDefId::ConstId(it) => Some(it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }); - res - } -} - -impl ChildFromSource for TraitId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let data = db.trait_data(*self); - data.items - .iter() - .filter_map(|(_, item)| match item { - AssocItemId::TypeAliasId(it) => Some(*it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }) - } -} - -impl ChildFromSource for ImplId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let data = db.impl_data(*self); - data.items - .iter() - .filter_map(|item| match item { - AssocItemId::TypeAliasId(it) => Some(*it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }) - } -} - -impl ChildFromSource for ModuleId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let crate_def_map = db.crate_def_map(self.krate); - let res = crate_def_map[self.local_id] - .scope - .declarations() - .filter_map(|item| match item { - ModuleDefId::TypeAliasId(it) => Some(it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }); - res - } -} - -impl ChildFromSource for ModuleId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let crate_def_map = db.crate_def_map(self.krate); - let res = crate_def_map[self.local_id] - .scope - .declarations() - .filter_map(|item| match item { - ModuleDefId::StaticId(it) => Some(it), - _ => None, - }) - .find(|func| { - let source = func.lookup(db).source(db); - same_source(&source, &child_source) - }); - res - } -} - -impl ChildFromSource> for VariantId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile>, - ) -> Option { - let arena_map = self.child_source(db); - let (local_id, _) = arena_map.as_ref().value.iter().find(|(_local_id, source)| { - child_source.file_id == arena_map.file_id - && match (source, &child_source.value) { - (Either::Left(a), Either::Left(b)) => AstPtr::new(a) == AstPtr::new(b), - (Either::Right(a), Either::Right(b)) => AstPtr::new(a) == AstPtr::new(b), - _ => false, - } - })?; - Some(StructFieldId { parent: *self, local_id }) - } -} - -impl ChildFromSource for EnumId { - fn child_from_source( - &self, - db: &impl DefDatabase, - child_source: InFile, - ) -> Option { - let arena_map = self.child_source(db); - let (local_id, _) = arena_map.as_ref().value.iter().find(|(_local_id, source)| { - child_source.file_id == arena_map.file_id - && AstPtr::new(*source) == AstPtr::new(&child_source.value) - })?; - Some(EnumVariantId { parent: *self, local_id }) - } -} - -/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are -/// equal if they point to exactly the same object. -/// -/// In general, we do not guarantee that we have exactly one instance of a -/// syntax tree for each file. We probably should add such guarantee, but, for -/// the time being, we will use identity-less AstPtr comparison. -fn same_source(s1: &InFile, s2: &InFile) -> bool { - s1.as_ref().map(AstPtr::new) == s2.as_ref().map(AstPtr::new) -} diff --git a/crates/ra_hir_def/src/dyn_map.rs b/crates/ra_hir_def/src/dyn_map.rs new file mode 100644 index 000000000..6f269d7b0 --- /dev/null +++ b/crates/ra_hir_def/src/dyn_map.rs @@ -0,0 +1,108 @@ +//! This module defines a `DynMap` -- a container for heterogeneous maps. +//! +//! This means that `DynMap` stores a bunch of hash maps inside, and those maps +//! can be of different types. +//! +//! It is used like this: +//! +//! ``` +//! // keys define submaps of a `DynMap` +//! const STRING_TO_U32: Key = Key::new(); +//! const U32_TO_VEC: Key> = Key::new(); +//! +//! // Note: concrete type, no type params! +//! let mut map = DynMap::new(); +//! +//! // To access a specific map, index the `DynMap` by `Key`: +//! map[STRING_TO_U32].insert("hello".to_string(), 92); +//! let value = map[U32_TO_VEC].get(92); +//! assert!(value.is_none()); +//! ``` +//! +//! This is a work of fiction. Any similarities to Kotlin's `BindingContext` are +//! a coincidence. +use std::{ + hash::Hash, + marker::PhantomData, + ops::{Index, IndexMut}, +}; + +use anymap::Map; +use rustc_hash::FxHashMap; + +pub struct Key { + _phantom: PhantomData<(K, V, P)>, +} + +impl Key { + pub(crate) const fn new() -> Key { + Key { _phantom: PhantomData } + } +} + +impl Copy for Key {} + +impl Clone for Key { + fn clone(&self) -> Key { + *self + } +} + +pub trait Policy { + type K; + type V; + + fn insert(map: &mut DynMap, key: Self::K, value: Self::V); + fn get<'a>(map: &'a DynMap, key: &Self::K) -> Option<&'a Self::V>; +} + +impl Policy for (K, V) { + type K = K; + type V = V; + fn insert(map: &mut DynMap, key: K, value: V) { + map.map.entry::>().or_insert_with(Default::default).insert(key, value); + } + fn get<'a>(map: &'a DynMap, key: &K) -> Option<&'a V> { + map.map.get::>()?.get(key) + } +} + +pub struct DynMap { + pub(crate) map: Map, +} + +impl Default for DynMap { + fn default() -> Self { + DynMap { map: Map::new() } + } +} + +#[repr(transparent)] +pub struct KeyMap { + map: DynMap, + _phantom: PhantomData, +} + +impl KeyMap> { + pub fn insert(&mut self, key: P::K, value: P::V) { + P::insert(&mut self.map, key, value) + } + pub fn get(&self, key: &P::K) -> Option<&P::V> { + P::get(&self.map, key) + } +} + +impl Index> for DynMap { + type Output = KeyMap>; + fn index(&self, _key: Key) -> &Self::Output { + // Safe due to `#[repr(transparent)]`. + unsafe { std::mem::transmute::<&DynMap, &KeyMap>>(self) } + } +} + +impl IndexMut> for DynMap { + fn index_mut(&mut self, _key: Key) -> &mut Self::Output { + // Safe due to `#[repr(transparent)]`. + unsafe { std::mem::transmute::<&mut DynMap, &mut KeyMap>>(self) } + } +} diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs new file mode 100644 index 000000000..447b7e3ba --- /dev/null +++ b/crates/ra_hir_def/src/keys.rs @@ -0,0 +1,48 @@ +//! keys to be used with `DynMap` + +use std::marker::PhantomData; + +use hir_expand::InFile; +use ra_syntax::{ast, AstNode, AstPtr}; +use rustc_hash::FxHashMap; + +use crate::{ + dyn_map::{DynMap, Policy}, + ConstId, EnumVariantId, FunctionId, StaticId, StructFieldId, TypeAliasId, +}; + +type Key = crate::dyn_map::Key, V, AstPtrPolicy>; + +pub const FUNCTION: Key = Key::new(); +pub const CONST: Key = Key::new(); +pub const STATIC: Key = Key::new(); +pub const ENUM_VARIANT: Key = Key::new(); +pub const TYPE_ALIAS: Key = Key::new(); +pub const TUPLE_FIELD: Key = Key::new(); +pub const RECORD_FIELD: Key = Key::new(); + +/// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are +/// equal if they point to exactly the same object. +/// +/// In general, we do not guarantee that we have exactly one instance of a +/// syntax tree for each file. We probably should add such guarantee, but, for +/// the time being, we will use identity-less AstPtr comparison. +pub struct AstPtrPolicy { + _phantom: PhantomData<(AST, ID)>, +} + +impl Policy for AstPtrPolicy { + type K = InFile; + type V = ID; + fn insert(map: &mut DynMap, key: InFile, value: ID) { + let key = key.as_ref().map(AstPtr::new); + map.map + .entry::>, ID>>() + .or_insert_with(Default::default) + .insert(key, value); + } + fn get<'a>(map: &'a DynMap, key: &InFile) -> Option<&'a ID> { + let key = key.as_ref().map(AstPtr::new); + map.map.get::>, ID>>()?.get(&key) + } +} diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index e02622f62..68e66d276 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -16,6 +16,9 @@ pub mod builtin_type; pub mod diagnostics; pub mod per_ns; +pub mod dyn_map; +pub mod keys; + pub mod adt; pub mod data; pub mod generics; @@ -30,7 +33,7 @@ mod trace; pub mod nameres; pub mod src; -pub mod child_from_source; +pub mod child_by_source; #[cfg(test)] mod test_db; -- cgit v1.2.3 From e5997e174666435acd5abb4531f833bd41bbdb00 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 7 Dec 2019 09:50:21 +0800 Subject: Push glob_imports only if non-exists --- crates/ra_hir_def/src/nameres/collector.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 08693cb13..252178b6b 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -352,10 +352,10 @@ where self.update(module_id, Some(import_id), &items); // record the glob import in case we add further items - self.glob_imports - .entry(m.local_id) - .or_default() - .push((module_id, import_id)); + let glob = self.glob_imports.entry(m.local_id).or_default(); + if !glob.iter().any(|it| *it == (module_id, import_id)) { + glob.push((module_id, import_id)); + } } } Some(ModuleDefId::AdtId(AdtId::EnumId(e))) => { -- cgit v1.2.3 From 51f4fb448f1993a20c9527a8e6d301a9202ce35a Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 7 Dec 2019 19:20:41 +0800 Subject: Refactor resolve_imports logic --- crates/ra_hir_def/src/nameres/collector.rs | 156 +++++++++++++++++------ crates/ra_hir_def/src/nameres/path_resolution.rs | 13 +- 2 files changed, 129 insertions(+), 40 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 252178b6b..3b3f30eec 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -58,6 +58,8 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C def_map, glob_imports: FxHashMap::default(), unresolved_imports: Vec::new(), + resolved_imports: Vec::new(), + unexpanded_macros: Vec::new(), unexpanded_attribute_macros: Vec::new(), mod_dirs: FxHashMap::default(), @@ -97,12 +99,41 @@ impl MacroStackMonitor { } } +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +enum PartialResolvedImport { + /// None of any namespaces is resolved + Unresolved, + /// One of namespaces is resolved + Indeterminate(PerNs), + /// All namespaces are resolved, OR it is came from other crate + Resolved(PerNs), +} + +impl PartialResolvedImport { + fn namespaces(&self) -> PerNs { + match self { + PartialResolvedImport::Unresolved => PerNs::none(), + PartialResolvedImport::Indeterminate(ns) => *ns, + PartialResolvedImport::Resolved(ns) => *ns, + } + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +struct ImportDirective { + module_id: LocalModuleId, + import_id: LocalImportId, + import: raw::ImportData, + status: PartialResolvedImport, +} + /// Walks the tree of module recursively struct DefCollector<'a, DB> { db: &'a DB, def_map: CrateDefMap, glob_imports: FxHashMap>, - unresolved_imports: Vec<(LocalModuleId, LocalImportId, raw::ImportData)>, + unresolved_imports: Vec, + resolved_imports: Vec, unexpanded_macros: Vec<(LocalModuleId, AstId, Path)>, unexpanded_attribute_macros: Vec<(LocalModuleId, AstId, Path)>, mod_dirs: FxHashMap, @@ -148,9 +179,11 @@ where let mut i = 0; loop { self.db.check_canceled(); - match (self.resolve_imports(), self.resolve_macros()) { - (ReachedFixedPoint::Yes, ReachedFixedPoint::Yes) => break, - _ => i += 1, + self.resolve_imports(); + + match self.resolve_macros() { + ReachedFixedPoint::Yes => break, + ReachedFixedPoint::No => i += 1, } if i == 1000 { log::error!("name resolution is stuck"); @@ -158,10 +191,26 @@ where } } + // Resolve all indeterminate resolved imports again + // As some of the macros will expand newly import shadowing partial resolved imports + // FIXME: We maybe could skip this, if we handle the Indetermine imports in `resolve_imports` + // correctly + let partial_resolved = self.resolved_imports.iter().filter_map(|directive| { + if let PartialResolvedImport::Indeterminate(_) = directive.status { + let mut directive = directive.clone(); + directive.status = PartialResolvedImport::Unresolved; + Some(directive) + } else { + None + } + }); + self.unresolved_imports.extend(partial_resolved); + self.resolve_imports(); + let unresolved_imports = std::mem::replace(&mut self.unresolved_imports, Vec::new()); // show unresolved imports in completion, etc - for (module_id, import, import_data) in unresolved_imports { - self.record_resolved_import(module_id, PerNs::none(), import, &import_data) + for directive in unresolved_imports { + self.record_resolved_import(&directive) } } @@ -262,31 +311,43 @@ where } } - fn resolve_imports(&mut self) -> ReachedFixedPoint { - let mut imports = std::mem::replace(&mut self.unresolved_imports, Vec::new()); - let mut resolved = Vec::new(); - imports.retain(|(module_id, import, import_data)| { - let (def, fp) = self.resolve_import(*module_id, import_data); - if fp == ReachedFixedPoint::Yes { - resolved.push((*module_id, def, *import, import_data.clone())) + /// Import resolution + /// + /// This is a fix point algorithm. We resolve imports until no forward + /// progress in resolving imports is made + fn resolve_imports(&mut self) { + let mut n_previous_unresolved = self.unresolved_imports.len() + 1; + + while self.unresolved_imports.len() < n_previous_unresolved { + n_previous_unresolved = self.unresolved_imports.len(); + let imports = std::mem::replace(&mut self.unresolved_imports, Vec::new()); + for mut directive in imports { + directive.status = self.resolve_import(directive.module_id, &directive.import); + + match directive.status { + PartialResolvedImport::Indeterminate(_) => { + self.record_resolved_import(&directive); + // FIXME: For avoid performance regression, + // we consider an imported resolved if it is indeterminate (i.e not all namespace resolved) + self.resolved_imports.push(directive) + } + PartialResolvedImport::Resolved(_) => { + self.record_resolved_import(&directive); + self.resolved_imports.push(directive) + } + PartialResolvedImport::Unresolved => { + self.unresolved_imports.push(directive); + } + } } - fp == ReachedFixedPoint::No - }); - self.unresolved_imports = imports; - // Resolves imports, filling-in module scopes - let result = - if resolved.is_empty() { ReachedFixedPoint::Yes } else { ReachedFixedPoint::No }; - for (module_id, def, import, import_data) in resolved { - self.record_resolved_import(module_id, def, import, &import_data) } - result } fn resolve_import( &self, module_id: LocalModuleId, import: &raw::ImportData, - ) -> (PerNs, ReachedFixedPoint) { + ) -> PartialResolvedImport { log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); if import.is_extern_crate { let res = self.def_map.resolve_name_in_extern_prelude( @@ -295,7 +356,7 @@ where .as_ident() .expect("extern crate should have been desugared to one-element path"), ); - (res, ReachedFixedPoint::Yes) + PartialResolvedImport::Resolved(res) } else { let res = self.def_map.resolve_path_fp_with_macro( self.db, @@ -305,17 +366,35 @@ where BuiltinShadowMode::Module, ); - (res.resolved_def, res.reached_fixedpoint) + let def = res.resolved_def; + if res.reached_fixedpoint == ReachedFixedPoint::No { + return PartialResolvedImport::Unresolved; + } + + if let Some(krate) = res.krate { + if krate != self.def_map.krate { + return PartialResolvedImport::Resolved(def); + } + } + + // Check whether all namespace is resolved + if def.take_types().is_some() + && def.take_values().is_some() + && def.take_macros().is_some() + { + PartialResolvedImport::Resolved(def) + } else { + PartialResolvedImport::Indeterminate(def) + } } } - fn record_resolved_import( - &mut self, - module_id: LocalModuleId, - def: PerNs, - import_id: LocalImportId, - import: &raw::ImportData, - ) { + fn record_resolved_import(&mut self, directive: &ImportDirective) { + let module_id = directive.module_id; + let import_id = directive.import_id; + let import = &directive.import; + let def = directive.status.namespaces(); + if import.is_glob { log::debug!("glob import: {:?}", import); match def.take_types() { @@ -615,10 +694,14 @@ where raw::RawItemKind::Module(m) => { self.collect_module(&self.raw_items[m], &item.attrs) } - raw::RawItemKind::Import(import_id) => self - .def_collector - .unresolved_imports - .push((self.module_id, import_id, self.raw_items[import_id].clone())), + raw::RawItemKind::Import(import_id) => { + self.def_collector.unresolved_imports.push(ImportDirective { + module_id: self.module_id, + import_id, + import: self.raw_items[import_id].clone(), + status: PartialResolvedImport::Unresolved, + }) + } raw::RawItemKind::Def(def) => { self.define_def(&self.raw_items[def], &item.attrs) } @@ -886,6 +969,7 @@ mod tests { def_map, glob_imports: FxHashMap::default(), unresolved_imports: Vec::new(), + resolved_imports: Vec::new(), unexpanded_macros: Vec::new(), unexpanded_attribute_macros: Vec::new(), mod_dirs: FxHashMap::default(), diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 42a75226b..aab4b1dd9 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -19,7 +19,7 @@ use crate::{ nameres::{BuiltinShadowMode, CrateDefMap}, path::{Path, PathKind}, per_ns::PerNs, - AdtId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, + AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, }; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -39,19 +39,21 @@ pub(super) struct ResolvePathResult { pub(super) resolved_def: PerNs, pub(super) segment_index: Option, pub(super) reached_fixedpoint: ReachedFixedPoint, + pub(super) krate: Option, } impl ResolvePathResult { fn empty(reached_fixedpoint: ReachedFixedPoint) -> ResolvePathResult { - ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None) + ResolvePathResult::with(PerNs::none(), reached_fixedpoint, None, None) } fn with( resolved_def: PerNs, reached_fixedpoint: ReachedFixedPoint, segment_index: Option, + krate: Option, ) -> ResolvePathResult { - ResolvePathResult { resolved_def, reached_fixedpoint, segment_index } + ResolvePathResult { resolved_def, reached_fixedpoint, segment_index, krate } } } @@ -175,6 +177,7 @@ impl CrateDefMap { def, ReachedFixedPoint::Yes, s.map(|s| s + i), + Some(module.krate), ); } @@ -201,6 +204,7 @@ impl CrateDefMap { PerNs::types(e.into()), ReachedFixedPoint::Yes, Some(i), + Some(self.krate), ); } } @@ -218,12 +222,13 @@ impl CrateDefMap { PerNs::types(s), ReachedFixedPoint::Yes, Some(i), + Some(self.krate), ); } }; } - ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None) + ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None, Some(self.krate)) } fn resolve_name_in_module( -- cgit v1.2.3 From 30fefcc08cc0c670ce541476491238d258ca55c1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 6 Dec 2019 17:35:05 +0100 Subject: Store GenericParams in arena --- crates/ra_hir_def/src/generics.rs | 25 +++++++++++++------------ crates/ra_hir_def/src/lib.rs | 10 ++++++++++ crates/ra_hir_def/src/resolver.rs | 2 +- 3 files changed, 24 insertions(+), 13 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 5f648ffc3..abe749a40 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -5,18 +5,19 @@ use std::sync::Arc; use hir_expand::name::{self, AsName, Name}; +use ra_arena::Arena; use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; use crate::{ db::DefDatabase, src::HasSource, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, ContainerId, GenericDefId, Lookup, + AdtId, AstItemDef, ContainerId, GenericDefId, LocalGenericParamId, Lookup, }; /// Data about a generic parameter (to a function, struct, impl, ...). #[derive(Clone, PartialEq, Eq, Debug)] -pub struct GenericParam { +pub struct GenericParamData { // FIXME: give generic params proper IDs pub idx: u32, pub name: Name, @@ -27,7 +28,7 @@ pub struct GenericParam { #[derive(Clone, PartialEq, Eq, Debug)] pub struct GenericParams { pub parent_params: Option>, - pub params: Vec, + pub params: Arena, pub where_predicates: Vec, } @@ -56,7 +57,7 @@ impl GenericParams { parent_params: Option>, ) -> GenericParams { let mut generics = - GenericParams { params: Vec::new(), parent_params, where_predicates: Vec::new() }; + GenericParams { params: Arena::default(), parent_params, where_predicates: Vec::new() }; let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; // FIXME: add `: Sized` bound for everything except for `Self` in traits match def { @@ -66,7 +67,7 @@ impl GenericParams { GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), GenericDefId::TraitId(it) => { // traits get the Self type as an implicit first type parameter - generics.params.push(GenericParam { + generics.params.alloc(GenericParamData { idx: start, name: name::SELF_TYPE, default: None, @@ -110,8 +111,8 @@ impl GenericParams { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` let default = type_param.default_type().map(TypeRef::from_ast); - let param = GenericParam { idx: idx as u32 + start, name: name.clone(), default }; - self.params.push(param); + let param = GenericParamData { idx: idx as u32 + start, name: name.clone(), default }; + self.params.alloc(param); let type_ref = TypeRef::Path(name.into()); self.fill_bounds(&type_param, type_ref); @@ -140,8 +141,8 @@ impl GenericParams { self.where_predicates.push(WherePredicate { type_ref, bound }); } - pub fn find_by_name(&self, name: &Name) -> Option<&GenericParam> { - self.params.iter().find(|p| &p.name == name) + pub fn find_by_name(&self, name: &Name) -> Option<&GenericParamData> { + self.params.iter().map(|(_id, data)| data).find(|p| &p.name == name) } pub fn count_parent_params(&self) -> usize { @@ -153,14 +154,14 @@ impl GenericParams { parent_count + self.params.len() } - fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParam)) { + fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParamData)) { if let Some(parent) = &self.parent_params { parent.for_each_param(f); } - self.params.iter().for_each(f); + self.params.iter().map(|(_id, data)| data).for_each(f); } - pub fn params_including_parent(&self) -> Vec<&GenericParam> { + pub fn params_including_parent(&self) -> Vec<&GenericParamData> { let mut vec = Vec::with_capacity(self.count_params_including_parent()); self.for_each_param(&mut |p| vec.push(p)); vec diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 68e66d276..b8dfc0ab1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -317,6 +317,16 @@ macro_rules! impl_froms { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct GenericParamId { + pub parent: GenericDefId, + pub local_id: LocalGenericParamId, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct LocalGenericParamId(RawId); +impl_arena_id!(LocalGenericParamId); + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ContainerId { ModuleId(ModuleId), diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 7d4df222e..ee19d79a7 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -426,7 +426,7 @@ impl Scope { } } Scope::GenericParams { params, .. } => { - for param in params.params.iter() { + for (_id, param) in params.params.iter() { f(param.name.clone(), ScopeDef::GenericParam(param.idx)) } } -- cgit v1.2.3 From 8e9837df21942ca12a5aece0a868ea46eb405742 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 7 Dec 2019 11:50:36 +0100 Subject: Remove idx and parent generics from generics This makes `hir_def::GenericParams` flatter. The logic for re-numbering the params is moved to hir instead. --- crates/ra_hir_def/src/generics.rs | 90 +++++++++------------------------------ crates/ra_hir_def/src/resolver.rs | 38 ++++++++++------- 2 files changed, 42 insertions(+), 86 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index abe749a40..94ce83564 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -12,14 +12,12 @@ use crate::{ db::DefDatabase, src::HasSource, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, ContainerId, GenericDefId, LocalGenericParamId, Lookup, + AdtId, AstItemDef, GenericDefId, LocalGenericParamId, Lookup, }; /// Data about a generic parameter (to a function, struct, impl, ...). #[derive(Clone, PartialEq, Eq, Debug)] pub struct GenericParamData { - // FIXME: give generic params proper IDs - pub idx: u32, pub name: Name, pub default: Option, } @@ -27,7 +25,6 @@ pub struct GenericParamData { /// Data about the generic parameters of a function, struct, impl, etc. #[derive(Clone, PartialEq, Eq, Debug)] pub struct GenericParams { - pub parent_params: Option>, pub params: Arena, pub where_predicates: Vec, } @@ -47,51 +44,40 @@ impl GenericParams { db: &impl DefDatabase, def: GenericDefId, ) -> Arc { - let parent_generics = parent_generic_def(db, def).map(|it| db.generic_params(it)); - Arc::new(GenericParams::new(db, def.into(), parent_generics)) + Arc::new(GenericParams::new(db, def.into())) } - fn new( - db: &impl DefDatabase, - def: GenericDefId, - parent_params: Option>, - ) -> GenericParams { - let mut generics = - GenericParams { params: Arena::default(), parent_params, where_predicates: Vec::new() }; - let start = generics.parent_params.as_ref().map(|p| p.params.len()).unwrap_or(0) as u32; + fn new(db: &impl DefDatabase, def: GenericDefId) -> GenericParams { + let mut generics = GenericParams { params: Arena::default(), where_predicates: Vec::new() }; // FIXME: add `: Sized` bound for everything except for `Self` in traits match def { - GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value, start), - GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value, start), - GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value, start), - GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value, start), + GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value), + GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value), + GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value), + GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value), GenericDefId::TraitId(it) => { // traits get the Self type as an implicit first type parameter - generics.params.alloc(GenericParamData { - idx: start, - name: name::SELF_TYPE, - default: None, - }); - generics.fill(&it.source(db).value, start + 1); + generics.params.alloc(GenericParamData { name: name::SELF_TYPE, default: None }); + generics.fill(&it.source(db).value); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar let self_param = TypeRef::Path(name::SELF_TYPE.into()); generics.fill_bounds(&it.source(db).value, self_param); } - GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value, start), + GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value), // Note that we don't add `Self` here: in `impl`s, `Self` is not a // type-parameter, but rather is a type-alias for impl's target // type, so this is handled by the resolver. - GenericDefId::ImplId(it) => generics.fill(&it.source(db).value, start), + GenericDefId::ImplId(it) => generics.fill(&it.source(db).value), GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} } generics } - fn fill(&mut self, node: &impl TypeParamsOwner, start: u32) { + fn fill(&mut self, node: &impl TypeParamsOwner) { if let Some(params) = node.type_param_list() { - self.fill_params(params, start) + self.fill_params(params) } if let Some(where_clause) = node.where_clause() { self.fill_where_predicates(where_clause); @@ -106,12 +92,12 @@ impl GenericParams { } } - fn fill_params(&mut self, params: ast::TypeParamList, start: u32) { - for (idx, type_param) in params.type_params().enumerate() { + fn fill_params(&mut self, params: ast::TypeParamList) { + for type_param in params.type_params() { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` let default = type_param.default_type().map(TypeRef::from_ast); - let param = GenericParamData { idx: idx as u32 + start, name: name.clone(), default }; + let param = GenericParamData { name: name.clone(), default }; self.params.alloc(param); let type_ref = TypeRef::Path(name.into()); @@ -141,45 +127,7 @@ impl GenericParams { self.where_predicates.push(WherePredicate { type_ref, bound }); } - pub fn find_by_name(&self, name: &Name) -> Option<&GenericParamData> { - self.params.iter().map(|(_id, data)| data).find(|p| &p.name == name) - } - - pub fn count_parent_params(&self) -> usize { - self.parent_params.as_ref().map(|p| p.count_params_including_parent()).unwrap_or(0) - } - - pub fn count_params_including_parent(&self) -> usize { - let parent_count = self.count_parent_params(); - parent_count + self.params.len() - } - - fn for_each_param<'a>(&'a self, f: &mut impl FnMut(&'a GenericParamData)) { - if let Some(parent) = &self.parent_params { - parent.for_each_param(f); - } - self.params.iter().map(|(_id, data)| data).for_each(f); - } - - pub fn params_including_parent(&self) -> Vec<&GenericParamData> { - let mut vec = Vec::with_capacity(self.count_params_including_parent()); - self.for_each_param(&mut |p| vec.push(p)); - vec - } -} - -fn parent_generic_def(db: &impl DefDatabase, def: GenericDefId) -> Option { - let container = match def { - GenericDefId::FunctionId(it) => it.lookup(db).container, - GenericDefId::TypeAliasId(it) => it.lookup(db).container, - GenericDefId::ConstId(it) => it.lookup(db).container, - GenericDefId::EnumVariantId(it) => return Some(it.parent.into()), - GenericDefId::AdtId(_) | GenericDefId::TraitId(_) | GenericDefId::ImplId(_) => return None, - }; - - match container { - ContainerId::ImplId(it) => Some(it.into()), - ContainerId::TraitId(it) => Some(it.into()), - ContainerId::ModuleId(_) => None, + pub fn find_by_name(&self, name: &Name) -> Option { + self.params.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None }) } } diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index ee19d79a7..e00bd03d5 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -18,12 +18,13 @@ use crate::{ path::{Path, PathKind}, per_ns::PerNs, AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, - GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, - StructId, TraitId, TypeAliasId, + GenericDefId, GenericParamId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, + StaticId, StructId, TraitId, TypeAliasId, }; #[derive(Debug, Clone, Default)] pub struct Resolver { + // FIXME: all usages generally call `.rev`, so maybe reverse once in consturciton? scopes: Vec, } @@ -58,7 +59,7 @@ enum Scope { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TypeNs { SelfType(ImplId), - GenericParam(u32), + GenericParam(GenericParamId), AdtId(AdtId), AdtSelfType(AdtId), // Yup, enum variants are added to the types ns, but any usage of variant as @@ -152,10 +153,13 @@ impl Resolver { Scope::ExprScope(_) => continue, Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, - Scope::GenericParams { params, .. } => { - if let Some(param) = params.find_by_name(first_name) { + Scope::GenericParams { params, def } => { + if let Some(local_id) = params.find_by_name(first_name) { let idx = if path.segments.len() == 1 { None } else { Some(1) }; - return Some((TypeNs::GenericParam(param.idx), idx)); + return Some(( + TypeNs::GenericParam(GenericParamId { local_id, parent: *def }), + idx, + )); } } Scope::ImplBlockScope(impl_) => { @@ -246,9 +250,9 @@ impl Resolver { } Scope::ExprScope(_) => continue, - Scope::GenericParams { params, .. } if n_segments > 1 => { - if let Some(param) = params.find_by_name(first_name) { - let ty = TypeNs::GenericParam(param.idx); + Scope::GenericParams { params, def } if n_segments > 1 => { + if let Some(local_id) = params.find_by_name(first_name) { + let ty = TypeNs::GenericParam(GenericParamId { local_id, parent: *def }); return Some(ResolveValueResult::Partial(ty, 1)); } } @@ -368,6 +372,7 @@ impl Resolver { ) -> impl Iterator + 'a { self.scopes .iter() + .rev() .filter_map(|scope| match scope { Scope::GenericParams { params, .. } => Some(params), _ => None, @@ -376,14 +381,14 @@ impl Resolver { } pub fn generic_def(&self) -> Option { - self.scopes.iter().find_map(|scope| match scope { + self.scopes.iter().rev().find_map(|scope| match scope { Scope::GenericParams { def, .. } => Some(*def), _ => None, }) } pub fn body_owner(&self) -> Option { - self.scopes.iter().find_map(|scope| match scope { + self.scopes.iter().rev().find_map(|scope| match scope { Scope::ExprScope(it) => Some(it.owner), _ => None, }) @@ -394,7 +399,7 @@ pub enum ScopeDef { PerNs(PerNs), ImplSelfType(ImplId), AdtSelfType(AdtId), - GenericParam(u32), + GenericParam(GenericParamId), Local(PatId), } @@ -425,9 +430,12 @@ impl Scope { }); } } - Scope::GenericParams { params, .. } => { - for (_id, param) in params.params.iter() { - f(param.name.clone(), ScopeDef::GenericParam(param.idx)) + Scope::GenericParams { params, def } => { + for (local_id, param) in params.params.iter() { + f( + param.name.clone(), + ScopeDef::GenericParam(GenericParamId { local_id, parent: *def }), + ) } } Scope::ImplBlockScope(i) => { -- cgit v1.2.3 From d75f768c13752dfa5ea9189a0b4dfb9b460993e6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 7 Dec 2019 17:34:28 +0100 Subject: Minor --- crates/ra_hir_def/src/generics.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 94ce83564..b3e345082 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -58,11 +58,12 @@ impl GenericParams { GenericDefId::TraitId(it) => { // traits get the Self type as an implicit first type parameter generics.params.alloc(GenericParamData { name: name::SELF_TYPE, default: None }); - generics.fill(&it.source(db).value); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar let self_param = TypeRef::Path(name::SELF_TYPE.into()); generics.fill_bounds(&it.source(db).value, self_param); + + generics.fill(&it.source(db).value); } GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value), // Note that we don't add `Self` here: in `impl`s, `Self` is not a @@ -75,7 +76,7 @@ impl GenericParams { generics } - fn fill(&mut self, node: &impl TypeParamsOwner) { + fn fill(&mut self, node: &dyn TypeParamsOwner) { if let Some(params) = node.type_param_list() { self.fill_params(params) } @@ -84,7 +85,7 @@ impl GenericParams { } } - fn fill_bounds(&mut self, node: &impl ast::TypeBoundsOwner, type_ref: TypeRef) { + fn fill_bounds(&mut self, node: &dyn ast::TypeBoundsOwner, type_ref: TypeRef) { for bound in node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds()) { -- cgit v1.2.3 From dda9587e75f4fd1740d16531038023ff582ef43f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 7 Dec 2019 18:24:52 +0100 Subject: Track source of type parameters --- crates/ra_hir_def/src/generics.rs | 93 ++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 21 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index b3e345082..0df5a20f5 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -4,12 +4,18 @@ //! in rustc. use std::sync::Arc; -use hir_expand::name::{self, AsName, Name}; -use ra_arena::Arena; +use either::Either; +use hir_expand::{ + name::{self, AsName, Name}, + InFile, +}; +use ra_arena::{map::ArenaMap, Arena}; +use ra_db::FileId; use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; use crate::{ db::DefDatabase, + src::HasChildSource, src::HasSource, type_ref::{TypeBound, TypeRef}, AdtId, AstItemDef, GenericDefId, LocalGenericParamId, Lookup, @@ -39,46 +45,81 @@ pub struct WherePredicate { pub bound: TypeBound, } +type SourceMap = ArenaMap>; + impl GenericParams { pub(crate) fn generic_params_query( db: &impl DefDatabase, def: GenericDefId, ) -> Arc { - Arc::new(GenericParams::new(db, def.into())) + let (params, _source_map) = GenericParams::new(db, def.into()); + Arc::new(params) } - fn new(db: &impl DefDatabase, def: GenericDefId) -> GenericParams { + fn new(db: &impl DefDatabase, def: GenericDefId) -> (GenericParams, InFile) { let mut generics = GenericParams { params: Arena::default(), where_predicates: Vec::new() }; + let mut sm = ArenaMap::default(); // FIXME: add `: Sized` bound for everything except for `Self` in traits - match def { - GenericDefId::FunctionId(it) => generics.fill(&it.lookup(db).source(db).value), - GenericDefId::AdtId(AdtId::StructId(it)) => generics.fill(&it.source(db).value), - GenericDefId::AdtId(AdtId::UnionId(it)) => generics.fill(&it.source(db).value), - GenericDefId::AdtId(AdtId::EnumId(it)) => generics.fill(&it.source(db).value), + let file_id = match def { + GenericDefId::FunctionId(it) => { + let src = it.lookup(db).source(db); + generics.fill(&mut sm, &src.value); + src.file_id + } + GenericDefId::AdtId(AdtId::StructId(it)) => { + let src = it.source(db); + generics.fill(&mut sm, &src.value); + src.file_id + } + GenericDefId::AdtId(AdtId::UnionId(it)) => { + let src = it.source(db); + generics.fill(&mut sm, &src.value); + src.file_id + } + GenericDefId::AdtId(AdtId::EnumId(it)) => { + let src = it.source(db); + generics.fill(&mut sm, &src.value); + src.file_id + } GenericDefId::TraitId(it) => { + let src = it.source(db); + // traits get the Self type as an implicit first type parameter - generics.params.alloc(GenericParamData { name: name::SELF_TYPE, default: None }); + let self_param_id = generics + .params + .alloc(GenericParamData { name: name::SELF_TYPE, default: None }); + sm.insert(self_param_id, Either::Left(src.value.clone())); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar let self_param = TypeRef::Path(name::SELF_TYPE.into()); - generics.fill_bounds(&it.source(db).value, self_param); + generics.fill_bounds(&src.value, self_param); - generics.fill(&it.source(db).value); + generics.fill(&mut sm, &src.value); + src.file_id + } + GenericDefId::TypeAliasId(it) => { + let src = it.lookup(db).source(db); + generics.fill(&mut sm, &src.value); + src.file_id } - GenericDefId::TypeAliasId(it) => generics.fill(&it.lookup(db).source(db).value), // Note that we don't add `Self` here: in `impl`s, `Self` is not a // type-parameter, but rather is a type-alias for impl's target // type, so this is handled by the resolver. - GenericDefId::ImplId(it) => generics.fill(&it.source(db).value), - GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => {} - } + GenericDefId::ImplId(it) => { + let src = it.source(db); + generics.fill(&mut sm, &src.value); + src.file_id + } + // We won't be using this ID anyway + GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => FileId(!0).into(), + }; - generics + (generics, InFile::new(file_id, sm)) } - fn fill(&mut self, node: &dyn TypeParamsOwner) { + fn fill(&mut self, sm: &mut SourceMap, node: &dyn TypeParamsOwner) { if let Some(params) = node.type_param_list() { - self.fill_params(params) + self.fill_params(sm, params) } if let Some(where_clause) = node.where_clause() { self.fill_where_predicates(where_clause); @@ -93,13 +134,14 @@ impl GenericParams { } } - fn fill_params(&mut self, params: ast::TypeParamList) { + fn fill_params(&mut self, sm: &mut SourceMap, params: ast::TypeParamList) { for type_param in params.type_params() { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` let default = type_param.default_type().map(TypeRef::from_ast); let param = GenericParamData { name: name.clone(), default }; - self.params.alloc(param); + let param_id = self.params.alloc(param); + sm.insert(param_id, Either::Right(type_param.clone())); let type_ref = TypeRef::Path(name.into()); self.fill_bounds(&type_param, type_ref); @@ -132,3 +174,12 @@ impl GenericParams { self.params.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None }) } } + +impl HasChildSource for GenericDefId { + type ChildId = LocalGenericParamId; + type Value = Either; + fn child_source(&self, db: &impl DefDatabase) -> InFile { + let (_, sm) = GenericParams::new(db, *self); + sm + } +} -- cgit v1.2.3 From 7d2080a0311cab62388f416beeb360695dbc5ded Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 7 Dec 2019 19:52:09 +0100 Subject: Classify name works for TypeParams --- crates/ra_hir_def/src/generics.rs | 20 +++++++++++++++++++- crates/ra_hir_def/src/keys.rs | 3 ++- crates/ra_hir_def/src/lib.rs | 14 ++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 0df5a20f5..159f9034b 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -14,11 +14,14 @@ use ra_db::FileId; use ra_syntax::ast::{self, NameOwner, TypeBoundsOwner, TypeParamsOwner}; use crate::{ + child_by_source::ChildBySource, db::DefDatabase, + dyn_map::DynMap, + keys, src::HasChildSource, src::HasSource, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, GenericDefId, LocalGenericParamId, Lookup, + AdtId, AstItemDef, GenericDefId, GenericParamId, LocalGenericParamId, Lookup, }; /// Data about a generic parameter (to a function, struct, impl, ...). @@ -183,3 +186,18 @@ impl HasChildSource for GenericDefId { sm } } + +impl ChildBySource for GenericDefId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + let arena_map = self.child_source(db); + let arena_map = arena_map.as_ref(); + for (local_id, src) in arena_map.value.iter() { + let id = GenericParamId { parent: *self, local_id }; + if let Either::Right(type_param) = src { + res[keys::TYPE_PARAM].insert(arena_map.with_value(type_param.clone()), id) + } + } + res + } +} diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index 447b7e3ba..ca5630c80 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs @@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; use crate::{ dyn_map::{DynMap, Policy}, - ConstId, EnumVariantId, FunctionId, StaticId, StructFieldId, TypeAliasId, + ConstId, EnumVariantId, FunctionId, GenericParamId, StaticId, StructFieldId, TypeAliasId, }; type Key = crate::dyn_map::Key, V, AstPtrPolicy>; @@ -20,6 +20,7 @@ pub const ENUM_VARIANT: Key = Key::new(); pub const TYPE_ALIAS: Key = Key::new(); pub const TUPLE_FIELD: Key = Key::new(); pub const RECORD_FIELD: Key = Key::new(); +pub const TYPE_PARAM: Key = Key::new(); /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are /// equal if they point to exactly the same object. diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index b8dfc0ab1..6dfb3c03d 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -525,6 +525,20 @@ impl HasModule for DefWithBodyId { } } +impl HasModule for GenericDefId { + fn module(&self, db: &impl db::DefDatabase) -> ModuleId { + match self { + GenericDefId::FunctionId(it) => it.lookup(db).module(db), + GenericDefId::AdtId(it) => it.module(db), + GenericDefId::TraitId(it) => it.module(db), + GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), + GenericDefId::ImplId(it) => it.module(db), + GenericDefId::EnumVariantId(it) => it.parent.module(db), + GenericDefId::ConstId(it) => it.lookup(db).module(db), + } + } +} + impl HasModule for StaticLoc { fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { self.container -- cgit v1.2.3 From 88c5b1282a5770097c6c768b24bedfc3a6944e08 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 7 Dec 2019 20:09:53 +0100 Subject: Rename GenericParam -> TypeParam We don't have LifetimeParam yet, but they are planned! --- crates/ra_hir_def/src/generics.rs | 28 ++++++++++++++-------------- crates/ra_hir_def/src/keys.rs | 4 ++-- crates/ra_hir_def/src/lib.rs | 8 ++++---- crates/ra_hir_def/src/resolver.rs | 18 +++++++++--------- 4 files changed, 29 insertions(+), 29 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 159f9034b..976cf72d0 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -21,12 +21,12 @@ use crate::{ src::HasChildSource, src::HasSource, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, GenericDefId, GenericParamId, LocalGenericParamId, Lookup, + AdtId, AstItemDef, GenericDefId, LocalTypeParamId, Lookup, TypeParamId, }; /// Data about a generic parameter (to a function, struct, impl, ...). #[derive(Clone, PartialEq, Eq, Debug)] -pub struct GenericParamData { +pub struct TypeParamData { pub name: Name, pub default: Option, } @@ -34,7 +34,8 @@ pub struct GenericParamData { /// Data about the generic parameters of a function, struct, impl, etc. #[derive(Clone, PartialEq, Eq, Debug)] pub struct GenericParams { - pub params: Arena, + pub types: Arena, + // lifetimes: Arena, pub where_predicates: Vec, } @@ -48,7 +49,7 @@ pub struct WherePredicate { pub bound: TypeBound, } -type SourceMap = ArenaMap>; +type SourceMap = ArenaMap>; impl GenericParams { pub(crate) fn generic_params_query( @@ -60,7 +61,7 @@ impl GenericParams { } fn new(db: &impl DefDatabase, def: GenericDefId) -> (GenericParams, InFile) { - let mut generics = GenericParams { params: Arena::default(), where_predicates: Vec::new() }; + let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() }; let mut sm = ArenaMap::default(); // FIXME: add `: Sized` bound for everything except for `Self` in traits let file_id = match def { @@ -88,9 +89,8 @@ impl GenericParams { let src = it.source(db); // traits get the Self type as an implicit first type parameter - let self_param_id = generics - .params - .alloc(GenericParamData { name: name::SELF_TYPE, default: None }); + let self_param_id = + generics.types.alloc(TypeParamData { name: name::SELF_TYPE, default: None }); sm.insert(self_param_id, Either::Left(src.value.clone())); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar @@ -142,8 +142,8 @@ impl GenericParams { let name = type_param.name().map_or_else(Name::missing, |it| it.as_name()); // FIXME: Use `Path::from_src` let default = type_param.default_type().map(TypeRef::from_ast); - let param = GenericParamData { name: name.clone(), default }; - let param_id = self.params.alloc(param); + let param = TypeParamData { name: name.clone(), default }; + let param_id = self.types.alloc(param); sm.insert(param_id, Either::Right(type_param.clone())); let type_ref = TypeRef::Path(name.into()); @@ -173,13 +173,13 @@ impl GenericParams { self.where_predicates.push(WherePredicate { type_ref, bound }); } - pub fn find_by_name(&self, name: &Name) -> Option { - self.params.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None }) + pub fn find_by_name(&self, name: &Name) -> Option { + self.types.iter().find_map(|(id, p)| if &p.name == name { Some(id) } else { None }) } } impl HasChildSource for GenericDefId { - type ChildId = LocalGenericParamId; + type ChildId = LocalTypeParamId; type Value = Either; fn child_source(&self, db: &impl DefDatabase) -> InFile { let (_, sm) = GenericParams::new(db, *self); @@ -193,7 +193,7 @@ impl ChildBySource for GenericDefId { let arena_map = self.child_source(db); let arena_map = arena_map.as_ref(); for (local_id, src) in arena_map.value.iter() { - let id = GenericParamId { parent: *self, local_id }; + let id = TypeParamId { parent: *self, local_id }; if let Either::Right(type_param) = src { res[keys::TYPE_PARAM].insert(arena_map.with_value(type_param.clone()), id) } diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index ca5630c80..be702a4f8 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs @@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; use crate::{ dyn_map::{DynMap, Policy}, - ConstId, EnumVariantId, FunctionId, GenericParamId, StaticId, StructFieldId, TypeAliasId, + ConstId, EnumVariantId, FunctionId, StaticId, StructFieldId, TypeAliasId, TypeParamId, }; type Key = crate::dyn_map::Key, V, AstPtrPolicy>; @@ -20,7 +20,7 @@ pub const ENUM_VARIANT: Key = Key::new(); pub const TYPE_ALIAS: Key = Key::new(); pub const TUPLE_FIELD: Key = Key::new(); pub const RECORD_FIELD: Key = Key::new(); -pub const TYPE_PARAM: Key = Key::new(); +pub const TYPE_PARAM: Key = Key::new(); /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are /// equal if they point to exactly the same object. diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 6dfb3c03d..569da4f28 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -318,14 +318,14 @@ macro_rules! impl_froms { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct GenericParamId { +pub struct TypeParamId { pub parent: GenericDefId, - pub local_id: LocalGenericParamId, + pub local_id: LocalTypeParamId, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct LocalGenericParamId(RawId); -impl_arena_id!(LocalGenericParamId); +pub struct LocalTypeParamId(RawId); +impl_arena_id!(LocalTypeParamId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ContainerId { diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index e00bd03d5..4c859e497 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -18,8 +18,8 @@ use crate::{ path::{Path, PathKind}, per_ns::PerNs, AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, - GenericDefId, GenericParamId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, - StaticId, StructId, TraitId, TypeAliasId, + GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, + StructId, TraitId, TypeAliasId, TypeParamId, }; #[derive(Debug, Clone, Default)] @@ -59,7 +59,7 @@ enum Scope { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum TypeNs { SelfType(ImplId), - GenericParam(GenericParamId), + GenericParam(TypeParamId), AdtId(AdtId), AdtSelfType(AdtId), // Yup, enum variants are added to the types ns, but any usage of variant as @@ -157,7 +157,7 @@ impl Resolver { if let Some(local_id) = params.find_by_name(first_name) { let idx = if path.segments.len() == 1 { None } else { Some(1) }; return Some(( - TypeNs::GenericParam(GenericParamId { local_id, parent: *def }), + TypeNs::GenericParam(TypeParamId { local_id, parent: *def }), idx, )); } @@ -252,7 +252,7 @@ impl Resolver { Scope::GenericParams { params, def } if n_segments > 1 => { if let Some(local_id) = params.find_by_name(first_name) { - let ty = TypeNs::GenericParam(GenericParamId { local_id, parent: *def }); + let ty = TypeNs::GenericParam(TypeParamId { local_id, parent: *def }); return Some(ResolveValueResult::Partial(ty, 1)); } } @@ -399,7 +399,7 @@ pub enum ScopeDef { PerNs(PerNs), ImplSelfType(ImplId), AdtSelfType(AdtId), - GenericParam(GenericParamId), + GenericParam(TypeParamId), Local(PatId), } @@ -431,10 +431,10 @@ impl Scope { } } Scope::GenericParams { params, def } => { - for (local_id, param) in params.params.iter() { + for (local_id, param) in params.types.iter() { f( param.name.clone(), - ScopeDef::GenericParam(GenericParamId { local_id, parent: *def }), + ScopeDef::GenericParam(TypeParamId { local_id, parent: *def }), ) } } @@ -481,7 +481,7 @@ impl Resolver { fn push_generic_params_scope(self, db: &impl DefDatabase, def: GenericDefId) -> Resolver { let params = db.generic_params(def); - if params.params.is_empty() { + if params.types.is_empty() { self } else { self.push_scope(Scope::GenericParams { def, params }) -- cgit v1.2.3 From 509fedd9d2f228c6dca762cbf06c31af34ac0c75 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 8 Dec 2019 16:16:52 +0800 Subject: Remove MacroFileKind --- crates/ra_hir_def/src/body.rs | 6 ++---- crates/ra_hir_def/src/nameres/collector.rs | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 7b385f3fd..b3bc336cf 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -6,9 +6,7 @@ pub mod scope; use std::{ops::Index, sync::Arc}; use either::Either; -use hir_expand::{ - hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId, MacroFileKind, -}; +use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId}; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstNode, AstPtr}; use rustc_hash::FxHashMap; @@ -49,7 +47,7 @@ impl Expander { if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { if let Some(def) = self.resolve_path_as_macro(db, &path) { let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); - let file_id = call_id.as_file(MacroFileKind::Expr); + let file_id = call_id.as_file(); if let Some(node) = db.parse_or_expand(file_id) { if let Some(expr) = ast::Expr::cast(node) { log::debug!("macro expansion {:#?}", expr.syntax()); diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 08693cb13..6a01e3ab7 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -7,7 +7,7 @@ use hir_expand::{ builtin_derive::find_builtin_derive, builtin_macro::find_builtin_macro, name::{self, AsName, Name}, - HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, MacroFileKind, + HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; use ra_cfg::CfgOptions; use ra_db::{CrateId, FileId}; @@ -545,7 +545,7 @@ where self.macro_stack_monitor.increase(macro_def_id); if !self.macro_stack_monitor.is_poison(macro_def_id) { - let file_id: HirFileId = macro_call_id.as_file(MacroFileKind::Items); + let file_id: HirFileId = macro_call_id.as_file(); let raw_items = self.db.raw_items(file_id); let mod_dir = self.mod_dirs[&module_id].clone(); ModCollector { -- cgit v1.2.3 From 200bda3daf66f338e9bb1d833146f06fb81f829e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 8 Dec 2019 12:16:57 +0100 Subject: Cleanup Field ty --- crates/ra_hir_def/src/resolver.rs | 42 ++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 4c859e497..9484a61d5 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -19,7 +19,7 @@ use crate::{ per_ns::PerNs, AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, - StructId, TraitId, TypeAliasId, TypeParamId, + StructId, TraitId, TypeAliasId, TypeParamId, VariantId, }; #[derive(Debug, Clone, Default)] @@ -544,16 +544,6 @@ impl HasResolver for FunctionId { } } -impl HasResolver for DefWithBodyId { - fn resolver(self, db: &impl DefDatabase) -> Resolver { - match self { - DefWithBodyId::ConstId(c) => c.resolver(db), - DefWithBodyId::FunctionId(f) => f.resolver(db), - DefWithBodyId::StaticId(s) => s.resolver(db), - } - } -} - impl HasResolver for ConstId { fn resolver(self, db: &impl DefDatabase) -> Resolver { self.lookup(db).container.resolver(db) @@ -572,6 +562,25 @@ impl HasResolver for TypeAliasId { } } +impl HasResolver for ImplId { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + self.module(db) + .resolver(db) + .push_generic_params_scope(db, self.into()) + .push_impl_block_scope(self) + } +} + +impl HasResolver for DefWithBodyId { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + DefWithBodyId::ConstId(c) => c.resolver(db), + DefWithBodyId::FunctionId(f) => f.resolver(db), + DefWithBodyId::StaticId(s) => s.resolver(db), + } + } +} + impl HasResolver for ContainerId { fn resolver(self, db: &impl DefDatabase) -> Resolver { match self { @@ -596,11 +605,12 @@ impl HasResolver for GenericDefId { } } -impl HasResolver for ImplId { +impl HasResolver for VariantId { fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db) - .resolver(db) - .push_generic_params_scope(db, self.into()) - .push_impl_block_scope(self) + match self { + VariantId::EnumVariantId(it) => it.parent.resolver(db), + VariantId::StructId(it) => it.resolver(db), + VariantId::UnionId(it) => it.resolver(db), + } } } -- cgit v1.2.3 From 5e096def15e992938b0e2838ae6c344939aa10f2 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 8 Dec 2019 12:50:49 +0100 Subject: Expand macros in blocks to expressions for now Expanding to statements isn't handled properly yet and breaks things. --- crates/ra_hir_def/src/body/lower.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 71c08f024..cc068ff94 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -437,9 +437,7 @@ where None => self.alloc_expr(Expr::Missing, syntax_ptr), } } - - // FIXME implement HIR for these: - ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), + // FIXME expand to statements in statement position ast::Expr::MacroCall(e) => match self.expander.enter_expand(self.db, e) { Some((mark, expansion)) => { let id = self.collect_expr(expansion); @@ -448,6 +446,9 @@ where } None => self.alloc_expr(Expr::Missing, syntax_ptr), }, + + // FIXME implement HIR for these: + ast::Expr::Label(_e) => self.alloc_expr(Expr::Missing, syntax_ptr), } } -- cgit v1.2.3 From 3a95d01d0cbc5ac2d789b3c70f4472a609fc5af4 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sun, 8 Dec 2019 20:33:42 +0800 Subject: Delay legacy macro expansion --- crates/ra_hir_def/src/nameres/collector.rs | 206 ++++++++--------------------- 1 file changed, 57 insertions(+), 149 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 3ff071f9e..a80067979 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -12,7 +12,7 @@ use hir_expand::{ use ra_cfg::CfgOptions; use ra_db::{CrateId, FileId}; use ra_syntax::ast; -use rustc_hash::{FxHashMap, FxHashSet}; +use rustc_hash::FxHashMap; use test_utils::tested_by; use crate::{ @@ -63,42 +63,12 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C unexpanded_macros: Vec::new(), unexpanded_attribute_macros: Vec::new(), mod_dirs: FxHashMap::default(), - macro_stack_monitor: MacroStackMonitor::default(), - poison_macros: FxHashSet::default(), cfg_options, }; collector.collect(); collector.finish() } -#[derive(Default)] -struct MacroStackMonitor { - counts: FxHashMap, - - /// Mainly use for test - validator: Option bool>>, -} - -impl MacroStackMonitor { - fn increase(&mut self, macro_def_id: MacroDefId) { - *self.counts.entry(macro_def_id).or_default() += 1; - } - - fn decrease(&mut self, macro_def_id: MacroDefId) { - *self.counts.entry(macro_def_id).or_default() -= 1; - } - - fn is_poison(&self, macro_def_id: MacroDefId) -> bool { - let cur = *self.counts.get(¯o_def_id).unwrap_or(&0); - - if let Some(validator) = &self.validator { - validator(cur) - } else { - cur > 100 - } - } -} - #[derive(Copy, Clone, Debug, Eq, PartialEq)] enum PartialResolvedImport { /// None of any namespaces is resolved @@ -127,6 +97,14 @@ struct ImportDirective { status: PartialResolvedImport, } +#[derive(Clone, Debug, Eq, PartialEq)] +struct MacroDirective { + module_id: LocalModuleId, + ast_id: AstId, + path: Path, + legacy: Option, +} + /// Walks the tree of module recursively struct DefCollector<'a, DB> { db: &'a DB, @@ -134,25 +112,9 @@ struct DefCollector<'a, DB> { glob_imports: FxHashMap>, unresolved_imports: Vec, resolved_imports: Vec, - unexpanded_macros: Vec<(LocalModuleId, AstId, Path)>, + unexpanded_macros: Vec, unexpanded_attribute_macros: Vec<(LocalModuleId, AstId, Path)>, mod_dirs: FxHashMap, - - /// Some macro use `$tt:tt which mean we have to handle the macro perfectly - /// To prevent stack overflow, we add a deep counter here for prevent that. - macro_stack_monitor: MacroStackMonitor, - /// Some macros are not well-behavior, which leads to infinite loop - /// e.g. macro_rules! foo { ($ty:ty) => { foo!($ty); } } - /// We mark it down and skip it in collector - /// - /// FIXME: - /// Right now it only handle a poison macro in a single crate, - /// such that if other crate try to call that macro, - /// the whole process will do again until it became poisoned in that crate. - /// We should handle this macro set globally - /// However, do we want to put it as a global variable? - poison_macros: FxHashSet, - cfg_options: &'a CfgOptions, } @@ -556,18 +518,24 @@ where std::mem::replace(&mut self.unexpanded_attribute_macros, Vec::new()); let mut resolved = Vec::new(); let mut res = ReachedFixedPoint::Yes; - macros.retain(|(module_id, ast_id, path)| { + macros.retain(|directive| { + if let Some(call_id) = directive.legacy { + res = ReachedFixedPoint::No; + resolved.push((directive.module_id, call_id)); + return false; + } + let resolved_res = self.def_map.resolve_path_fp_with_macro( self.db, ResolveMode::Other, - *module_id, - path, + directive.module_id, + &directive.path, BuiltinShadowMode::Module, ); if let Some(def) = resolved_res.resolved_def.take_macros() { - let call_id = def.as_call_id(self.db, MacroCallKind::FnLike(*ast_id)); - resolved.push((*module_id, call_id, def)); + let call_id = def.as_call_id(self.db, MacroCallKind::FnLike(directive.ast_id)); + resolved.push((directive.module_id, call_id)); res = ReachedFixedPoint::No; return false; } @@ -579,7 +547,7 @@ where if let Some(def) = resolved_res { let call_id = def.as_call_id(self.db, MacroCallKind::Attr(*ast_id)); - resolved.push((*module_id, call_id, def)); + resolved.push((*module_id, call_id)); res = ReachedFixedPoint::No; return false; } @@ -590,8 +558,8 @@ where self.unexpanded_macros = macros; self.unexpanded_attribute_macros = attribute_macros; - for (module_id, macro_call_id, macro_def_id) in resolved { - self.collect_macro_expansion(module_id, macro_call_id, macro_def_id); + for (module_id, macro_call_id) in resolved { + self.collect_macro_expansion(module_id, macro_call_id); } res @@ -611,36 +579,18 @@ where None } - fn collect_macro_expansion( - &mut self, - module_id: LocalModuleId, - macro_call_id: MacroCallId, - macro_def_id: MacroDefId, - ) { - if self.poison_macros.contains(¯o_def_id) { - return; - } - - self.macro_stack_monitor.increase(macro_def_id); - - if !self.macro_stack_monitor.is_poison(macro_def_id) { - let file_id: HirFileId = macro_call_id.as_file(); - let raw_items = self.db.raw_items(file_id); - let mod_dir = self.mod_dirs[&module_id].clone(); - ModCollector { - def_collector: &mut *self, - file_id, - module_id, - raw_items: &raw_items, - mod_dir, - } - .collect(raw_items.items()); - } else { - log::error!("Too deep macro expansion: {:?}", macro_call_id); - self.poison_macros.insert(macro_def_id); + fn collect_macro_expansion(&mut self, module_id: LocalModuleId, macro_call_id: MacroCallId) { + let file_id: HirFileId = macro_call_id.as_file(); + let raw_items = self.db.raw_items(file_id); + let mod_dir = self.mod_dirs[&module_id].clone(); + ModCollector { + def_collector: &mut *self, + file_id, + module_id, + raw_items: &raw_items, + mod_dir, } - - self.macro_stack_monitor.decrease(macro_def_id); + .collect(raw_items.items()); } fn finish(self) -> CrateDefMap { @@ -908,15 +858,20 @@ where return; } - // Case 2: try to resolve in legacy scope and expand macro_rules, triggering - // recursive item collection. + // Case 2: try to resolve in legacy scope and expand macro_rules if let Some(macro_def) = mac.path.as_ident().and_then(|name| { self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) }) { let macro_call_id = macro_def.as_call_id(self.def_collector.db, MacroCallKind::FnLike(ast_id)); - self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, macro_def); + self.def_collector.unexpanded_macros.push(MacroDirective { + module_id: self.module_id, + path: mac.path.clone(), + ast_id, + legacy: Some(macro_call_id), + }); + return; } @@ -926,7 +881,13 @@ where if path.is_ident() { path.kind = PathKind::Self_; } - self.def_collector.unexpanded_macros.push((self.module_id, ast_id, path)); + + self.def_collector.unexpanded_macros.push(MacroDirective { + module_id: self.module_id, + path, + ast_id, + legacy: None, + }); } fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { @@ -951,19 +912,13 @@ fn is_macro_rules(path: &Path) -> bool { #[cfg(test)] mod tests { + use crate::{db::DefDatabase, test_db::TestDB}; use ra_arena::Arena; use ra_db::{fixture::WithFixture, SourceDatabase}; - use rustc_hash::FxHashSet; - - use crate::{db::DefDatabase, test_db::TestDB}; use super::*; - fn do_collect_defs( - db: &impl DefDatabase, - def_map: CrateDefMap, - monitor: MacroStackMonitor, - ) -> (CrateDefMap, FxHashSet) { + fn do_collect_defs(db: &impl DefDatabase, def_map: CrateDefMap) -> CrateDefMap { let mut collector = DefCollector { db, def_map, @@ -973,19 +928,13 @@ mod tests { unexpanded_macros: Vec::new(), unexpanded_attribute_macros: Vec::new(), mod_dirs: FxHashMap::default(), - macro_stack_monitor: monitor, - poison_macros: FxHashSet::default(), cfg_options: &CfgOptions::default(), }; collector.collect(); - (collector.def_map, collector.poison_macros) + collector.def_map } - fn do_limited_resolve( - code: &str, - limit: u32, - poison_limit: u32, - ) -> (CrateDefMap, FxHashSet) { + fn do_resolve(code: &str) -> CrateDefMap { let (db, _file_id) = TestDB::with_single_file(&code); let krate = db.test_crate(); @@ -1003,59 +952,18 @@ mod tests { diagnostics: Vec::new(), } }; - - let mut monitor = MacroStackMonitor::default(); - monitor.validator = Some(Box::new(move |count| { - assert!(count < limit); - count >= poison_limit - })); - - do_collect_defs(&db, def_map, monitor) + do_collect_defs(&db, def_map) } #[test] - fn test_macro_expand_limit_width() { - do_limited_resolve( + fn test_macro_expand_will_stop() { + do_resolve( r#" macro_rules! foo { ($($ty:ty)*) => { foo!($($ty)*, $($ty)*); } } foo!(KABOOM); "#, - 16, - 1000, ); } - - #[test] - fn test_macro_expand_poisoned() { - let (_, poison_macros) = do_limited_resolve( - r#" - macro_rules! foo { - ($ty:ty) => { foo!($ty); } - } -foo!(KABOOM); - "#, - 100, - 16, - ); - - assert_eq!(poison_macros.len(), 1); - } - - #[test] - fn test_macro_expand_normal() { - let (_, poison_macros) = do_limited_resolve( - r#" - macro_rules! foo { - ($ident:ident) => { struct $ident {} } - } -foo!(Bar); - "#, - 16, - 16, - ); - - assert_eq!(poison_macros.len(), 0); - } } -- cgit v1.2.3 From 7b0644d81e52d00a7a6795b187f356213ff68225 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 14:09:13 +0100 Subject: Switch to the new location for impls --- crates/ra_hir_def/src/attr.rs | 2 +- crates/ra_hir_def/src/child_by_source.rs | 5 +++++ crates/ra_hir_def/src/data.rs | 2 +- crates/ra_hir_def/src/db.rs | 6 +++--- crates/ra_hir_def/src/generics.rs | 2 +- crates/ra_hir_def/src/keys.rs | 6 ++++-- crates/ra_hir_def/src/lib.rs | 30 +++++++++++++++++++++--------- crates/ra_hir_def/src/nameres/collector.rs | 10 ++++++---- crates/ra_hir_def/src/resolver.rs | 3 ++- crates/ra_hir_def/src/src.rs | 11 ++++++++++- 10 files changed, 54 insertions(+), 23 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 2f8f02d82..12d4e777a 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -64,7 +64,7 @@ impl Attrs { AttrDefId::MacroDefId(it) => { it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db)) } - AttrDefId::ImplId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AttrDefId::ImplId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::StaticId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index a3574a9db..821549bd5 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -98,6 +98,11 @@ impl ChildBySource for ModuleId { } } + for &impl_ in crate_def_map[self.local_id].impls.iter() { + let src = impl_.lookup(db).source(db); + res[keys::IMPL].insert(src, impl_) + } + res } } diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 095d7064a..42821b9b1 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -167,7 +167,7 @@ pub struct ImplData { impl ImplData { pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc { - let src = id.source(db); + let src = id.lookup(db).source(db); let items = db.ast_id_map(src.file_id); let target_trait = src.value.target_trait().map(TypeRef::from_ast); diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index ef5611ffc..8907aacca 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -18,8 +18,8 @@ use crate::{ CrateDefMap, }, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, - ImplId, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, TypeAliasLoc, - UnionId, + ImplId, ImplLoc, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, + TypeAliasLoc, UnionId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -41,7 +41,7 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId; #[salsa::interned] - fn intern_impl(&self, loc: ItemLoc) -> ImplId; + fn intern_impl(&self, loc: ImplLoc) -> ImplId; } #[salsa::query_group(DefDatabaseStorage)] diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 976cf72d0..5d1100945 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -109,7 +109,7 @@ impl GenericParams { // type-parameter, but rather is a type-alias for impl's target // type, so this is handled by the resolver. GenericDefId::ImplId(it) => { - let src = it.source(db); + let src = it.lookup(db).source(db); generics.fill(&mut sm, &src.value); src.file_id } diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index be702a4f8..d318b2451 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs @@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; use crate::{ dyn_map::{DynMap, Policy}, - ConstId, EnumVariantId, FunctionId, StaticId, StructFieldId, TypeAliasId, TypeParamId, + ConstId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, TypeAliasId, TypeParamId, }; type Key = crate::dyn_map::Key, V, AstPtrPolicy>; @@ -16,8 +16,10 @@ type Key = crate::dyn_map::Key, V, AstPtrPolicy>; pub const FUNCTION: Key = Key::new(); pub const CONST: Key = Key::new(); pub const STATIC: Key = Key::new(); -pub const ENUM_VARIANT: Key = Key::new(); pub const TYPE_ALIAS: Key = Key::new(); +pub const IMPL: Key = Key::new(); + +pub const ENUM_VARIANT: Key = Key::new(); pub const TUPLE_FIELD: Key = Key::new(); pub const RECORD_FIELD: Key = Key::new(); pub const TYPE_PARAM: Key = Key::new(); diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 569da4f28..5564b166b 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -289,12 +289,24 @@ impl Lookup for TypeAliasId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ImplId(salsa::InternId); impl_intern_key!(ImplId); -impl AstItemDef for ImplId { - fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_impl(loc) + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ImplLoc { + pub container: ModuleId, + pub ast_id: AstId, +} + +impl Intern for ImplLoc { + type ID = ImplId; + fn intern(self, db: &impl db::DefDatabase) -> ImplId { + db.intern_impl(self) } - fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_impl(self) +} + +impl Lookup for ImplId { + type Data = ImplLoc; + fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc { + db.lookup_intern_impl(*self) } } @@ -479,7 +491,7 @@ impl HasModule for FunctionLoc { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match self.container { ContainerId::ModuleId(it) => it, - ContainerId::ImplId(it) => it.module(db), + ContainerId::ImplId(it) => it.lookup(db).container, ContainerId::TraitId(it) => it.module(db), } } @@ -489,7 +501,7 @@ impl HasModule for TypeAliasLoc { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match self.container { ContainerId::ModuleId(it) => it, - ContainerId::ImplId(it) => it.module(db), + ContainerId::ImplId(it) => it.lookup(db).container, ContainerId::TraitId(it) => it.module(db), } } @@ -499,7 +511,7 @@ impl HasModule for ConstLoc { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match self.container { ContainerId::ModuleId(it) => it, - ContainerId::ImplId(it) => it.module(db), + ContainerId::ImplId(it) => it.lookup(db).container, ContainerId::TraitId(it) => it.module(db), } } @@ -532,7 +544,7 @@ impl HasModule for GenericDefId { GenericDefId::AdtId(it) => it.module(db), GenericDefId::TraitId(it) => it.module(db), GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), - GenericDefId::ImplId(it) => it.module(db), + GenericDefId::ImplId(it) => it.lookup(db).container, GenericDefId::EnumVariantId(it) => it.parent.module(db), GenericDefId::ConstId(it) => it.lookup(db).module(db), } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index a80067979..b33507a9a 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -24,7 +24,7 @@ use crate::{ }, path::{Path, PathKind}, per_ns::PerNs, - AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplId, + AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplLoc, Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, TraitId, TypeAliasLoc, UnionId, }; @@ -661,9 +661,11 @@ where krate: self.def_collector.def_map.krate, local_id: self.module_id, }; - let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); - let imp_id = ImplId::from_ast_id(ctx, self.raw_items[imp].ast_id); - self.def_collector.def_map.modules[self.module_id].impls.push(imp_id) + let ast_id = self.raw_items[imp].ast_id; + let impl_id = + ImplLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db); + self.def_collector.def_map.modules[self.module_id].impls.push(impl_id) } } } diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 9484a61d5..f87b16b44 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -564,7 +564,8 @@ impl HasResolver for TypeAliasId { impl HasResolver for ImplId { fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db) + self.lookup(db) + .container .resolver(db) .push_generic_params_scope(db, self.into()) .push_impl_block_scope(self) diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs index 27caa02cc..a5c4359a7 100644 --- a/crates/ra_hir_def/src/src.rs +++ b/crates/ra_hir_def/src/src.rs @@ -4,7 +4,7 @@ use hir_expand::InFile; use ra_arena::map::ArenaMap; use ra_syntax::ast; -use crate::{db::DefDatabase, ConstLoc, FunctionLoc, StaticLoc, TypeAliasLoc}; +use crate::{db::DefDatabase, ConstLoc, FunctionLoc, ImplLoc, StaticLoc, TypeAliasLoc}; pub trait HasSource { type Value; @@ -47,6 +47,15 @@ impl HasSource for StaticLoc { } } +impl HasSource for ImplLoc { + type Value = ast::ImplBlock; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + pub trait HasChildSource { type ChildId; type Value; -- cgit v1.2.3 From 82e9b245587046d2a1ed432225b19023adbe3245 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 14:34:03 +0100 Subject: Move traits to the new loc --- crates/ra_hir_def/src/attr.rs | 2 +- crates/ra_hir_def/src/child_by_source.rs | 4 ++++ crates/ra_hir_def/src/data.rs | 6 +++--- crates/ra_hir_def/src/db.rs | 6 +++--- crates/ra_hir_def/src/docs.rs | 2 +- crates/ra_hir_def/src/generics.rs | 2 +- crates/ra_hir_def/src/keys.rs | 4 +++- crates/ra_hir_def/src/lib.rs | 30 +++++++++++++++++++++--------- crates/ra_hir_def/src/nameres/collector.rs | 9 +++++++-- crates/ra_hir_def/src/resolver.rs | 8 ++++---- crates/ra_hir_def/src/src.rs | 11 ++++++++++- 11 files changed, 58 insertions(+), 26 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 12d4e777a..3347d819c 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -60,7 +60,7 @@ impl Attrs { AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), }, - AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AttrDefId::TraitId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::MacroDefId(it) => { it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db)) } diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 821549bd5..88c2d3f24 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -94,6 +94,10 @@ impl ChildBySource for ModuleId { let src = ty.lookup(db).source(db); res[keys::TYPE_ALIAS].insert(src, ty) } + ModuleDefId::TraitId(trait_) => { + let src = trait_.lookup(db).source(db); + res[keys::TRAIT].insert(src, trait_) + } _ => (), } } diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 42821b9b1..b2dac183e 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -12,8 +12,8 @@ use crate::{ db::DefDatabase, src::HasSource, type_ref::{Mutability, TypeRef}, - AssocItemId, AstItemDef, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, - Intern, Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, + AssocItemId, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, Intern, Lookup, + StaticId, TraitId, TypeAliasId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -94,7 +94,7 @@ pub struct TraitData { impl TraitData { pub(crate) fn trait_data_query(db: &impl DefDatabase, tr: TraitId) -> Arc { - let src = tr.source(db); + let src = tr.lookup(db).source(db); let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let auto = src.value.is_auto(); let ast_id_map = db.ast_id_map(src.file_id); diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 8907aacca..f0c2ae559 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -18,8 +18,8 @@ use crate::{ CrateDefMap, }, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, - ImplId, ImplLoc, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TypeAliasId, - TypeAliasLoc, UnionId, + ImplId, ImplLoc, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TraitLoc, + TypeAliasId, TypeAliasLoc, UnionId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -37,7 +37,7 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_static(&self, loc: StaticLoc) -> StaticId; #[salsa::interned] - fn intern_trait(&self, loc: ItemLoc) -> TraitId; + fn intern_trait(&self, loc: TraitLoc) -> TraitId; #[salsa::interned] fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId; #[salsa::interned] diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index 61727bd26..1921681fb 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -59,7 +59,7 @@ impl Documentation { let src = it.parent.child_source(db); docs_from_ast(&src.value[it.local_id]) } - AttrDefId::TraitId(it) => docs_from_ast(&it.source(db).value), + AttrDefId::TraitId(it) => docs_from_ast(&it.lookup(db).source(db).value), AttrDefId::MacroDefId(it) => docs_from_ast(&it.ast_id?.to_node(db)), AttrDefId::ConstId(it) => docs_from_ast(&it.lookup(db).source(db).value), AttrDefId::StaticId(it) => docs_from_ast(&it.lookup(db).source(db).value), diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 5d1100945..cbfc3ff04 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -86,7 +86,7 @@ impl GenericParams { src.file_id } GenericDefId::TraitId(it) => { - let src = it.source(db); + let src = it.lookup(db).source(db); // traits get the Self type as an implicit first type parameter let self_param_id = diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index d318b2451..6ec58f5f9 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs @@ -8,7 +8,8 @@ use rustc_hash::FxHashMap; use crate::{ dyn_map::{DynMap, Policy}, - ConstId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, TypeAliasId, TypeParamId, + ConstId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, TraitId, TypeAliasId, + TypeParamId, }; type Key = crate::dyn_map::Key, V, AstPtrPolicy>; @@ -18,6 +19,7 @@ pub const CONST: Key = Key::new(); pub const STATIC: Key = Key::new(); pub const TYPE_ALIAS: Key = Key::new(); pub const IMPL: Key = Key::new(); +pub const TRAIT: Key = Key::new(); pub const ENUM_VARIANT: Key = Key::new(); pub const TUPLE_FIELD: Key = Key::new(); diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 5564b166b..0fcc2cde4 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -253,12 +253,24 @@ impl Lookup for StaticId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TraitId(salsa::InternId); impl_intern_key!(TraitId); -impl AstItemDef for TraitId { - fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_trait(loc) + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct TraitLoc { + pub container: ModuleId, + pub ast_id: AstId, +} + +impl Intern for TraitLoc { + type ID = TraitId; + fn intern(self, db: &impl db::DefDatabase) -> TraitId { + db.intern_trait(self) } - fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_trait(self) +} + +impl Lookup for TraitId { + type Data = TraitLoc; + fn lookup(&self, db: &impl db::DefDatabase) -> TraitLoc { + db.lookup_intern_trait(*self) } } @@ -492,7 +504,7 @@ impl HasModule for FunctionLoc { match self.container { ContainerId::ModuleId(it) => it, ContainerId::ImplId(it) => it.lookup(db).container, - ContainerId::TraitId(it) => it.module(db), + ContainerId::TraitId(it) => it.lookup(db).container, } } } @@ -502,7 +514,7 @@ impl HasModule for TypeAliasLoc { match self.container { ContainerId::ModuleId(it) => it, ContainerId::ImplId(it) => it.lookup(db).container, - ContainerId::TraitId(it) => it.module(db), + ContainerId::TraitId(it) => it.lookup(db).container, } } } @@ -512,7 +524,7 @@ impl HasModule for ConstLoc { match self.container { ContainerId::ModuleId(it) => it, ContainerId::ImplId(it) => it.lookup(db).container, - ContainerId::TraitId(it) => it.module(db), + ContainerId::TraitId(it) => it.lookup(db).container, } } } @@ -542,7 +554,7 @@ impl HasModule for GenericDefId { match self { GenericDefId::FunctionId(it) => it.lookup(db).module(db), GenericDefId::AdtId(it) => it.module(db), - GenericDefId::TraitId(it) => it.module(db), + GenericDefId::TraitId(it) => it.lookup(db).container, GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), GenericDefId::ImplId(it) => it.lookup(db).container, GenericDefId::EnumVariantId(it) => it.parent.module(db), diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index b33507a9a..a7bdd620b 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -26,7 +26,7 @@ use crate::{ per_ns::PerNs, AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplLoc, Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, - TraitId, TypeAliasLoc, UnionId, + TraitLoc, TypeAliasLoc, UnionId, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -796,7 +796,12 @@ where PerNs::values(def.into()) } - raw::DefKind::Trait(ast_id) => PerNs::types(TraitId::from_ast_id(ctx, ast_id).into()), + raw::DefKind::Trait(ast_id) => { + let def = TraitLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db); + + PerNs::types(def.into()) + } raw::DefKind::TypeAlias(ast_id) => { let def = TypeAliasLoc { container: ContainerId::ModuleId(module), diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index f87b16b44..17b2169d2 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -17,9 +17,9 @@ use crate::{ nameres::{BuiltinShadowMode, CrateDefMap}, path::{Path, PathKind}, per_ns::PerNs, - AdtId, AstItemDef, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, - GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, - StructId, TraitId, TypeAliasId, TypeParamId, VariantId, + AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, + HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, + TypeAliasId, TypeParamId, VariantId, }; #[derive(Debug, Clone, Default)] @@ -524,7 +524,7 @@ impl HasResolver for ModuleId { impl HasResolver for TraitId { fn resolver(self, db: &impl DefDatabase) -> Resolver { - self.module(db).resolver(db).push_generic_params_scope(db, self.into()) + self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into()) } } diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs index a5c4359a7..858e4861e 100644 --- a/crates/ra_hir_def/src/src.rs +++ b/crates/ra_hir_def/src/src.rs @@ -4,7 +4,7 @@ use hir_expand::InFile; use ra_arena::map::ArenaMap; use ra_syntax::ast; -use crate::{db::DefDatabase, ConstLoc, FunctionLoc, ImplLoc, StaticLoc, TypeAliasLoc}; +use crate::{db::DefDatabase, ConstLoc, FunctionLoc, ImplLoc, StaticLoc, TraitLoc, TypeAliasLoc}; pub trait HasSource { type Value; @@ -56,6 +56,15 @@ impl HasSource for ImplLoc { } } +impl HasSource for TraitLoc { + type Value = ast::TraitDef; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + pub trait HasChildSource { type ChildId; type Value; -- cgit v1.2.3 From f135a8ea55c0a46c67713fb3b79b5f62ada430c1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 14:58:04 +0100 Subject: Move structs to new loc --- crates/ra_hir_def/src/adt.rs | 9 +++++---- crates/ra_hir_def/src/attr.rs | 2 +- crates/ra_hir_def/src/child_by_source.rs | 12 ++++++++++-- crates/ra_hir_def/src/db.rs | 6 +++--- crates/ra_hir_def/src/docs.rs | 2 +- crates/ra_hir_def/src/generics.rs | 2 +- crates/ra_hir_def/src/keys.rs | 5 +++-- crates/ra_hir_def/src/lib.rs | 24 ++++++++++++++++++------ crates/ra_hir_def/src/nameres/collector.rs | 7 ++++--- crates/ra_hir_def/src/src.rs | 13 ++++++++++++- 10 files changed, 58 insertions(+), 24 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index db3e63ef8..ef2b20f1e 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -11,8 +11,9 @@ use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; use crate::{ - db::DefDatabase, src::HasChildSource, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, - LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId, + db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, type_ref::TypeRef, + AstItemDef, EnumId, LocalEnumVariantId, LocalStructFieldId, Lookup, StructId, UnionId, + VariantId, }; /// Note that we use `StructData` for unions as well! @@ -50,7 +51,7 @@ pub struct StructFieldData { impl StructData { pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc { - let src = id.source(db); + let src = id.lookup(db).source(db); let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let variant_data = VariantData::new(src.value.kind()); let variant_data = Arc::new(variant_data); @@ -153,7 +154,7 @@ impl HasChildSource for VariantId { let src = it.parent.child_source(db); src.map(|map| map[it.local_id].kind()) } - VariantId::StructId(it) => it.source(db).map(|it| it.kind()), + VariantId::StructId(it) => it.lookup(db).source(db).map(|it| it.kind()), VariantId::UnionId(it) => it.source(db).map(|it| { it.record_field_def_list() .map(ast::StructKind::Record) diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 3347d819c..d2aa5ce8f 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -56,7 +56,7 @@ impl Attrs { Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) } AttrDefId::AdtId(it) => match it { - AdtId::StructId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AdtId::StructId(it) => attrs_from_loc(it.lookup(db), db), AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), }, diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 88c2d3f24..eba361578 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -11,8 +11,8 @@ use crate::{ dyn_map::DynMap, keys, src::{HasChildSource, HasSource}, - AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, StructFieldId, - TraitId, VariantId, + AdtId, AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, + StructFieldId, TraitId, VariantId, }; pub trait ChildBySource { @@ -98,6 +98,14 @@ impl ChildBySource for ModuleId { let src = trait_.lookup(db).source(db); res[keys::TRAIT].insert(src, trait_) } + ModuleDefId::AdtId(adt) => match adt { + AdtId::StructId(strukt) => { + let src = strukt.lookup(db).source(db); + res[keys::STRUCT].insert(src, strukt) + } + AdtId::UnionId(_) => (), + AdtId::EnumId(_) => (), + }, _ => (), } } diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index f0c2ae559..e120c7768 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -18,8 +18,8 @@ use crate::{ CrateDefMap, }, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, - ImplId, ImplLoc, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, TraitId, TraitLoc, - TypeAliasId, TypeAliasLoc, UnionId, + ImplId, ImplLoc, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, + TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, }; #[salsa::query_group(InternDatabaseStorage)] @@ -27,7 +27,7 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_function(&self, loc: FunctionLoc) -> FunctionId; #[salsa::interned] - fn intern_struct(&self, loc: ItemLoc) -> StructId; + fn intern_struct(&self, loc: StructLoc) -> StructId; #[salsa::interned] fn intern_union(&self, loc: ItemLoc) -> UnionId; #[salsa::interned] diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index 1921681fb..58143b894 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -51,7 +51,7 @@ impl Documentation { } } AttrDefId::AdtId(it) => match it { - AdtId::StructId(it) => docs_from_ast(&it.source(db).value), + AdtId::StructId(it) => docs_from_ast(&it.lookup(db).source(db).value), AdtId::EnumId(it) => docs_from_ast(&it.source(db).value), AdtId::UnionId(it) => docs_from_ast(&it.source(db).value), }, diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index cbfc3ff04..f1ce8d59a 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -71,7 +71,7 @@ impl GenericParams { src.file_id } GenericDefId::AdtId(AdtId::StructId(it)) => { - let src = it.source(db); + let src = it.lookup(db).source(db); generics.fill(&mut sm, &src.value); src.file_id } diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index 6ec58f5f9..758cf8097 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs @@ -8,8 +8,8 @@ use rustc_hash::FxHashMap; use crate::{ dyn_map::{DynMap, Policy}, - ConstId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, TraitId, TypeAliasId, - TypeParamId, + ConstId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, StructId, TraitId, + TypeAliasId, TypeParamId, }; type Key = crate::dyn_map::Key, V, AstPtrPolicy>; @@ -20,6 +20,7 @@ pub const STATIC: Key = Key::new(); pub const TYPE_ALIAS: Key = Key::new(); pub const IMPL: Key = Key::new(); pub const TRAIT: Key = Key::new(); +pub const STRUCT: Key = Key::new(); pub const ENUM_VARIANT: Key = Key::new(); pub const TUPLE_FIELD: Key = Key::new(); diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 0fcc2cde4..1a599706a 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -149,12 +149,24 @@ impl Lookup for FunctionId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StructId(salsa::InternId); impl_intern_key!(StructId); -impl AstItemDef for StructId { - fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_struct(loc) + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct StructLoc { + pub container: ModuleId, + pub ast_id: AstId, +} + +impl Intern for StructLoc { + type ID = StructId; + fn intern(self, db: &impl db::DefDatabase) -> StructId { + db.intern_struct(self) } - fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_struct(self) +} + +impl Lookup for StructId { + type Data = StructLoc; + fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc { + db.lookup_intern_struct(*self) } } @@ -532,7 +544,7 @@ impl HasModule for ConstLoc { impl HasModule for AdtId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match self { - AdtId::StructId(it) => it.module(db), + AdtId::StructId(it) => it.lookup(db).container, AdtId::UnionId(it) => it.module(db), AdtId::EnumId(it) => it.module(db), } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index a7bdd620b..602ec0911 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -25,7 +25,7 @@ use crate::{ path::{Path, PathKind}, per_ns::PerNs, AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplLoc, - Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructId, + Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionId, }; @@ -773,8 +773,9 @@ where PerNs::values(def.into()) } raw::DefKind::Struct(ast_id) => { - let id = StructId::from_ast_id(ctx, ast_id).into(); - PerNs::both(id, id) + let def = StructLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db); + PerNs::both(def.into(), def.into()) } raw::DefKind::Union(ast_id) => { let id = UnionId::from_ast_id(ctx, ast_id).into(); diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs index 858e4861e..7e212adb1 100644 --- a/crates/ra_hir_def/src/src.rs +++ b/crates/ra_hir_def/src/src.rs @@ -4,7 +4,9 @@ use hir_expand::InFile; use ra_arena::map::ArenaMap; use ra_syntax::ast; -use crate::{db::DefDatabase, ConstLoc, FunctionLoc, ImplLoc, StaticLoc, TraitLoc, TypeAliasLoc}; +use crate::{ + db::DefDatabase, ConstLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, +}; pub trait HasSource { type Value; @@ -65,6 +67,15 @@ impl HasSource for TraitLoc { } } +impl HasSource for StructLoc { + type Value = ast::StructDef; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + pub trait HasChildSource { type ChildId; type Value; -- cgit v1.2.3 From 56710f119b7114efac237ac36ea21730b8bd5311 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 15:11:57 +0100 Subject: Move enum&union to new loc --- crates/ra_hir_def/src/adt.rs | 13 ++++---- crates/ra_hir_def/src/attr.rs | 7 ++--- crates/ra_hir_def/src/child_by_source.rs | 10 ++++-- crates/ra_hir_def/src/db.rs | 12 +++---- crates/ra_hir_def/src/docs.rs | 6 ++-- crates/ra_hir_def/src/generics.rs | 6 ++-- crates/ra_hir_def/src/keys.rs | 4 ++- crates/ra_hir_def/src/lib.rs | 50 ++++++++++++++++++++++-------- crates/ra_hir_def/src/nameres/collector.rs | 19 +++++++----- crates/ra_hir_def/src/src.rs | 21 ++++++++++++- 10 files changed, 100 insertions(+), 48 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index ef2b20f1e..ec3d57d1a 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -11,9 +11,8 @@ use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; use crate::{ - db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, type_ref::TypeRef, - AstItemDef, EnumId, LocalEnumVariantId, LocalStructFieldId, Lookup, StructId, UnionId, - VariantId, + db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, type_ref::TypeRef, EnumId, + LocalEnumVariantId, LocalStructFieldId, Lookup, StructId, UnionId, VariantId, }; /// Note that we use `StructData` for unions as well! @@ -58,7 +57,7 @@ impl StructData { Arc::new(StructData { name, variant_data }) } pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc { - let src = id.source(db); + let src = id.lookup(db).source(db); let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let variant_data = VariantData::new( src.value @@ -73,7 +72,7 @@ impl StructData { impl EnumData { pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc { - let src = e.source(db); + let src = e.lookup(db).source(db); let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let mut trace = Trace::new_for_arena(); lower_enum(&mut trace, &src.value); @@ -90,7 +89,7 @@ impl HasChildSource for EnumId { type ChildId = LocalEnumVariantId; type Value = ast::EnumVariant; fn child_source(&self, db: &impl DefDatabase) -> InFile> { - let src = self.source(db); + let src = self.lookup(db).source(db); let mut trace = Trace::new_for_map(); lower_enum(&mut trace, &src.value); src.with_value(trace.into_map()) @@ -155,7 +154,7 @@ impl HasChildSource for VariantId { src.map(|map| map[it.local_id].kind()) } VariantId::StructId(it) => it.lookup(db).source(db).map(|it| it.kind()), - VariantId::UnionId(it) => it.source(db).map(|it| { + VariantId::UnionId(it) => it.lookup(db).source(db).map(|it| { it.record_field_def_list() .map(ast::StructKind::Record) .unwrap_or(ast::StructKind::Unit) diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index d2aa5ce8f..5bf82e191 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -12,8 +12,7 @@ use ra_syntax::{ use tt::Subtree; use crate::{ - db::DefDatabase, path::Path, src::HasChildSource, src::HasSource, AdtId, AstItemDef, AttrDefId, - Lookup, + db::DefDatabase, path::Path, src::HasChildSource, src::HasSource, AdtId, AttrDefId, Lookup, }; #[derive(Default, Debug, Clone, PartialEq, Eq)] @@ -57,8 +56,8 @@ impl Attrs { } AttrDefId::AdtId(it) => match it { AdtId::StructId(it) => attrs_from_loc(it.lookup(db), db), - AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), - AdtId::UnionId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), + AdtId::EnumId(it) => attrs_from_loc(it.lookup(db), db), + AdtId::UnionId(it) => attrs_from_loc(it.lookup(db), db), }, AttrDefId::TraitId(it) => attrs_from_loc(it.lookup(db), db), AttrDefId::MacroDefId(it) => { diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index eba361578..3c9379b15 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -103,8 +103,14 @@ impl ChildBySource for ModuleId { let src = strukt.lookup(db).source(db); res[keys::STRUCT].insert(src, strukt) } - AdtId::UnionId(_) => (), - AdtId::EnumId(_) => (), + AdtId::UnionId(union_) => { + let src = union_.lookup(db).source(db); + res[keys::UNION].insert(src, union_) + } + AdtId::EnumId(enum_) => { + let src = enum_.lookup(db).source(db); + res[keys::ENUM].insert(src, enum_) + } }, _ => (), } diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index e120c7768..98bff6cb7 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use hir_expand::{db::AstDatabase, HirFileId}; use ra_db::{salsa, CrateId, SourceDatabase}; -use ra_syntax::{ast, SmolStr}; +use ra_syntax::SmolStr; use crate::{ adt::{EnumData, StructData}, @@ -17,9 +17,9 @@ use crate::{ raw::{ImportSourceMap, RawItems}, CrateDefMap, }, - AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, FunctionId, FunctionLoc, GenericDefId, - ImplId, ImplLoc, ItemLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, - TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, + AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, + GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, + TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, }; #[salsa::query_group(InternDatabaseStorage)] @@ -29,9 +29,9 @@ pub trait InternDatabase: SourceDatabase { #[salsa::interned] fn intern_struct(&self, loc: StructLoc) -> StructId; #[salsa::interned] - fn intern_union(&self, loc: ItemLoc) -> UnionId; + fn intern_union(&self, loc: UnionLoc) -> UnionId; #[salsa::interned] - fn intern_enum(&self, loc: ItemLoc) -> EnumId; + fn intern_enum(&self, loc: EnumLoc) -> EnumId; #[salsa::interned] fn intern_const(&self, loc: ConstLoc) -> ConstId; #[salsa::interned] diff --git a/crates/ra_hir_def/src/docs.rs b/crates/ra_hir_def/src/docs.rs index 58143b894..b29f142e3 100644 --- a/crates/ra_hir_def/src/docs.rs +++ b/crates/ra_hir_def/src/docs.rs @@ -11,7 +11,7 @@ use ra_syntax::ast; use crate::{ db::DefDatabase, src::{HasChildSource, HasSource}, - AdtId, AstItemDef, AttrDefId, Lookup, + AdtId, AttrDefId, Lookup, }; /// Holds documentation @@ -52,8 +52,8 @@ impl Documentation { } AttrDefId::AdtId(it) => match it { AdtId::StructId(it) => docs_from_ast(&it.lookup(db).source(db).value), - AdtId::EnumId(it) => docs_from_ast(&it.source(db).value), - AdtId::UnionId(it) => docs_from_ast(&it.source(db).value), + AdtId::EnumId(it) => docs_from_ast(&it.lookup(db).source(db).value), + AdtId::UnionId(it) => docs_from_ast(&it.lookup(db).source(db).value), }, AttrDefId::EnumVariantId(it) => { let src = it.parent.child_source(db); diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index f1ce8d59a..e502dd798 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -21,7 +21,7 @@ use crate::{ src::HasChildSource, src::HasSource, type_ref::{TypeBound, TypeRef}, - AdtId, AstItemDef, GenericDefId, LocalTypeParamId, Lookup, TypeParamId, + AdtId, GenericDefId, LocalTypeParamId, Lookup, TypeParamId, }; /// Data about a generic parameter (to a function, struct, impl, ...). @@ -76,12 +76,12 @@ impl GenericParams { src.file_id } GenericDefId::AdtId(AdtId::UnionId(it)) => { - let src = it.source(db); + let src = it.lookup(db).source(db); generics.fill(&mut sm, &src.value); src.file_id } GenericDefId::AdtId(AdtId::EnumId(it)) => { - let src = it.source(db); + let src = it.lookup(db).source(db); generics.fill(&mut sm, &src.value); src.file_id } diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index 758cf8097..ada145379 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs @@ -9,7 +9,7 @@ use rustc_hash::FxHashMap; use crate::{ dyn_map::{DynMap, Policy}, ConstId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, StructId, TraitId, - TypeAliasId, TypeParamId, + TypeAliasId, TypeParamId, EnumId, UnionId, }; type Key = crate::dyn_map::Key, V, AstPtrPolicy>; @@ -21,6 +21,8 @@ pub const TYPE_ALIAS: Key = Key::new(); pub const IMPL: Key = Key::new(); pub const TRAIT: Key = Key::new(); pub const STRUCT: Key = Key::new(); +pub const UNION: Key = Key::new(); +pub const ENUM: Key = Key::new(); pub const ENUM_VARIANT: Key = Key::new(); pub const TUPLE_FIELD: Key = Key::new(); diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 1a599706a..c9e4e6a0f 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -173,24 +173,48 @@ impl Lookup for StructId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UnionId(salsa::InternId); impl_intern_key!(UnionId); -impl AstItemDef for UnionId { - fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_union(loc) + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct UnionLoc { + pub container: ModuleId, + pub ast_id: AstId, +} + +impl Intern for UnionLoc { + type ID = UnionId; + fn intern(self, db: &impl db::DefDatabase) -> UnionId { + db.intern_union(self) } - fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_union(self) +} + +impl Lookup for UnionId { + type Data = UnionLoc; + fn lookup(&self, db: &impl db::DefDatabase) -> UnionLoc { + db.lookup_intern_union(*self) } } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct EnumId(salsa::InternId); impl_intern_key!(EnumId); -impl AstItemDef for EnumId { - fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self { - db.intern_enum(loc) + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct EnumLoc { + pub container: ModuleId, + pub ast_id: AstId, +} + +impl Intern for EnumLoc { + type ID = EnumId; + fn intern(self, db: &impl db::DefDatabase) -> EnumId { + db.intern_enum(self) } - fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc { - db.lookup_intern_enum(self) +} + +impl Lookup for EnumId { + type Data = EnumLoc; + fn lookup(&self, db: &impl db::DefDatabase) -> EnumLoc { + db.lookup_intern_enum(*self) } } @@ -545,8 +569,8 @@ impl HasModule for AdtId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match self { AdtId::StructId(it) => it.lookup(db).container, - AdtId::UnionId(it) => it.module(db), - AdtId::EnumId(it) => it.module(db), + AdtId::UnionId(it) => it.lookup(db).container, + AdtId::EnumId(it) => it.lookup(db).container, } } } @@ -569,7 +593,7 @@ impl HasModule for GenericDefId { GenericDefId::TraitId(it) => it.lookup(db).container, GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), GenericDefId::ImplId(it) => it.lookup(db).container, - GenericDefId::EnumVariantId(it) => it.parent.module(db), + GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container, GenericDefId::ConstId(it) => it.lookup(db).module(db), } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 602ec0911..04aadead1 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -24,9 +24,9 @@ use crate::{ }, path::{Path, PathKind}, per_ns::PerNs, - AdtId, AstId, AstItemDef, ConstLoc, ContainerId, EnumId, EnumVariantId, FunctionLoc, ImplLoc, - Intern, LocalImportId, LocalModuleId, LocationCtx, ModuleDefId, ModuleId, StaticLoc, StructLoc, - TraitLoc, TypeAliasLoc, UnionId, + AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, + LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, + TypeAliasLoc, UnionLoc, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -753,8 +753,6 @@ where fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; - let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); - // FIXME: check attrs to see if this is an attribute macro invocation; // in which case we don't add the invocation, just a single attribute // macro invocation @@ -778,10 +776,15 @@ where PerNs::both(def.into(), def.into()) } raw::DefKind::Union(ast_id) => { - let id = UnionId::from_ast_id(ctx, ast_id).into(); - PerNs::both(id, id) + let def = UnionLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db); + PerNs::both(def.into(), def.into()) + } + raw::DefKind::Enum(ast_id) => { + let def = EnumLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db); + PerNs::types(def.into()) } - raw::DefKind::Enum(ast_id) => PerNs::types(EnumId::from_ast_id(ctx, ast_id).into()), raw::DefKind::Const(ast_id) => { let def = ConstLoc { container: ContainerId::ModuleId(module), diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs index 7e212adb1..20200d1db 100644 --- a/crates/ra_hir_def/src/src.rs +++ b/crates/ra_hir_def/src/src.rs @@ -5,7 +5,8 @@ use ra_arena::map::ArenaMap; use ra_syntax::ast; use crate::{ - db::DefDatabase, ConstLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, + db::DefDatabase, ConstLoc, EnumLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc, + TypeAliasLoc, UnionLoc, }; pub trait HasSource { @@ -76,6 +77,24 @@ impl HasSource for StructLoc { } } +impl HasSource for UnionLoc { + type Value = ast::UnionDef; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + +impl HasSource for EnumLoc { + type Value = ast::EnumDef; + + fn source(&self, db: &impl DefDatabase) -> InFile { + let node = self.ast_id.to_node(db); + InFile::new(self.ast_id.file_id, node) + } +} + pub trait HasChildSource { type ChildId; type Value; -- cgit v1.2.3 From 7a255a2f9381ba5886cacc48c1dd0420a739a55c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 15:13:05 +0100 Subject: Remove old location infra --- crates/ra_hir_def/src/keys.rs | 4 +-- crates/ra_hir_def/src/lib.rs | 65 +++---------------------------------------- 2 files changed, 6 insertions(+), 63 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index ada145379..4611c6e38 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs @@ -8,8 +8,8 @@ use rustc_hash::FxHashMap; use crate::{ dyn_map::{DynMap, Policy}, - ConstId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, StructId, TraitId, - TypeAliasId, TypeParamId, EnumId, UnionId, + ConstId, EnumId, EnumVariantId, FunctionId, ImplId, StaticId, StructFieldId, StructId, TraitId, + TypeAliasId, TypeParamId, UnionId, }; type Key = crate::dyn_map::Key, V, AstPtrPolicy>; diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index c9e4e6a0f..f085bbe87 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -40,14 +40,14 @@ mod test_db; #[cfg(test)] mod marks; -use std::hash::{Hash, Hasher}; +use std::hash::Hash; -use hir_expand::{ast_id_map::FileAstId, db::AstDatabase, AstId, HirFileId, InFile, MacroDefId}; +use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; use ra_arena::{impl_arena_id, RawId}; use ra_db::{impl_intern_key, salsa, CrateId}; -use ra_syntax::{ast, AstNode}; +use ra_syntax::ast; -use crate::{builtin_type::BuiltinType, db::InternDatabase}; +use crate::builtin_type::BuiltinType; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct LocalImportId(RawId); @@ -65,63 +65,6 @@ pub struct ModuleId { pub struct LocalModuleId(RawId); impl_arena_id!(LocalModuleId); -#[derive(Debug)] -pub struct ItemLoc { - pub(crate) module: ModuleId, - ast_id: AstId, -} - -impl PartialEq for ItemLoc { - fn eq(&self, other: &Self) -> bool { - self.module == other.module && self.ast_id == other.ast_id - } -} -impl Eq for ItemLoc {} -impl Hash for ItemLoc { - fn hash(&self, hasher: &mut H) { - self.module.hash(hasher); - self.ast_id.hash(hasher); - } -} - -impl Clone for ItemLoc { - fn clone(&self) -> ItemLoc { - ItemLoc { module: self.module, ast_id: self.ast_id } - } -} - -#[derive(Clone, Copy)] -pub struct LocationCtx { - db: DB, - module: ModuleId, - file_id: HirFileId, -} - -impl<'a, DB> LocationCtx<&'a DB> { - pub fn new(db: &'a DB, module: ModuleId, file_id: HirFileId) -> LocationCtx<&'a DB> { - LocationCtx { db, module, file_id } - } -} - -pub trait AstItemDef: salsa::InternKey + Clone { - fn intern(db: &impl InternDatabase, loc: ItemLoc) -> Self; - fn lookup_intern(self, db: &impl InternDatabase) -> ItemLoc; - - fn from_ast_id(ctx: LocationCtx<&impl InternDatabase>, ast_id: FileAstId) -> Self { - let loc = ItemLoc { module: ctx.module, ast_id: AstId::new(ctx.file_id, ast_id) }; - Self::intern(ctx.db, loc) - } - fn source(self, db: &(impl AstDatabase + InternDatabase)) -> InFile { - let loc = self.lookup_intern(db); - let value = loc.ast_id.to_node(db); - InFile { file_id: loc.ast_id.file_id, value } - } - fn module(self, db: &impl InternDatabase) -> ModuleId { - let loc = self.lookup_intern(db); - loc.module - } -} - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct FunctionId(salsa::InternId); impl_intern_key!(FunctionId); -- cgit v1.2.3 From 8e65b773874909985b6ffc9247ea9dfbaac6a02b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 15:50:16 +0100 Subject: Dedupe from_source impls --- crates/ra_hir_def/src/keys.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/keys.rs b/crates/ra_hir_def/src/keys.rs index 4611c6e38..d844f7a62 100644 --- a/crates/ra_hir_def/src/keys.rs +++ b/crates/ra_hir_def/src/keys.rs @@ -12,7 +12,7 @@ use crate::{ TypeAliasId, TypeParamId, UnionId, }; -type Key = crate::dyn_map::Key, V, AstPtrPolicy>; +pub type Key = crate::dyn_map::Key, V, AstPtrPolicy>; pub const FUNCTION: Key = Key::new(); pub const CONST: Key = Key::new(); -- cgit v1.2.3 From 125559c14b0e85bb69e9b2759d7ecd33a73ea443 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 17:15:57 +0100 Subject: Move use tree lowering to a separate module --- crates/ra_hir_def/src/path.rs | 107 +---------------------------- crates/ra_hir_def/src/path/lower_use.rs | 115 ++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 104 deletions(-) create mode 100644 crates/ra_hir_def/src/path/lower_use.rs (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index e547b2f03..ddb53ee7c 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -1,4 +1,5 @@ //! A desugared representation of paths like `crate::foo` or `::bar`. +mod lower_use; use std::{iter, sync::Arc}; @@ -9,7 +10,7 @@ use hir_expand::{ }; use ra_db::CrateId; use ra_syntax::{ - ast::{self, NameOwner, TypeAscriptionOwner}, + ast::{self, TypeAscriptionOwner}, AstNode, }; @@ -72,7 +73,7 @@ impl Path { mut cb: impl FnMut(Path, &ast::UseTree, bool, Option), ) { if let Some(tree) = item_src.value.use_tree() { - expand_use_tree(None, tree, hygiene, &mut cb); + lower_use::lower_use_tree(None, tree, hygiene, &mut cb); } } @@ -296,108 +297,6 @@ impl From for Path { } } -fn expand_use_tree( - prefix: Option, - tree: ast::UseTree, - hygiene: &Hygiene, - cb: &mut dyn FnMut(Path, &ast::UseTree, bool, Option), -) { - if let Some(use_tree_list) = tree.use_tree_list() { - let prefix = match tree.path() { - // E.g. use something::{{{inner}}}; - None => prefix, - // E.g. `use something::{inner}` (prefix is `None`, path is `something`) - // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) - Some(path) => match convert_path(prefix, path, hygiene) { - Some(it) => Some(it), - None => return, // FIXME: report errors somewhere - }, - }; - for child_tree in use_tree_list.use_trees() { - expand_use_tree(prefix.clone(), child_tree, hygiene, cb); - } - } else { - let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); - if let Some(ast_path) = tree.path() { - // Handle self in a path. - // E.g. `use something::{self, <...>}` - if ast_path.qualifier().is_none() { - if let Some(segment) = ast_path.segment() { - if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { - if let Some(prefix) = prefix { - cb(prefix, &tree, false, alias); - return; - } - } - } - } - if let Some(path) = convert_path(prefix, ast_path, hygiene) { - let is_glob = tree.has_star(); - cb(path, &tree, is_glob, alias) - } - // FIXME: report errors somewhere - // We get here if we do - } - } -} - -fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> Option { - let prefix = if let Some(qual) = path.qualifier() { - Some(convert_path(prefix, qual, hygiene)?) - } else { - prefix - }; - - let segment = path.segment()?; - let res = match segment.kind()? { - ast::PathSegmentKind::Name(name_ref) => { - match hygiene.name_ref_to_name(name_ref) { - Either::Left(name) => { - // no type args in use - let mut res = prefix.unwrap_or_else(|| Path { - kind: PathKind::Plain, - segments: Vec::with_capacity(1), - }); - res.segments.push(PathSegment { - name, - args_and_bindings: None, // no type args in use - }); - res - } - Either::Right(crate_id) => { - return Some(Path::from_simple_segments( - PathKind::DollarCrate(crate_id), - iter::empty(), - )) - } - } - } - ast::PathSegmentKind::CrateKw => { - if prefix.is_some() { - return None; - } - Path::from_simple_segments(PathKind::Crate, iter::empty()) - } - ast::PathSegmentKind::SelfKw => { - if prefix.is_some() { - return None; - } - Path::from_simple_segments(PathKind::Self_, iter::empty()) - } - ast::PathSegmentKind::SuperKw => { - if prefix.is_some() { - return None; - } - Path::from_simple_segments(PathKind::Super, iter::empty()) - } - ast::PathSegmentKind::Type { .. } => { - // not allowed in imports - return None; - } - }; - Some(res) -} - pub mod known { use hir_expand::name; diff --git a/crates/ra_hir_def/src/path/lower_use.rs b/crates/ra_hir_def/src/path/lower_use.rs new file mode 100644 index 000000000..e2e1f716d --- /dev/null +++ b/crates/ra_hir_def/src/path/lower_use.rs @@ -0,0 +1,115 @@ +//! Lowers a single complex use like `use foo::{bar, baz};` into a list of paths like +//! `foo::bar`, `foo::baz`; + +use std::iter; + +use either::Either; +use hir_expand::{ + hygiene::Hygiene, + name::{AsName, Name}, +}; +use ra_syntax::ast::{self, NameOwner}; + +use crate::path::{Path, PathKind, PathSegment}; + +pub(crate) fn lower_use_tree( + prefix: Option, + tree: ast::UseTree, + hygiene: &Hygiene, + cb: &mut dyn FnMut(Path, &ast::UseTree, bool, Option), +) { + if let Some(use_tree_list) = tree.use_tree_list() { + let prefix = match tree.path() { + // E.g. use something::{{{inner}}}; + None => prefix, + // E.g. `use something::{inner}` (prefix is `None`, path is `something`) + // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) + Some(path) => match convert_path(prefix, path, hygiene) { + Some(it) => Some(it), + None => return, // FIXME: report errors somewhere + }, + }; + for child_tree in use_tree_list.use_trees() { + lower_use_tree(prefix.clone(), child_tree, hygiene, cb); + } + } else { + let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); + if let Some(ast_path) = tree.path() { + // Handle self in a path. + // E.g. `use something::{self, <...>}` + if ast_path.qualifier().is_none() { + if let Some(segment) = ast_path.segment() { + if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { + if let Some(prefix) = prefix { + cb(prefix, &tree, false, alias); + return; + } + } + } + } + if let Some(path) = convert_path(prefix, ast_path, hygiene) { + let is_glob = tree.has_star(); + cb(path, &tree, is_glob, alias) + } + // FIXME: report errors somewhere + // We get here if we do + } + } +} + +fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> Option { + let prefix = if let Some(qual) = path.qualifier() { + Some(convert_path(prefix, qual, hygiene)?) + } else { + prefix + }; + + let segment = path.segment()?; + let res = match segment.kind()? { + ast::PathSegmentKind::Name(name_ref) => { + match hygiene.name_ref_to_name(name_ref) { + Either::Left(name) => { + // no type args in use + let mut res = prefix.unwrap_or_else(|| Path { + kind: PathKind::Plain, + segments: Vec::with_capacity(1), + }); + res.segments.push(PathSegment { + name, + args_and_bindings: None, // no type args in use + }); + res + } + Either::Right(crate_id) => { + return Some(Path::from_simple_segments( + PathKind::DollarCrate(crate_id), + iter::empty(), + )) + } + } + } + ast::PathSegmentKind::CrateKw => { + if prefix.is_some() { + return None; + } + Path::from_simple_segments(PathKind::Crate, iter::empty()) + } + ast::PathSegmentKind::SelfKw => { + if prefix.is_some() { + return None; + } + Path::from_simple_segments(PathKind::Self_, iter::empty()) + } + ast::PathSegmentKind::SuperKw => { + if prefix.is_some() { + return None; + } + Path::from_simple_segments(PathKind::Super, iter::empty()) + } + ast::PathSegmentKind::Type { .. } => { + // not allowed in imports + return None; + } + }; + Some(res) +} -- cgit v1.2.3 From 332f2205b092744265914a4064b61161ba368df3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 12 Dec 2019 17:17:57 +0100 Subject: Correct obsolete comment --- crates/ra_hir_def/src/path.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index ddb53ee7c..ec9d13e82 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -29,8 +29,7 @@ pub struct PathSegment { } /// Generic arguments to a path segment (e.g. the `i32` in `Option`). This -/// can (in the future) also include bindings of associated types, like in -/// `Iterator`. +/// also includes bindings of associated types, like in `Iterator`. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct GenericArgs { pub args: Vec, -- cgit v1.2.3 From 77052090515c1bb2a00236b3a57cdd778e581c8c Mon Sep 17 00:00:00 2001 From: Emil Lauridsen Date: Fri, 13 Dec 2019 12:44:42 +0100 Subject: Correctly infer - and ! using std::ops::{Neg,Not} --- crates/ra_hir_def/src/path.rs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index ec9d13e82..50f0cad94 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -342,6 +342,14 @@ pub mod known { ) } + pub fn std_ops_neg() -> Path { + Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::NEG_TYPE]) + } + + pub fn std_ops_not() -> Path { + Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::NOT_TYPE]) + } + pub fn std_result_result() -> Path { Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE]) } -- cgit v1.2.3 From 259c42f00e2e85594c7373166bc8467ce375a045 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 13 Dec 2019 21:43:53 +0100 Subject: Add macros for known names and paths --- crates/ra_hir_def/src/body/lower.rs | 4 +-- crates/ra_hir_def/src/builtin_type.rs | 42 ++++++++++++++-------------- crates/ra_hir_def/src/data.rs | 4 +-- crates/ra_hir_def/src/generics.rs | 6 ++-- crates/ra_hir_def/src/nameres/collector.rs | 4 +-- crates/ra_hir_def/src/path.rs | 45 +++++++++++++----------------- crates/ra_hir_def/src/resolver.rs | 16 +++++------ 7 files changed, 58 insertions(+), 63 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index cc068ff94..6c760166f 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -2,7 +2,7 @@ //! representation. use either::Either; -use hir_expand::name::{self, AsName, Name}; +use hir_expand::name::{AsName, Name, N}; use ra_arena::Arena; use ra_syntax::{ ast::{ @@ -68,7 +68,7 @@ where let ptr = AstPtr::new(&self_param); let param_pat = self.alloc_pat( Pat::Bind { - name: name::SELF_PARAM, + name: N![self], mode: BindingAnnotation::Unannotated, subpat: None, }, diff --git a/crates/ra_hir_def/src/builtin_type.rs b/crates/ra_hir_def/src/builtin_type.rs index 5e8157144..757123f82 100644 --- a/crates/ra_hir_def/src/builtin_type.rs +++ b/crates/ra_hir_def/src/builtin_type.rs @@ -5,7 +5,7 @@ use std::fmt; -use hir_expand::name::{self, Name}; +use hir_expand::name::{Name, N}; #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum Signedness { @@ -52,26 +52,26 @@ pub enum BuiltinType { impl BuiltinType { #[rustfmt::skip] pub const ALL: &'static [(Name, BuiltinType)] = &[ - (name::CHAR, BuiltinType::Char), - (name::BOOL, BuiltinType::Bool), - (name::STR, BuiltinType::Str ), - - (name::ISIZE, BuiltinType::Int(BuiltinInt::ISIZE)), - (name::I8, BuiltinType::Int(BuiltinInt::I8)), - (name::I16, BuiltinType::Int(BuiltinInt::I16)), - (name::I32, BuiltinType::Int(BuiltinInt::I32)), - (name::I64, BuiltinType::Int(BuiltinInt::I64)), - (name::I128, BuiltinType::Int(BuiltinInt::I128)), - - (name::USIZE, BuiltinType::Int(BuiltinInt::USIZE)), - (name::U8, BuiltinType::Int(BuiltinInt::U8)), - (name::U16, BuiltinType::Int(BuiltinInt::U16)), - (name::U32, BuiltinType::Int(BuiltinInt::U32)), - (name::U64, BuiltinType::Int(BuiltinInt::U64)), - (name::U128, BuiltinType::Int(BuiltinInt::U128)), - - (name::F32, BuiltinType::Float(BuiltinFloat::F32)), - (name::F64, BuiltinType::Float(BuiltinFloat::F64)), + (N![char], BuiltinType::Char), + (N![bool], BuiltinType::Bool), + (N![str], BuiltinType::Str), + + (N![isize], BuiltinType::Int(BuiltinInt::ISIZE)), + (N![i8], BuiltinType::Int(BuiltinInt::I8)), + (N![i16], BuiltinType::Int(BuiltinInt::I16)), + (N![i32], BuiltinType::Int(BuiltinInt::I32)), + (N![i64], BuiltinType::Int(BuiltinInt::I64)), + (N![i128], BuiltinType::Int(BuiltinInt::I128)), + + (N![usize], BuiltinType::Int(BuiltinInt::USIZE)), + (N![u8], BuiltinType::Int(BuiltinInt::U8)), + (N![u16], BuiltinType::Int(BuiltinInt::U16)), + (N![u32], BuiltinType::Int(BuiltinInt::U32)), + (N![u64], BuiltinType::Int(BuiltinInt::U64)), + (N![u128], BuiltinType::Int(BuiltinInt::U128)), + + (N![f32], BuiltinType::Float(BuiltinFloat::F32)), + (N![f64], BuiltinType::Float(BuiltinFloat::F64)), ]; } diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index b2dac183e..afeac0ec2 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use hir_expand::{ - name::{self, AsName, Name}, + name::{AsName, Name, N}, AstId, }; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; @@ -37,7 +37,7 @@ impl FunctionData { let self_type = if let Some(type_ref) = self_param.ascribed_type() { TypeRef::from_ast(type_ref) } else { - let self_type = TypeRef::Path(name::SELF_TYPE.into()); + let self_type = TypeRef::Path(N![Self].into()); match self_param.kind() { ast::SelfParamKind::Owned => self_type, ast::SelfParamKind::Ref => { diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index e502dd798..2b13748f3 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use either::Either; use hir_expand::{ - name::{self, AsName, Name}, + name::{AsName, Name, N}, InFile, }; use ra_arena::{map::ArenaMap, Arena}; @@ -90,11 +90,11 @@ impl GenericParams { // traits get the Self type as an implicit first type parameter let self_param_id = - generics.types.alloc(TypeParamData { name: name::SELF_TYPE, default: None }); + generics.types.alloc(TypeParamData { name: N![Self], default: None }); sm.insert(self_param_id, Either::Left(src.value.clone())); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar - let self_param = TypeRef::Path(name::SELF_TYPE.into()); + let self_param = TypeRef::Path(N![Self].into()); generics.fill_bounds(&src.value, self_param); generics.fill(&mut sm, &src.value); diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 04aadead1..e81bac914 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -6,7 +6,7 @@ use hir_expand::{ builtin_derive::find_builtin_derive, builtin_macro::find_builtin_macro, - name::{self, AsName, Name}, + name::{AsName, Name, N}, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; use ra_cfg::CfgOptions; @@ -918,7 +918,7 @@ where } fn is_macro_rules(path: &Path) -> bool { - path.as_ident() == Some(&name::MACRO_RULES) + path.as_ident() == Some(&N![macro_rules]) } #[cfg(test)] diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 50f0cad94..36ad27867 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -6,7 +6,7 @@ use std::{iter, sync::Arc}; use either::Either; use hir_expand::{ hygiene::Hygiene, - name::{self, AsName, Name}, + name::{AsName, Name, N}, }; use ra_db::CrateId; use ra_syntax::{ @@ -276,7 +276,7 @@ impl GenericArgs { } if let Some(ret_type) = ret_type { let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); - bindings.push((name::OUTPUT_TYPE, type_ref)) + bindings.push((N![Output], type_ref)) } if args.is_empty() && bindings.is_empty() { None @@ -297,68 +297,63 @@ impl From for Path { } pub mod known { - use hir_expand::name; + use hir_expand::name::N; use super::{Path, PathKind}; + macro_rules! P { + ($start:ident $(:: $seg:ident)*) => { Path::from_simple_segments(PathKind::Abs, vec![N![$start], $(N![$seg],)*]) }; + } + pub fn std_iter_into_iterator() -> Path { - Path::from_simple_segments( - PathKind::Abs, - vec![name::STD, name::ITER, name::INTO_ITERATOR_TYPE], - ) + P![std::iter::IntoIterator] } pub fn std_ops_try() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::TRY_TYPE]) + P![std::ops::Try] } pub fn std_ops_range() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TYPE]) + P![std::ops::Range] } pub fn std_ops_range_from() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FROM_TYPE]) + P![std::ops::RangeFrom] } pub fn std_ops_range_full() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_FULL_TYPE]) + P![std::ops::RangeFull] } pub fn std_ops_range_inclusive() -> Path { - Path::from_simple_segments( - PathKind::Abs, - vec![name::STD, name::OPS, name::RANGE_INCLUSIVE_TYPE], - ) + P![std::ops::RangeInclusive] } pub fn std_ops_range_to() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::RANGE_TO_TYPE]) + P![std::ops::RangeTo] } pub fn std_ops_range_to_inclusive() -> Path { - Path::from_simple_segments( - PathKind::Abs, - vec![name::STD, name::OPS, name::RANGE_TO_INCLUSIVE_TYPE], - ) + P![std::ops::RangeToInclusive] } pub fn std_ops_neg() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::NEG_TYPE]) + P![std::ops::Neg] } pub fn std_ops_not() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::OPS, name::NOT_TYPE]) + P![std::ops::Not] } pub fn std_result_result() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::RESULT, name::RESULT_TYPE]) + P![std::result::Result] } pub fn std_future_future() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::FUTURE, name::FUTURE_TYPE]) + P![std::future::Future] } pub fn std_boxed_box() -> Path { - Path::from_simple_segments(PathKind::Abs, vec![name::STD, name::BOXED, name::BOX_TYPE]) + P![std::boxed::Box] } } diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 17b2169d2..0fb529527 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use hir_expand::{ - name::{self, Name}, + name::{Name, N}, MacroDefId, }; use ra_db::CrateId; @@ -163,13 +163,13 @@ impl Resolver { } } Scope::ImplBlockScope(impl_) => { - if first_name == &name::SELF_TYPE { + if first_name == &N![Self] { let idx = if path.segments.len() == 1 { None } else { Some(1) }; return Some((TypeNs::SelfType(*impl_), idx)); } } Scope::AdtScope(adt) => { - if first_name == &name::SELF_TYPE { + if first_name == &N![Self] { let idx = if path.segments.len() == 1 { None } else { Some(1) }; return Some((TypeNs::AdtSelfType(*adt), idx)); } @@ -223,7 +223,7 @@ impl Resolver { return None; } let n_segments = path.segments.len(); - let tmp = name::SELF_PARAM; + let tmp = N![self]; let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); for scope in self.scopes.iter().rev() { @@ -259,13 +259,13 @@ impl Resolver { Scope::GenericParams { .. } => continue, Scope::ImplBlockScope(impl_) if n_segments > 1 => { - if first_name == &name::SELF_TYPE { + if first_name == &N![Self] { let ty = TypeNs::SelfType(*impl_); return Some(ResolveValueResult::Partial(ty, 1)); } } Scope::AdtScope(adt) if n_segments > 1 => { - if first_name == &name::SELF_TYPE { + if first_name == &N![Self] { let ty = TypeNs::AdtSelfType(*adt); return Some(ResolveValueResult::Partial(ty, 1)); } @@ -439,10 +439,10 @@ impl Scope { } } Scope::ImplBlockScope(i) => { - f(name::SELF_TYPE, ScopeDef::ImplSelfType((*i).into())); + f(N![Self], ScopeDef::ImplSelfType((*i).into())); } Scope::AdtScope(i) => { - f(name::SELF_TYPE, ScopeDef::AdtSelfType((*i).into())); + f(N![Self], ScopeDef::AdtSelfType((*i).into())); } Scope::ExprScope(scope) => { scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { -- cgit v1.2.3 From 6911bc89a784ce72b4dfd8e0ba72bd22ce898395 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 13 Dec 2019 22:01:06 +0100 Subject: Rename N! to name! --- crates/ra_hir_def/src/body/lower.rs | 4 +-- crates/ra_hir_def/src/builtin_type.rs | 42 +++++++++++++++--------------- crates/ra_hir_def/src/data.rs | 4 +-- crates/ra_hir_def/src/generics.rs | 6 ++--- crates/ra_hir_def/src/nameres/collector.rs | 4 +-- crates/ra_hir_def/src/path.rs | 8 +++--- crates/ra_hir_def/src/resolver.rs | 16 ++++++------ 7 files changed, 42 insertions(+), 42 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 6c760166f..61193b4d8 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -2,7 +2,7 @@ //! representation. use either::Either; -use hir_expand::name::{AsName, Name, N}; +use hir_expand::name::{name, AsName, Name}; use ra_arena::Arena; use ra_syntax::{ ast::{ @@ -68,7 +68,7 @@ where let ptr = AstPtr::new(&self_param); let param_pat = self.alloc_pat( Pat::Bind { - name: N![self], + name: name![self], mode: BindingAnnotation::Unannotated, subpat: None, }, diff --git a/crates/ra_hir_def/src/builtin_type.rs b/crates/ra_hir_def/src/builtin_type.rs index 757123f82..d14901a9b 100644 --- a/crates/ra_hir_def/src/builtin_type.rs +++ b/crates/ra_hir_def/src/builtin_type.rs @@ -5,7 +5,7 @@ use std::fmt; -use hir_expand::name::{Name, N}; +use hir_expand::name::{name, Name}; #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum Signedness { @@ -52,26 +52,26 @@ pub enum BuiltinType { impl BuiltinType { #[rustfmt::skip] pub const ALL: &'static [(Name, BuiltinType)] = &[ - (N![char], BuiltinType::Char), - (N![bool], BuiltinType::Bool), - (N![str], BuiltinType::Str), - - (N![isize], BuiltinType::Int(BuiltinInt::ISIZE)), - (N![i8], BuiltinType::Int(BuiltinInt::I8)), - (N![i16], BuiltinType::Int(BuiltinInt::I16)), - (N![i32], BuiltinType::Int(BuiltinInt::I32)), - (N![i64], BuiltinType::Int(BuiltinInt::I64)), - (N![i128], BuiltinType::Int(BuiltinInt::I128)), - - (N![usize], BuiltinType::Int(BuiltinInt::USIZE)), - (N![u8], BuiltinType::Int(BuiltinInt::U8)), - (N![u16], BuiltinType::Int(BuiltinInt::U16)), - (N![u32], BuiltinType::Int(BuiltinInt::U32)), - (N![u64], BuiltinType::Int(BuiltinInt::U64)), - (N![u128], BuiltinType::Int(BuiltinInt::U128)), - - (N![f32], BuiltinType::Float(BuiltinFloat::F32)), - (N![f64], BuiltinType::Float(BuiltinFloat::F64)), + (name![char], BuiltinType::Char), + (name![bool], BuiltinType::Bool), + (name![str], BuiltinType::Str), + + (name![isize], BuiltinType::Int(BuiltinInt::ISIZE)), + (name![i8], BuiltinType::Int(BuiltinInt::I8)), + (name![i16], BuiltinType::Int(BuiltinInt::I16)), + (name![i32], BuiltinType::Int(BuiltinInt::I32)), + (name![i64], BuiltinType::Int(BuiltinInt::I64)), + (name![i128], BuiltinType::Int(BuiltinInt::I128)), + + (name![usize], BuiltinType::Int(BuiltinInt::USIZE)), + (name![u8], BuiltinType::Int(BuiltinInt::U8)), + (name![u16], BuiltinType::Int(BuiltinInt::U16)), + (name![u32], BuiltinType::Int(BuiltinInt::U32)), + (name![u64], BuiltinType::Int(BuiltinInt::U64)), + (name![u128], BuiltinType::Int(BuiltinInt::U128)), + + (name![f32], BuiltinType::Float(BuiltinFloat::F32)), + (name![f64], BuiltinType::Float(BuiltinFloat::F64)), ]; } diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index afeac0ec2..4f4ef57cc 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use hir_expand::{ - name::{AsName, Name, N}, + name::{name, AsName, Name}, AstId, }; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; @@ -37,7 +37,7 @@ impl FunctionData { let self_type = if let Some(type_ref) = self_param.ascribed_type() { TypeRef::from_ast(type_ref) } else { - let self_type = TypeRef::Path(N![Self].into()); + let self_type = TypeRef::Path(name![Self].into()); match self_param.kind() { ast::SelfParamKind::Owned => self_type, ast::SelfParamKind::Ref => { diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index 2b13748f3..e9c28c730 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use either::Either; use hir_expand::{ - name::{AsName, Name, N}, + name::{name, AsName, Name}, InFile, }; use ra_arena::{map::ArenaMap, Arena}; @@ -90,11 +90,11 @@ impl GenericParams { // traits get the Self type as an implicit first type parameter let self_param_id = - generics.types.alloc(TypeParamData { name: N![Self], default: None }); + generics.types.alloc(TypeParamData { name: name![Self], default: None }); sm.insert(self_param_id, Either::Left(src.value.clone())); // add super traits as bounds on Self // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar - let self_param = TypeRef::Path(N![Self].into()); + let self_param = TypeRef::Path(name![Self].into()); generics.fill_bounds(&src.value, self_param); generics.fill(&mut sm, &src.value); diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index e81bac914..5d7469a6e 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -6,7 +6,7 @@ use hir_expand::{ builtin_derive::find_builtin_derive, builtin_macro::find_builtin_macro, - name::{AsName, Name, N}, + name::{name, AsName, Name}, HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, }; use ra_cfg::CfgOptions; @@ -918,7 +918,7 @@ where } fn is_macro_rules(path: &Path) -> bool { - path.as_ident() == Some(&N![macro_rules]) + path.as_ident() == Some(&name![macro_rules]) } #[cfg(test)] diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 36ad27867..c1376af36 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -6,7 +6,7 @@ use std::{iter, sync::Arc}; use either::Either; use hir_expand::{ hygiene::Hygiene, - name::{AsName, Name, N}, + name::{name, AsName, Name}, }; use ra_db::CrateId; use ra_syntax::{ @@ -276,7 +276,7 @@ impl GenericArgs { } if let Some(ret_type) = ret_type { let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); - bindings.push((N![Output], type_ref)) + bindings.push((name![Output], type_ref)) } if args.is_empty() && bindings.is_empty() { None @@ -297,12 +297,12 @@ impl From for Path { } pub mod known { - use hir_expand::name::N; + use hir_expand::name::name; use super::{Path, PathKind}; macro_rules! P { - ($start:ident $(:: $seg:ident)*) => { Path::from_simple_segments(PathKind::Abs, vec![N![$start], $(N![$seg],)*]) }; + ($start:ident $(:: $seg:ident)*) => { Path::from_simple_segments(PathKind::Abs, vec![name![$start], $(name![$seg],)*]) }; } pub fn std_iter_into_iterator() -> Path { diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 0fb529527..b6d595a20 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use hir_expand::{ - name::{Name, N}, + name::{name, Name}, MacroDefId, }; use ra_db::CrateId; @@ -163,13 +163,13 @@ impl Resolver { } } Scope::ImplBlockScope(impl_) => { - if first_name == &N![Self] { + if first_name == &name![Self] { let idx = if path.segments.len() == 1 { None } else { Some(1) }; return Some((TypeNs::SelfType(*impl_), idx)); } } Scope::AdtScope(adt) => { - if first_name == &N![Self] { + if first_name == &name![Self] { let idx = if path.segments.len() == 1 { None } else { Some(1) }; return Some((TypeNs::AdtSelfType(*adt), idx)); } @@ -223,7 +223,7 @@ impl Resolver { return None; } let n_segments = path.segments.len(); - let tmp = N![self]; + let tmp = name![self]; let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); for scope in self.scopes.iter().rev() { @@ -259,13 +259,13 @@ impl Resolver { Scope::GenericParams { .. } => continue, Scope::ImplBlockScope(impl_) if n_segments > 1 => { - if first_name == &N![Self] { + if first_name == &name![Self] { let ty = TypeNs::SelfType(*impl_); return Some(ResolveValueResult::Partial(ty, 1)); } } Scope::AdtScope(adt) if n_segments > 1 => { - if first_name == &N![Self] { + if first_name == &name![Self] { let ty = TypeNs::AdtSelfType(*adt); return Some(ResolveValueResult::Partial(ty, 1)); } @@ -439,10 +439,10 @@ impl Scope { } } Scope::ImplBlockScope(i) => { - f(N![Self], ScopeDef::ImplSelfType((*i).into())); + f(name![Self], ScopeDef::ImplSelfType((*i).into())); } Scope::AdtScope(i) => { - f(N![Self], ScopeDef::AdtSelfType((*i).into())); + f(name![Self], ScopeDef::AdtSelfType((*i).into())); } Scope::ExprScope(scope) => { scope.expr_scopes.entries(scope.scope_id).iter().for_each(|e| { -- cgit v1.2.3 From f02fcc16444fcd18ccd51b43fa01bf0233e044fa Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 13 Dec 2019 22:32:44 +0100 Subject: Use path macro --- crates/ra_hir_def/src/path.rs | 95 +++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 63 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index c1376af36..1e9eb14ea 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -76,10 +76,7 @@ impl Path { } } - pub(crate) fn from_simple_segments( - kind: PathKind, - segments: impl IntoIterator, - ) -> Path { + pub fn from_simple_segments(kind: PathKind, segments: impl IntoIterator) -> Path { Path { kind, segments: segments @@ -296,64 +293,36 @@ impl From for Path { } } -pub mod known { - use hir_expand::name::name; - - use super::{Path, PathKind}; - - macro_rules! P { - ($start:ident $(:: $seg:ident)*) => { Path::from_simple_segments(PathKind::Abs, vec![name![$start], $(name![$seg],)*]) }; - } - - pub fn std_iter_into_iterator() -> Path { - P![std::iter::IntoIterator] - } - - pub fn std_ops_try() -> Path { - P![std::ops::Try] - } - - pub fn std_ops_range() -> Path { - P![std::ops::Range] - } - - pub fn std_ops_range_from() -> Path { - P![std::ops::RangeFrom] - } - - pub fn std_ops_range_full() -> Path { - P![std::ops::RangeFull] - } - - pub fn std_ops_range_inclusive() -> Path { - P![std::ops::RangeInclusive] - } - - pub fn std_ops_range_to() -> Path { - P![std::ops::RangeTo] - } - - pub fn std_ops_range_to_inclusive() -> Path { - P![std::ops::RangeToInclusive] - } - - pub fn std_ops_neg() -> Path { - P![std::ops::Neg] - } - - pub fn std_ops_not() -> Path { - P![std::ops::Not] - } - - pub fn std_result_result() -> Path { - P![std::result::Result] - } - - pub fn std_future_future() -> Path { - P![std::future::Future] - } +pub use hir_expand::name as __name; + +#[macro_export] +macro_rules! __known_path { + (std::iter::IntoIterator) => {}; + (std::result::Result) => {}; + (std::ops::Range) => {}; + (std::ops::RangeFrom) => {}; + (std::ops::RangeFull) => {}; + (std::ops::RangeTo) => {}; + (std::ops::RangeToInclusive) => {}; + (std::ops::RangeInclusive) => {}; + (std::boxed::Box) => {}; + (std::future::Future) => {}; + (std::ops::Try) => {}; + (std::ops::Neg) => {}; + (std::ops::Not) => {}; + ($path:path) => { + compile_error!("Please register your known path in the path module") + }; +} - pub fn std_boxed_box() -> Path { - P![std::boxed::Box] - } +#[macro_export] +macro_rules! __path { + ($start:ident $(:: $seg:ident)*) => ({ + $crate::__known_path!($start $(:: $seg)*); + $crate::path::Path::from_simple_segments($crate::path::PathKind::Abs, vec![ + $crate::path::__name![$start], $($crate::path::__name![$seg],)* + ]) + }); } + +pub use crate::__path as path; -- cgit v1.2.3 From 2619950b3b405324ab1c1745876165c834b3b4b9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 13 Dec 2019 12:12:36 +0100 Subject: Use different types for path with and without generics --- crates/ra_hir_def/src/attr.rs | 6 +- crates/ra_hir_def/src/body.rs | 2 +- crates/ra_hir_def/src/nameres.rs | 4 +- crates/ra_hir_def/src/nameres/collector.rs | 14 +- crates/ra_hir_def/src/nameres/path_resolution.rs | 24 +- crates/ra_hir_def/src/nameres/raw.rs | 12 +- crates/ra_hir_def/src/path.rs | 345 ++++++++++------------- crates/ra_hir_def/src/path/lower.rs | 176 ++++++++++++ crates/ra_hir_def/src/path/lower/lower_use.rs | 112 ++++++++ crates/ra_hir_def/src/path/lower_use.rs | 115 -------- crates/ra_hir_def/src/resolver.rs | 46 ++- 11 files changed, 487 insertions(+), 369 deletions(-) create mode 100644 crates/ra_hir_def/src/path/lower.rs create mode 100644 crates/ra_hir_def/src/path/lower/lower_use.rs delete mode 100644 crates/ra_hir_def/src/path/lower_use.rs (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 5bf82e191..9efa4970c 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -12,7 +12,7 @@ use ra_syntax::{ use tt::Subtree; use crate::{ - db::DefDatabase, path::Path, src::HasChildSource, src::HasSource, AdtId, AttrDefId, Lookup, + db::DefDatabase, path::ModPath, src::HasChildSource, src::HasSource, AdtId, AttrDefId, Lookup, }; #[derive(Default, Debug, Clone, PartialEq, Eq)] @@ -94,7 +94,7 @@ impl Attrs { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Attr { - pub(crate) path: Path, + pub(crate) path: ModPath, pub(crate) input: Option, } @@ -106,7 +106,7 @@ pub enum AttrInput { impl Attr { fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option { - let path = Path::from_src(ast.path()?, hygiene)?; + let path = ModPath::from_src(ast.path()?, hygiene)?; let input = match ast.input() { None => None, Some(ast::AttrInput::Literal(lit)) => { diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index b3bc336cf..7787cb87f 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -83,7 +83,7 @@ impl Expander { fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option { self.crate_def_map - .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other) + .resolve_path(db, self.module.local_id, path.mod_path(), BuiltinShadowMode::Other) .0 .take_macros() } diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index bd237a7b3..9aae7e48e 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -74,7 +74,7 @@ use crate::{ builtin_type::BuiltinType, db::DefDatabase, nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, - path::Path, + path::ModPath, per_ns::PerNs, AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, }; @@ -329,7 +329,7 @@ impl CrateDefMap { &self, db: &impl DefDatabase, original_module: LocalModuleId, - path: &Path, + path: &ModPath, shadow: BuiltinShadowMode, ) -> (PerNs, Option) { let res = diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 5d7469a6e..912a073ea 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -22,7 +22,7 @@ use crate::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode, }, - path::{Path, PathKind}, + path::{ModPath, PathKind}, per_ns::PerNs, AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, @@ -101,7 +101,7 @@ struct ImportDirective { struct MacroDirective { module_id: LocalModuleId, ast_id: AstId, - path: Path, + path: ModPath, legacy: Option, } @@ -113,7 +113,7 @@ struct DefCollector<'a, DB> { unresolved_imports: Vec, resolved_imports: Vec, unexpanded_macros: Vec, - unexpanded_attribute_macros: Vec<(LocalModuleId, AstId, Path)>, + unexpanded_attribute_macros: Vec<(LocalModuleId, AstId, ModPath)>, mod_dirs: FxHashMap, cfg_options: &'a CfgOptions, } @@ -428,7 +428,7 @@ where } else { match import.path.segments.last() { Some(last_segment) => { - let name = import.alias.clone().unwrap_or_else(|| last_segment.name.clone()); + let name = import.alias.clone().unwrap_or_else(|| last_segment.clone()); log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def); // extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658 @@ -565,7 +565,7 @@ where res } - fn resolve_attribute_macro(&self, path: &Path) -> Option { + fn resolve_attribute_macro(&self, path: &ModPath) -> Option { // FIXME this is currently super hacky, just enough to support the // built-in derives if let Some(name) = path.as_ident() { @@ -829,7 +829,7 @@ where tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok _ => continue, // anything else would be an error (which we currently ignore) }; - let path = Path::from_tt_ident(ident); + let path = ModPath::from_tt_ident(ident); let ast_id = AstId::new(self.file_id, def.kind.ast_id()); self.def_collector.unexpanded_attribute_macros.push((self.module_id, ast_id, path)); @@ -917,7 +917,7 @@ where } } -fn is_macro_rules(path: &Path) -> bool { +fn is_macro_rules(path: &ModPath) -> bool { path.as_ident() == Some(&name![macro_rules]) } diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index aab4b1dd9..4a249e7e7 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -17,7 +17,7 @@ use test_utils::tested_by; use crate::{ db::DefDatabase, nameres::{BuiltinShadowMode, CrateDefMap}, - path::{Path, PathKind}, + path::{ModPath, PathKind}, per_ns::PerNs, AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, }; @@ -69,7 +69,7 @@ impl CrateDefMap { db: &impl DefDatabase, mode: ResolveMode, original_module: LocalModuleId, - path: &Path, + path: &ModPath, shadow: BuiltinShadowMode, ) -> ResolvePathResult { // if it is not the last segment, we prefer the module to the builtin @@ -113,7 +113,7 @@ impl CrateDefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; log::debug!("resolving {:?} in crate root (+ extern prelude)", segment); - self.resolve_name_in_crate_root_or_extern_prelude(&segment.name, prefer_module(idx)) + self.resolve_name_in_crate_root_or_extern_prelude(&segment, prefer_module(idx)) } PathKind::Plain => { let (idx, segment) = match segments.next() { @@ -121,7 +121,7 @@ impl CrateDefMap { None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; log::debug!("resolving {:?} in module", segment); - self.resolve_name_in_module(db, original_module, &segment.name, prefer_module(idx)) + self.resolve_name_in_module(db, original_module, &segment, prefer_module(idx)) } PathKind::Super => { if let Some(p) = self.modules[original_module].parent { @@ -137,7 +137,7 @@ impl CrateDefMap { Some((_, segment)) => segment, None => return ResolvePathResult::empty(ReachedFixedPoint::Yes), }; - if let Some(def) = self.extern_prelude.get(&segment.name) { + if let Some(def) = self.extern_prelude.get(&segment) { log::debug!("absolute path {:?} resolved to crate {:?}", path, def); PerNs::types(*def) } else { @@ -168,8 +168,10 @@ impl CrateDefMap { curr_per_ns = match curr { ModuleDefId::ModuleId(module) => { if module.krate != self.krate { - let path = - Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; + let path = ModPath { + segments: path.segments[i..].to_vec(), + kind: PathKind::Self_, + }; log::debug!("resolving {:?} in other crate", path); let defp_map = db.crate_def_map(module.krate); let (def, s) = defp_map.resolve_path(db, module.local_id, &path, shadow); @@ -182,10 +184,10 @@ impl CrateDefMap { } // Since it is a qualified path here, it should not contains legacy macros - match self[module.local_id].scope.get(&segment.name, prefer_module(i)) { + match self[module.local_id].scope.get(&segment, prefer_module(i)) { Some(res) => res.def, _ => { - log::debug!("path segment {:?} not found", segment.name); + log::debug!("path segment {:?} not found", segment); return ResolvePathResult::empty(ReachedFixedPoint::No); } } @@ -194,7 +196,7 @@ impl CrateDefMap { // enum variant tested_by!(can_import_enum_variant); let enum_data = db.enum_data(e); - match enum_data.variant(&segment.name) { + match enum_data.variant(&segment) { Some(local_id) => { let variant = EnumVariantId { parent: e, local_id }; PerNs::both(variant.into(), variant.into()) @@ -214,7 +216,7 @@ impl CrateDefMap { // (`Struct::method`), or some other kind of associated item log::debug!( "path segment {:?} resolved to non-module {:?}, but is not last", - segment.name, + segment, curr, ); diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index a2821e1c3..ecb4d7c03 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -22,7 +22,7 @@ use ra_syntax::{ use test_utils::tested_by; use crate::{ - attr::Attrs, db::DefDatabase, path::Path, trace::Trace, FileAstId, HirFileId, InFile, + attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile, LocalImportId, }; @@ -154,7 +154,7 @@ pub(super) enum ModuleData { #[derive(Debug, Clone, PartialEq, Eq)] pub struct ImportData { - pub(super) path: Path, + pub(super) path: ModPath, pub(super) alias: Option, pub(super) is_glob: bool, pub(super) is_prelude: bool, @@ -206,7 +206,7 @@ impl_arena_id!(Macro); #[derive(Debug, PartialEq, Eq)] pub(super) struct MacroData { pub(super) ast_id: FileAstId, - pub(super) path: Path, + pub(super) path: ModPath, pub(super) name: Option, pub(super) export: bool, pub(super) builtin: bool, @@ -327,7 +327,7 @@ impl RawItemsCollector { let attrs = self.parse_attrs(&use_item); let mut buf = Vec::new(); - Path::expand_use_item( + ModPath::expand_use_item( InFile { value: use_item, file_id: self.file_id }, &self.hygiene, |path, use_tree, is_glob, alias| { @@ -353,7 +353,7 @@ impl RawItemsCollector { extern_crate: ast::ExternCrateItem, ) { if let Some(name_ref) = extern_crate.name_ref() { - let path = Path::from_name_ref(&name_ref); + let path = ModPath::from_name_ref(&name_ref); let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); let attrs = self.parse_attrs(&extern_crate); // FIXME: cfg_attr @@ -377,7 +377,7 @@ impl RawItemsCollector { fn add_macro(&mut self, current_module: Option, m: ast::MacroCall) { let attrs = self.parse_attrs(&m); - let path = match m.path().and_then(|path| Path::from_src(path, &self.hygiene)) { + let path = match m.path().and_then(|path| ModPath::from_src(path, &self.hygiene)) { Some(it) => it, _ => return, }; diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 1e9eb14ea..20d6d98ea 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -1,31 +1,78 @@ //! A desugared representation of paths like `crate::foo` or `::bar`. -mod lower_use; +mod lower; use std::{iter, sync::Arc}; -use either::Either; use hir_expand::{ hygiene::Hygiene, - name::{name, AsName, Name}, + name::{AsName, Name}, }; use ra_db::CrateId; -use ra_syntax::{ - ast::{self, TypeAscriptionOwner}, - AstNode, -}; +use ra_syntax::ast; use crate::{type_ref::TypeRef, InFile}; #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Path { +pub struct ModPath { pub kind: PathKind, - pub segments: Vec, + pub segments: Vec, +} + +impl ModPath { + pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option { + lower::lower_path(path, hygiene).map(|it| it.mod_path) + } + + pub fn from_simple_segments( + kind: PathKind, + segments: impl IntoIterator, + ) -> ModPath { + let segments = segments.into_iter().collect::>(); + ModPath { kind, segments } + } + + pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> ModPath { + name_ref.as_name().into() + } + + /// Converts an `tt::Ident` into a single-identifier `Path`. + pub(crate) fn from_tt_ident(ident: &tt::Ident) -> ModPath { + ident.as_name().into() + } + + /// Calls `cb` with all paths, represented by this use item. + pub(crate) fn expand_use_item( + item_src: InFile, + hygiene: &Hygiene, + mut cb: impl FnMut(ModPath, &ast::UseTree, /* is_glob */ bool, Option), + ) { + if let Some(tree) = item_src.value.use_tree() { + lower::lower_use_tree(None, tree, hygiene, &mut cb); + } + } + + pub fn is_ident(&self) -> bool { + self.kind == PathKind::Plain && self.segments.len() == 1 + } + + pub fn is_self(&self) -> bool { + self.kind == PathKind::Self_ && self.segments.is_empty() + } + + /// If this path is a single identifier, like `foo`, return its name. + pub fn as_ident(&self) -> Option<&Name> { + if self.kind != PathKind::Plain || self.segments.len() > 1 { + return None; + } + self.segments.first() + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct PathSegment { - pub name: Name, - pub args_and_bindings: Option>, +pub struct Path { + mod_path: ModPath, + /// Invariant: the same len as self.path.segments + generic_args: Vec>>, } /// Generic arguments to a path segment (e.g. the `i32` in `Option`). This @@ -65,221 +112,110 @@ pub enum PathKind { } impl Path { - /// Calls `cb` with all paths, represented by this use item. - pub(crate) fn expand_use_item( - item_src: InFile, - hygiene: &Hygiene, - mut cb: impl FnMut(Path, &ast::UseTree, bool, Option), - ) { - if let Some(tree) = item_src.value.use_tree() { - lower_use::lower_use_tree(None, tree, hygiene, &mut cb); - } - } - - pub fn from_simple_segments(kind: PathKind, segments: impl IntoIterator) -> Path { - Path { - kind, - segments: segments - .into_iter() - .map(|name| PathSegment { name, args_and_bindings: None }) - .collect(), - } - } - /// Converts an `ast::Path` to `Path`. Works with use trees. /// DEPRECATED: It does not handle `$crate` from macro call. pub fn from_ast(path: ast::Path) -> Option { - Path::from_src(path, &Hygiene::new_unhygienic()) + lower::lower_path(path, &Hygiene::new_unhygienic()) } /// Converts an `ast::Path` to `Path`. Works with use trees. /// It correctly handles `$crate` based path from macro call. - pub fn from_src(mut path: ast::Path, hygiene: &Hygiene) -> Option { - let mut kind = PathKind::Plain; - let mut segments = Vec::new(); - loop { - let segment = path.segment()?; - - if segment.has_colon_colon() { - kind = PathKind::Abs; - } - - match segment.kind()? { - ast::PathSegmentKind::Name(name_ref) => { - // FIXME: this should just return name - match hygiene.name_ref_to_name(name_ref) { - Either::Left(name) => { - let args = segment - .type_arg_list() - .and_then(GenericArgs::from_ast) - .or_else(|| { - GenericArgs::from_fn_like_path_ast( - segment.param_list(), - segment.ret_type(), - ) - }) - .map(Arc::new); - let segment = PathSegment { name, args_and_bindings: args }; - segments.push(segment); - } - Either::Right(crate_id) => { - kind = PathKind::DollarCrate(crate_id); - break; - } - } - } - ast::PathSegmentKind::Type { type_ref, trait_ref } => { - assert!(path.qualifier().is_none()); // this can only occur at the first segment - - let self_type = TypeRef::from_ast(type_ref?); - - match trait_ref { - // ::foo - None => { - kind = PathKind::Type(Box::new(self_type)); - } - // >::Foo desugars to Trait::Foo - Some(trait_ref) => { - let path = Path::from_src(trait_ref.path()?, hygiene)?; - kind = path.kind; - let mut prefix_segments = path.segments; - prefix_segments.reverse(); - segments.extend(prefix_segments); - // Insert the type reference (T in the above example) as Self parameter for the trait - let mut last_segment = segments.last_mut()?; - if last_segment.args_and_bindings.is_none() { - last_segment.args_and_bindings = - Some(Arc::new(GenericArgs::empty())); - }; - let args = last_segment.args_and_bindings.as_mut().unwrap(); - let mut args_inner = Arc::make_mut(args); - args_inner.has_self_type = true; - args_inner.args.insert(0, GenericArg::Type(self_type)); - } - } - } - ast::PathSegmentKind::CrateKw => { - kind = PathKind::Crate; - break; - } - ast::PathSegmentKind::SelfKw => { - kind = PathKind::Self_; - break; - } - ast::PathSegmentKind::SuperKw => { - kind = PathKind::Super; - break; - } - } - path = match qualifier(&path) { - Some(it) => it, - None => break, - }; - } - segments.reverse(); - return Some(Path { kind, segments }); - - fn qualifier(path: &ast::Path) -> Option { - if let Some(q) = path.qualifier() { - return Some(q); - } - // FIXME: this bottom up traversal is not too precise. - // Should we handle do a top-down analysis, recording results? - let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; - let use_tree = use_tree_list.parent_use_tree(); - use_tree.path() - } + pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option { + lower::lower_path(path, hygiene) } /// Converts an `ast::NameRef` into a single-identifier `Path`. pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path { - name_ref.as_name().into() + Path { mod_path: name_ref.as_name().into(), generic_args: vec![None] } } - /// Converts an `tt::Ident` into a single-identifier `Path`. - pub(crate) fn from_tt_ident(ident: &tt::Ident) -> Path { - ident.as_name().into() + /// `true` if this path is just a standalone `self` + pub fn is_self(&self) -> bool { + self.mod_path.is_self() } - /// `true` is this path is a single identifier, like `foo` - pub fn is_ident(&self) -> bool { - self.kind == PathKind::Plain && self.segments.len() == 1 + pub fn kind(&self) -> &PathKind { + &self.mod_path.kind } - /// `true` if this path is just a standalone `self` - pub fn is_self(&self) -> bool { - self.kind == PathKind::Self_ && self.segments.is_empty() + pub fn segments(&self) -> PathSegments<'_> { + PathSegments { + segments: self.mod_path.segments.as_slice(), + generic_args: self.generic_args.as_slice(), + } } - /// If this path is a single identifier, like `foo`, return its name. - pub fn as_ident(&self) -> Option<&Name> { - if self.kind != PathKind::Plain || self.segments.len() > 1 { + pub fn mod_path(&self) -> &ModPath { + &self.mod_path + } + + pub fn qualifier(&self) -> Option { + if self.mod_path.is_ident() { return None; } - self.segments.first().map(|s| &s.name) + let res = Path { + mod_path: ModPath { + kind: self.mod_path.kind.clone(), + segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(), + }, + generic_args: self.generic_args[..self.generic_args.len() - 1].to_vec(), + }; + Some(res) } +} - pub fn expand_macro_expr(&self) -> Option { - self.as_ident().and_then(|name| Some(name.clone())) - } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct PathSegment<'a> { + pub name: &'a Name, + pub args_and_bindings: Option<&'a GenericArgs>, +} - pub fn is_type_relative(&self) -> bool { - match self.kind { - PathKind::Type(_) => true, - _ => false, - } +pub struct PathSegments<'a> { + segments: &'a [Name], + generic_args: &'a [Option>], +} + +impl<'a> PathSegments<'a> { + pub const EMPTY: PathSegments<'static> = PathSegments { segments: &[], generic_args: &[] }; + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + pub fn len(&self) -> usize { + self.segments.len() + } + pub fn first(&self) -> Option> { + self.get(0) + } + pub fn last(&self) -> Option> { + self.get(self.len().checked_sub(1)?) + } + pub fn get(&self, idx: usize) -> Option> { + assert_eq!(self.segments.len(), self.generic_args.len()); + let res = PathSegment { + name: self.segments.get(idx)?, + args_and_bindings: self.generic_args.get(idx).unwrap().as_ref().map(|it| &**it), + }; + Some(res) + } + pub fn skip(&self, len: usize) -> PathSegments<'a> { + assert_eq!(self.segments.len(), self.generic_args.len()); + PathSegments { segments: &self.segments[len..], generic_args: &self.generic_args[len..] } + } + pub fn take(&self, len: usize) -> PathSegments<'a> { + assert_eq!(self.segments.len(), self.generic_args.len()); + PathSegments { segments: &self.segments[..len], generic_args: &self.generic_args[..len] } + } + pub fn iter(&self) -> impl Iterator> { + self.segments.iter().zip(self.generic_args.iter()).map(|(name, args)| PathSegment { + name, + args_and_bindings: args.as_ref().map(|it| &**it), + }) } } impl GenericArgs { pub(crate) fn from_ast(node: ast::TypeArgList) -> Option { - let mut args = Vec::new(); - for type_arg in node.type_args() { - let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); - args.push(GenericArg::Type(type_ref)); - } - // lifetimes ignored for now - let mut bindings = Vec::new(); - for assoc_type_arg in node.assoc_type_args() { - if let Some(name_ref) = assoc_type_arg.name_ref() { - let name = name_ref.as_name(); - let type_ref = TypeRef::from_ast_opt(assoc_type_arg.type_ref()); - bindings.push((name, type_ref)); - } - } - if args.is_empty() && bindings.is_empty() { - None - } else { - Some(GenericArgs { args, has_self_type: false, bindings }) - } - } - - /// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) - /// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). - pub(crate) fn from_fn_like_path_ast( - params: Option, - ret_type: Option, - ) -> Option { - let mut args = Vec::new(); - let mut bindings = Vec::new(); - if let Some(params) = params { - let mut param_types = Vec::new(); - for param in params.params() { - let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); - param_types.push(type_ref); - } - let arg = GenericArg::Type(TypeRef::Tuple(param_types)); - args.push(arg); - } - if let Some(ret_type) = ret_type { - let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); - bindings.push((name![Output], type_ref)) - } - if args.is_empty() && bindings.is_empty() { - None - } else { - Some(GenericArgs { args, has_self_type: false, bindings }) - } + lower::lower_generic_args(node) } pub(crate) fn empty() -> GenericArgs { @@ -289,7 +225,16 @@ impl GenericArgs { impl From for Path { fn from(name: Name) -> Path { - Path::from_simple_segments(PathKind::Plain, iter::once(name)) + Path { + mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)), + generic_args: vec![None], + } + } +} + +impl From for ModPath { + fn from(name: Name) -> ModPath { + ModPath::from_simple_segments(PathKind::Plain, iter::once(name)) } } @@ -319,7 +264,7 @@ macro_rules! __known_path { macro_rules! __path { ($start:ident $(:: $seg:ident)*) => ({ $crate::__known_path!($start $(:: $seg)*); - $crate::path::Path::from_simple_segments($crate::path::PathKind::Abs, vec![ + $crate::path::ModPath::from_simple_segments($crate::path::PathKind::Abs, vec![ $crate::path::__name![$start], $($crate::path::__name![$seg],)* ]) }); diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs new file mode 100644 index 000000000..a2e995198 --- /dev/null +++ b/crates/ra_hir_def/src/path/lower.rs @@ -0,0 +1,176 @@ +//! Transforms syntax into `Path` objects, ideally with accounting for hygiene + +mod lower_use; + +use std::sync::Arc; + +use either::Either; +use hir_expand::{ + hygiene::Hygiene, + name::{name, AsName}, +}; +use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner}; + +use crate::{ + path::{GenericArg, GenericArgs, ModPath, Path, PathKind}, + type_ref::TypeRef, +}; + +pub(super) use lower_use::lower_use_tree; + +/// Converts an `ast::Path` to `Path`. Works with use trees. +/// It correctly handles `$crate` based path from macro call. +pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option { + let mut kind = PathKind::Plain; + let mut segments = Vec::new(); + let mut generic_args = Vec::new(); + loop { + let segment = path.segment()?; + + if segment.has_colon_colon() { + kind = PathKind::Abs; + } + + match segment.kind()? { + ast::PathSegmentKind::Name(name_ref) => { + // FIXME: this should just return name + match hygiene.name_ref_to_name(name_ref) { + Either::Left(name) => { + let args = segment + .type_arg_list() + .and_then(lower_generic_args) + .or_else(|| { + lower_generic_args_from_fn_path( + segment.param_list(), + segment.ret_type(), + ) + }) + .map(Arc::new); + segments.push(name); + generic_args.push(args) + } + Either::Right(crate_id) => { + kind = PathKind::DollarCrate(crate_id); + break; + } + } + } + ast::PathSegmentKind::Type { type_ref, trait_ref } => { + assert!(path.qualifier().is_none()); // this can only occur at the first segment + + let self_type = TypeRef::from_ast(type_ref?); + + match trait_ref { + // ::foo + None => { + kind = PathKind::Type(Box::new(self_type)); + } + // >::Foo desugars to Trait::Foo + Some(trait_ref) => { + let path = Path::from_src(trait_ref.path()?, hygiene)?; + kind = path.mod_path.kind; + + let mut prefix_segments = path.mod_path.segments; + prefix_segments.reverse(); + segments.extend(prefix_segments); + + let mut prefix_args = path.generic_args; + prefix_args.reverse(); + generic_args.extend(prefix_args); + + // Insert the type reference (T in the above example) as Self parameter for the trait + let last_segment = generic_args.last_mut()?; + if last_segment.is_none() { + *last_segment = Some(Arc::new(GenericArgs::empty())); + }; + let args = last_segment.as_mut().unwrap(); + let mut args_inner = Arc::make_mut(args); + args_inner.has_self_type = true; + args_inner.args.insert(0, GenericArg::Type(self_type)); + } + } + } + ast::PathSegmentKind::CrateKw => { + kind = PathKind::Crate; + break; + } + ast::PathSegmentKind::SelfKw => { + kind = PathKind::Self_; + break; + } + ast::PathSegmentKind::SuperKw => { + kind = PathKind::Super; + break; + } + } + path = match qualifier(&path) { + Some(it) => it, + None => break, + }; + } + segments.reverse(); + generic_args.reverse(); + let mod_path = ModPath { kind, segments }; + return Some(Path { mod_path, generic_args }); + + fn qualifier(path: &ast::Path) -> Option { + if let Some(q) = path.qualifier() { + return Some(q); + } + // FIXME: this bottom up traversal is not too precise. + // Should we handle do a top-down analysis, recording results? + let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?; + let use_tree = use_tree_list.parent_use_tree(); + use_tree.path() + } +} + +pub(super) fn lower_generic_args(node: ast::TypeArgList) -> Option { + let mut args = Vec::new(); + for type_arg in node.type_args() { + let type_ref = TypeRef::from_ast_opt(type_arg.type_ref()); + args.push(GenericArg::Type(type_ref)); + } + // lifetimes ignored for now + let mut bindings = Vec::new(); + for assoc_type_arg in node.assoc_type_args() { + if let Some(name_ref) = assoc_type_arg.name_ref() { + let name = name_ref.as_name(); + let type_ref = TypeRef::from_ast_opt(assoc_type_arg.type_ref()); + bindings.push((name, type_ref)); + } + } + if args.is_empty() && bindings.is_empty() { + None + } else { + Some(GenericArgs { args, has_self_type: false, bindings }) + } +} + +/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y) +/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`). +fn lower_generic_args_from_fn_path( + params: Option, + ret_type: Option, +) -> Option { + let mut args = Vec::new(); + let mut bindings = Vec::new(); + if let Some(params) = params { + let mut param_types = Vec::new(); + for param in params.params() { + let type_ref = TypeRef::from_ast_opt(param.ascribed_type()); + param_types.push(type_ref); + } + let arg = GenericArg::Type(TypeRef::Tuple(param_types)); + args.push(arg); + } + if let Some(ret_type) = ret_type { + let type_ref = TypeRef::from_ast_opt(ret_type.type_ref()); + bindings.push((name![Output], type_ref)) + } + if args.is_empty() && bindings.is_empty() { + None + } else { + Some(GenericArgs { args, has_self_type: false, bindings }) + } +} diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs new file mode 100644 index 000000000..ea3fdb56c --- /dev/null +++ b/crates/ra_hir_def/src/path/lower/lower_use.rs @@ -0,0 +1,112 @@ +//! Lowers a single complex use like `use foo::{bar, baz};` into a list of paths like +//! `foo::bar`, `foo::baz`; + +use std::iter; + +use either::Either; +use hir_expand::{ + hygiene::Hygiene, + name::{AsName, Name}, +}; +use ra_syntax::ast::{self, NameOwner}; + +use crate::path::{ModPath, PathKind}; + +pub(crate) fn lower_use_tree( + prefix: Option, + tree: ast::UseTree, + hygiene: &Hygiene, + cb: &mut dyn FnMut(ModPath, &ast::UseTree, bool, Option), +) { + if let Some(use_tree_list) = tree.use_tree_list() { + let prefix = match tree.path() { + // E.g. use something::{{{inner}}}; + None => prefix, + // E.g. `use something::{inner}` (prefix is `None`, path is `something`) + // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) + Some(path) => match convert_path(prefix, path, hygiene) { + Some(it) => Some(it), + None => return, // FIXME: report errors somewhere + }, + }; + for child_tree in use_tree_list.use_trees() { + lower_use_tree(prefix.clone(), child_tree, hygiene, cb); + } + } else { + let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); + if let Some(ast_path) = tree.path() { + // Handle self in a path. + // E.g. `use something::{self, <...>}` + if ast_path.qualifier().is_none() { + if let Some(segment) = ast_path.segment() { + if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { + if let Some(prefix) = prefix { + cb(prefix, &tree, false, alias); + return; + } + } + } + } + if let Some(path) = convert_path(prefix, ast_path, hygiene) { + let is_glob = tree.has_star(); + cb(path, &tree, is_glob, alias) + } + // FIXME: report errors somewhere + // We get here if we do + } + } +} + +fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> Option { + let prefix = if let Some(qual) = path.qualifier() { + Some(convert_path(prefix, qual, hygiene)?) + } else { + prefix + }; + + let segment = path.segment()?; + let res = match segment.kind()? { + ast::PathSegmentKind::Name(name_ref) => { + match hygiene.name_ref_to_name(name_ref) { + Either::Left(name) => { + // no type args in use + let mut res = prefix.unwrap_or_else(|| ModPath { + kind: PathKind::Plain, + segments: Vec::with_capacity(1), + }); + res.segments.push(name); + res + } + Either::Right(crate_id) => { + return Some(ModPath::from_simple_segments( + PathKind::DollarCrate(crate_id), + iter::empty(), + )) + } + } + } + ast::PathSegmentKind::CrateKw => { + if prefix.is_some() { + return None; + } + ModPath::from_simple_segments(PathKind::Crate, iter::empty()) + } + ast::PathSegmentKind::SelfKw => { + if prefix.is_some() { + return None; + } + ModPath::from_simple_segments(PathKind::Self_, iter::empty()) + } + ast::PathSegmentKind::SuperKw => { + if prefix.is_some() { + return None; + } + ModPath::from_simple_segments(PathKind::Super, iter::empty()) + } + ast::PathSegmentKind::Type { .. } => { + // not allowed in imports + return None; + } + }; + Some(res) +} diff --git a/crates/ra_hir_def/src/path/lower_use.rs b/crates/ra_hir_def/src/path/lower_use.rs deleted file mode 100644 index e2e1f716d..000000000 --- a/crates/ra_hir_def/src/path/lower_use.rs +++ /dev/null @@ -1,115 +0,0 @@ -//! Lowers a single complex use like `use foo::{bar, baz};` into a list of paths like -//! `foo::bar`, `foo::baz`; - -use std::iter; - -use either::Either; -use hir_expand::{ - hygiene::Hygiene, - name::{AsName, Name}, -}; -use ra_syntax::ast::{self, NameOwner}; - -use crate::path::{Path, PathKind, PathSegment}; - -pub(crate) fn lower_use_tree( - prefix: Option, - tree: ast::UseTree, - hygiene: &Hygiene, - cb: &mut dyn FnMut(Path, &ast::UseTree, bool, Option), -) { - if let Some(use_tree_list) = tree.use_tree_list() { - let prefix = match tree.path() { - // E.g. use something::{{{inner}}}; - None => prefix, - // E.g. `use something::{inner}` (prefix is `None`, path is `something`) - // or `use something::{path::{inner::{innerer}}}` (prefix is `something::path`, path is `inner`) - Some(path) => match convert_path(prefix, path, hygiene) { - Some(it) => Some(it), - None => return, // FIXME: report errors somewhere - }, - }; - for child_tree in use_tree_list.use_trees() { - lower_use_tree(prefix.clone(), child_tree, hygiene, cb); - } - } else { - let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); - if let Some(ast_path) = tree.path() { - // Handle self in a path. - // E.g. `use something::{self, <...>}` - if ast_path.qualifier().is_none() { - if let Some(segment) = ast_path.segment() { - if segment.kind() == Some(ast::PathSegmentKind::SelfKw) { - if let Some(prefix) = prefix { - cb(prefix, &tree, false, alias); - return; - } - } - } - } - if let Some(path) = convert_path(prefix, ast_path, hygiene) { - let is_glob = tree.has_star(); - cb(path, &tree, is_glob, alias) - } - // FIXME: report errors somewhere - // We get here if we do - } - } -} - -fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> Option { - let prefix = if let Some(qual) = path.qualifier() { - Some(convert_path(prefix, qual, hygiene)?) - } else { - prefix - }; - - let segment = path.segment()?; - let res = match segment.kind()? { - ast::PathSegmentKind::Name(name_ref) => { - match hygiene.name_ref_to_name(name_ref) { - Either::Left(name) => { - // no type args in use - let mut res = prefix.unwrap_or_else(|| Path { - kind: PathKind::Plain, - segments: Vec::with_capacity(1), - }); - res.segments.push(PathSegment { - name, - args_and_bindings: None, // no type args in use - }); - res - } - Either::Right(crate_id) => { - return Some(Path::from_simple_segments( - PathKind::DollarCrate(crate_id), - iter::empty(), - )) - } - } - } - ast::PathSegmentKind::CrateKw => { - if prefix.is_some() { - return None; - } - Path::from_simple_segments(PathKind::Crate, iter::empty()) - } - ast::PathSegmentKind::SelfKw => { - if prefix.is_some() { - return None; - } - Path::from_simple_segments(PathKind::Self_, iter::empty()) - } - ast::PathSegmentKind::SuperKw => { - if prefix.is_some() { - return None; - } - Path::from_simple_segments(PathKind::Super, iter::empty()) - } - ast::PathSegmentKind::Type { .. } => { - // not allowed in imports - return None; - } - }; - Some(res) -} diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index b6d595a20..2694c0438 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -15,7 +15,7 @@ use crate::{ expr::{ExprId, PatId}, generics::GenericParams, nameres::{BuiltinShadowMode, CrateDefMap}, - path::{Path, PathKind}, + path::{ModPath, PathKind}, per_ns::PerNs, AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, @@ -91,7 +91,7 @@ pub enum ValueNs { impl Resolver { /// Resolve known trait from std, like `std::futures::Future` - pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &Path) -> Option { + pub fn resolve_known_trait(&self, db: &impl DefDatabase, path: &ModPath) -> Option { let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; match res { ModuleDefId::TraitId(it) => Some(it), @@ -100,7 +100,7 @@ impl Resolver { } /// Resolve known struct from std, like `std::boxed::Box` - pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &Path) -> Option { + pub fn resolve_known_struct(&self, db: &impl DefDatabase, path: &ModPath) -> Option { let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; match res { ModuleDefId::AdtId(AdtId::StructId(it)) => Some(it), @@ -109,7 +109,7 @@ impl Resolver { } /// Resolve known enum from std, like `std::result::Result` - pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &Path) -> Option { + pub fn resolve_known_enum(&self, db: &impl DefDatabase, path: &ModPath) -> Option { let res = self.resolve_module_path(db, path, BuiltinShadowMode::Other).take_types()?; match res { ModuleDefId::AdtId(AdtId::EnumId(it)) => Some(it), @@ -120,33 +120,30 @@ impl Resolver { fn resolve_module_path( &self, db: &impl DefDatabase, - path: &Path, + path: &ModPath, shadow: BuiltinShadowMode, ) -> PerNs { let (item_map, module) = match self.module() { Some(it) => it, None => return PerNs::none(), }; - let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow); + let (module_res, segment_index) = item_map.resolve_path(db, module, &path, shadow); if segment_index.is_some() { return PerNs::none(); } module_res } - pub fn resolve_module_path_in_items(&self, db: &impl DefDatabase, path: &Path) -> PerNs { + pub fn resolve_module_path_in_items(&self, db: &impl DefDatabase, path: &ModPath) -> PerNs { self.resolve_module_path(db, path, BuiltinShadowMode::Module) } pub fn resolve_path_in_type_ns( &self, db: &impl DefDatabase, - path: &Path, + path: &ModPath, ) -> Option<(TypeNs, Option)> { - if path.is_type_relative() { - return None; - } - let first_name = &path.segments.first()?.name; + let first_name = path.segments.first()?; let skip_to_mod = path.kind != PathKind::Plain; for scope in self.scopes.iter().rev() { match scope { @@ -178,7 +175,7 @@ impl Resolver { let (module_def, idx) = m.crate_def_map.resolve_path( db, m.module_id, - path, + &path, BuiltinShadowMode::Other, ); let res = match module_def.take_types()? { @@ -205,7 +202,7 @@ impl Resolver { pub fn resolve_path_in_type_ns_fully( &self, db: &impl DefDatabase, - path: &Path, + path: &ModPath, ) -> Option { let (res, unresolved) = self.resolve_path_in_type_ns(db, path)?; if unresolved.is_some() { @@ -214,17 +211,14 @@ impl Resolver { Some(res) } - pub fn resolve_path_in_value_ns<'p>( + pub fn resolve_path_in_value_ns( &self, db: &impl DefDatabase, - path: &'p Path, + path: &ModPath, ) -> Option { - if path.is_type_relative() { - return None; - } let n_segments = path.segments.len(); let tmp = name![self]; - let first_name = if path.is_self() { &tmp } else { &path.segments.first()?.name }; + let first_name = if path.is_self() { &tmp } else { &path.segments.first()? }; let skip_to_mod = path.kind != PathKind::Plain && !path.is_self(); for scope in self.scopes.iter().rev() { match scope { @@ -276,7 +270,7 @@ impl Resolver { let (module_def, idx) = m.crate_def_map.resolve_path( db, m.module_id, - path, + &path, BuiltinShadowMode::Other, ); return match idx { @@ -322,7 +316,7 @@ impl Resolver { pub fn resolve_path_in_value_ns_fully( &self, db: &impl DefDatabase, - path: &Path, + path: &ModPath, ) -> Option { match self.resolve_path_in_value_ns(db, path)? { ResolveValueResult::ValueNs(it) => Some(it), @@ -330,9 +324,13 @@ impl Resolver { } } - pub fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option { + pub fn resolve_path_as_macro( + &self, + db: &impl DefDatabase, + path: &ModPath, + ) -> Option { let (item_map, module) = self.module()?; - item_map.resolve_path(db, module, path, BuiltinShadowMode::Other).0.take_macros() + item_map.resolve_path(db, module, &path, BuiltinShadowMode::Other).0.take_macros() } pub fn process_all_names(&self, db: &impl DefDatabase, f: &mut dyn FnMut(Name, ScopeDef)) { -- cgit v1.2.3 From aca022f1d49a6d945f3ef4f8c781d7337120b68d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Dec 2019 15:38:28 +0100 Subject: Refactor PathKind --- crates/ra_hir_def/src/nameres/collector.rs | 2 +- crates/ra_hir_def/src/nameres/path_resolution.rs | 26 +++++++++++++++++------- crates/ra_hir_def/src/path.rs | 5 ++--- crates/ra_hir_def/src/path/lower.rs | 4 ++-- crates/ra_hir_def/src/path/lower/lower_use.rs | 4 ++-- 5 files changed, 26 insertions(+), 15 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 912a073ea..8bbf7ffa2 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -890,7 +890,7 @@ where // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only. let mut path = mac.path.clone(); if path.is_ident() { - path.kind = PathKind::Self_; + path.kind = PathKind::Super(0); } self.def_collector.unexpanded_macros.push(MacroDirective { diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 4a249e7e7..a3bfc1542 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -10,6 +10,8 @@ //! //! `ReachedFixedPoint` signals about this. +use std::iter::successors; + use hir_expand::name::Name; use ra_db::Edition; use test_utils::tested_by; @@ -97,9 +99,6 @@ impl CrateDefMap { PathKind::Crate => { PerNs::types(ModuleId { krate: self.krate, local_id: self.root }.into()) } - PathKind::Self_ => { - PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into()) - } // plain import or absolute path in 2015: crate-relative with // fallback to extern prelude (with the simplification in // rust-lang/rust#57745) @@ -123,9 +122,22 @@ impl CrateDefMap { log::debug!("resolving {:?} in module", segment); self.resolve_name_in_module(db, original_module, &segment, prefer_module(idx)) } - PathKind::Super => { - if let Some(p) = self.modules[original_module].parent { - PerNs::types(ModuleId { krate: self.krate, local_id: p }.into()) + // PathKind::Self_ => { + // PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into()) + // } + // PathKind::Super => { + // if let Some(p) = self.modules[original_module].parent { + // PerNs::types(ModuleId { krate: self.krate, local_id: p }.into()) + // } else { + // log::debug!("super path in root module"); + // return ResolvePathResult::empty(ReachedFixedPoint::Yes); + // } + // } + PathKind::Super(lvl) => { + let m = successors(Some(original_module), |m| self.modules[*m].parent) + .nth(lvl as usize); + if let Some(local_id) = m { + PerNs::types(ModuleId { krate: self.krate, local_id }.into()) } else { log::debug!("super path in root module"); return ResolvePathResult::empty(ReachedFixedPoint::Yes); @@ -170,7 +182,7 @@ impl CrateDefMap { if module.krate != self.krate { let path = ModPath { segments: path.segments[i..].to_vec(), - kind: PathKind::Self_, + kind: PathKind::Super(0), }; log::debug!("resolving {:?} in other crate", path); let defp_map = db.crate_def_map(module.krate); diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 20d6d98ea..3b26e8337 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -56,7 +56,7 @@ impl ModPath { } pub fn is_self(&self) -> bool { - self.kind == PathKind::Self_ && self.segments.is_empty() + self.kind == PathKind::Super(0) && self.segments.is_empty() } /// If this path is a single identifier, like `foo`, return its name. @@ -100,8 +100,7 @@ pub enum GenericArg { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum PathKind { Plain, - Self_, - Super, + Super(u8), Crate, // Absolute path Abs, diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index a2e995198..c71b52d89 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -95,11 +95,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option break; } ast::PathSegmentKind::SelfKw => { - kind = PathKind::Self_; + kind = PathKind::Super(0); break; } ast::PathSegmentKind::SuperKw => { - kind = PathKind::Super; + kind = PathKind::Super(1); break; } } diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs index ea3fdb56c..062c02063 100644 --- a/crates/ra_hir_def/src/path/lower/lower_use.rs +++ b/crates/ra_hir_def/src/path/lower/lower_use.rs @@ -95,13 +95,13 @@ fn convert_path(prefix: Option, path: ast::Path, hygiene: &Hygiene) -> if prefix.is_some() { return None; } - ModPath::from_simple_segments(PathKind::Self_, iter::empty()) + ModPath::from_simple_segments(PathKind::Super(0), iter::empty()) } ast::PathSegmentKind::SuperKw => { if prefix.is_some() { return None; } - ModPath::from_simple_segments(PathKind::Super, iter::empty()) + ModPath::from_simple_segments(PathKind::Super(1), iter::empty()) } ast::PathSegmentKind::Type { .. } => { // not allowed in imports -- cgit v1.2.3 From 0630f8110f998f937608cb2962875a896a0298ae Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 17 Dec 2019 16:03:15 +0100 Subject: Drop dead code --- crates/ra_hir_def/src/nameres/path_resolution.rs | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index a3bfc1542..1dbc4f371 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -122,17 +122,6 @@ impl CrateDefMap { log::debug!("resolving {:?} in module", segment); self.resolve_name_in_module(db, original_module, &segment, prefer_module(idx)) } - // PathKind::Self_ => { - // PerNs::types(ModuleId { krate: self.krate, local_id: original_module }.into()) - // } - // PathKind::Super => { - // if let Some(p) = self.modules[original_module].parent { - // PerNs::types(ModuleId { krate: self.krate, local_id: p }.into()) - // } else { - // log::debug!("super path in root module"); - // return ResolvePathResult::empty(ReachedFixedPoint::Yes); - // } - // } PathKind::Super(lvl) => { let m = successors(Some(original_module), |m| self.modules[*m].parent) .nth(lvl as usize); -- cgit v1.2.3 From d043689735edc12388e22f49b2319362f3b003fa Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 18 Dec 2019 17:04:20 +0100 Subject: Touch up docs --- crates/ra_hir_def/src/path.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 3b26e8337..c37364f57 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -100,13 +100,14 @@ pub enum GenericArg { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum PathKind { Plain, + /// `self::` is `Super(0)` Super(u8), Crate, - // Absolute path + /// Absolute path (::foo) Abs, - // Type based path like `::foo` + /// Type based path like `::foo` Type(Box), - // `$crate` from macro expansion + /// `$crate` from macro expansion DollarCrate(CrateId), } -- cgit v1.2.3 From 88c6109897417e7ab815ea1711f49545bff94601 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 18 Dec 2019 17:06:52 +0100 Subject: Move PathKindUp --- crates/ra_hir_def/src/path.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index c37364f57..e38d924fa 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -18,6 +18,20 @@ pub struct ModPath { pub segments: Vec, } +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum PathKind { + Plain, + /// `self::` is `Super(0)` + Super(u8), + Crate, + /// Absolute path (::foo) + Abs, + /// Type based path like `::foo` + Type(Box), + /// `$crate` from macro expansion + DollarCrate(CrateId), +} + impl ModPath { pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option { lower::lower_path(path, hygiene).map(|it| it.mod_path) @@ -97,20 +111,6 @@ pub enum GenericArg { // or lifetime... } -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub enum PathKind { - Plain, - /// `self::` is `Super(0)` - Super(u8), - Crate, - /// Absolute path (::foo) - Abs, - /// Type based path like `::foo` - Type(Box), - /// `$crate` from macro expansion - DollarCrate(CrateId), -} - impl Path { /// Converts an `ast::Path` to `Path`. Works with use trees. /// DEPRECATED: It does not handle `$crate` from macro call. -- cgit v1.2.3 From 04715cbe1caf92e55d393a352a12454ba958845e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 18 Dec 2019 17:41:33 +0100 Subject: Forbid ::foo syntax in mod paths --- crates/ra_hir_def/src/body.rs | 12 ++++++++---- crates/ra_hir_def/src/nameres/path_resolution.rs | 5 ----- crates/ra_hir_def/src/path.rs | 12 +++++++++--- crates/ra_hir_def/src/path/lower.rs | 6 ++++-- 4 files changed, 21 insertions(+), 14 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 7787cb87f..d4cab0561 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -15,7 +15,7 @@ use crate::{ db::DefDatabase, expr::{Expr, ExprId, Pat, PatId}, nameres::{BuiltinShadowMode, CrateDefMap}, - path::Path, + path::{ModPath, Path}, src::HasSource, DefWithBodyId, HasModule, Lookup, ModuleId, }; @@ -44,7 +44,7 @@ impl Expander { db.ast_id_map(self.current_file_id).ast_id(¯o_call), ); - if let Some(path) = macro_call.path().and_then(|path| self.parse_path(path)) { + if let Some(path) = macro_call.path().and_then(|path| self.parse_mod_path(path)) { if let Some(def) = self.resolve_path_as_macro(db, &path) { let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); let file_id = call_id.as_file(); @@ -81,9 +81,13 @@ impl Expander { Path::from_src(path, &self.hygiene) } - fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &Path) -> Option { + fn parse_mod_path(&mut self, path: ast::Path) -> Option { + ModPath::from_src(path, &self.hygiene) + } + + fn resolve_path_as_macro(&self, db: &impl DefDatabase, path: &ModPath) -> Option { self.crate_def_map - .resolve_path(db, self.module.local_id, path.mod_path(), BuiltinShadowMode::Other) + .resolve_path(db, self.module.local_id, path, BuiltinShadowMode::Other) .0 .take_macros() } diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 1dbc4f371..2dd779b66 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -145,11 +145,6 @@ impl CrateDefMap { return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude } } - PathKind::Type(_) => { - // This is handled in `infer::infer_path_expr` - // The result returned here does not matter - return ResolvePathResult::empty(ReachedFixedPoint::Yes); - } }; for (i, segment) in segments { diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index e38d924fa..1e2da6b48 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -26,8 +26,6 @@ pub enum PathKind { Crate, /// Absolute path (::foo) Abs, - /// Type based path like `::foo` - Type(Box), /// `$crate` from macro expansion DollarCrate(CrateId), } @@ -84,6 +82,8 @@ impl ModPath { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Path { + /// Type based path like `::foo` + type_anchor: Option>, mod_path: ModPath, /// Invariant: the same len as self.path.segments generic_args: Vec>>, @@ -126,7 +126,7 @@ impl Path { /// Converts an `ast::NameRef` into a single-identifier `Path`. pub(crate) fn from_name_ref(name_ref: &ast::NameRef) -> Path { - Path { mod_path: name_ref.as_name().into(), generic_args: vec![None] } + Path { type_anchor: None, mod_path: name_ref.as_name().into(), generic_args: vec![None] } } /// `true` if this path is just a standalone `self` @@ -138,6 +138,10 @@ impl Path { &self.mod_path.kind } + pub fn type_anchor(&self) -> Option<&TypeRef> { + self.type_anchor.as_ref().map(|it| &**it) + } + pub fn segments(&self) -> PathSegments<'_> { PathSegments { segments: self.mod_path.segments.as_slice(), @@ -154,6 +158,7 @@ impl Path { return None; } let res = Path { + type_anchor: self.type_anchor.clone(), mod_path: ModPath { kind: self.mod_path.kind.clone(), segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(), @@ -226,6 +231,7 @@ impl GenericArgs { impl From for Path { fn from(name: Name) -> Path { Path { + type_anchor: None, mod_path: ModPath::from_simple_segments(PathKind::Plain, iter::once(name)), generic_args: vec![None], } diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index c71b52d89..62aafd508 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs @@ -22,6 +22,7 @@ pub(super) use lower_use::lower_use_tree; /// It correctly handles `$crate` based path from macro call. pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option { let mut kind = PathKind::Plain; + let mut type_anchor = None; let mut segments = Vec::new(); let mut generic_args = Vec::new(); loop { @@ -63,7 +64,8 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option match trait_ref { // ::foo None => { - kind = PathKind::Type(Box::new(self_type)); + type_anchor = Some(Box::new(self_type)); + kind = PathKind::Plain; } // >::Foo desugars to Trait::Foo Some(trait_ref) => { @@ -111,7 +113,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option segments.reverse(); generic_args.reverse(); let mod_path = ModPath { kind, segments }; - return Some(Path { mod_path, generic_args }); + return Some(Path { type_anchor, mod_path, generic_args }); fn qualifier(path: &ast::Path) -> Option { if let Some(q) = path.qualifier() { -- cgit v1.2.3 From d33fc26e05c573f536e02afbffc354fa4f4a35f3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 18 Dec 2019 17:42:49 +0100 Subject: Touch up docs --- crates/ra_hir_def/src/path.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 1e2da6b48..3fb0955d1 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -82,7 +82,8 @@ impl ModPath { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Path { - /// Type based path like `::foo` + /// Type based path like `::foo`. + /// Note that paths like `::foo` are desugard to `Trait::::foo`. type_anchor: Option>, mod_path: ModPath, /// Invariant: the same len as self.path.segments -- cgit v1.2.3 From afdeacf3c126b3e19bd1e50a912fee2b3f2d4aa9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 18 Dec 2019 17:52:52 +0100 Subject: Remove dead code --- crates/ra_hir_def/src/path.rs | 5 ----- 1 file changed, 5 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 3fb0955d1..7302cf0f1 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -130,11 +130,6 @@ impl Path { Path { type_anchor: None, mod_path: name_ref.as_name().into(), generic_args: vec![None] } } - /// `true` if this path is just a standalone `self` - pub fn is_self(&self) -> bool { - self.mod_path.is_self() - } - pub fn kind(&self) -> &PathKind { &self.mod_path.kind } -- cgit v1.2.3 From dddee23f43a0e1939124a607ba534e69a810843a Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Thu, 19 Dec 2019 12:45:07 +0800 Subject: Add std::ops::Index support for infering --- crates/ra_hir_def/src/path.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 3b26e8337..9e37ac416 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -254,6 +254,7 @@ macro_rules! __known_path { (std::ops::Try) => {}; (std::ops::Neg) => {}; (std::ops::Not) => {}; + (std::ops::Index) => {}; ($path:path) => { compile_error!("Please register your known path in the path module") }; -- cgit v1.2.3 From 43ed3d1196164c96d025745c42f261930b832911 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 19 Dec 2019 16:57:22 +0100 Subject: Handle start imports in import groups --- crates/ra_hir_def/src/marks.rs | 1 + crates/ra_hir_def/src/nameres/tests/globs.rs | 21 +++++++++++++++++++++ crates/ra_hir_def/src/path/lower/lower_use.rs | 12 +++++++++--- 3 files changed, 31 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/marks.rs b/crates/ra_hir_def/src/marks.rs index 65239ca0a..457ba4abe 100644 --- a/crates/ra_hir_def/src/marks.rs +++ b/crates/ra_hir_def/src/marks.rs @@ -5,6 +5,7 @@ test_utils::marks!( name_res_works_for_broken_modules can_import_enum_variant glob_enum + glob_enum_group glob_across_crates std_prelude macro_rules_from_other_crates_are_visible_with_macro_use diff --git a/crates/ra_hir_def/src/nameres/tests/globs.rs b/crates/ra_hir_def/src/nameres/tests/globs.rs index 5b03fe365..5e24cb94d 100644 --- a/crates/ra_hir_def/src/nameres/tests/globs.rs +++ b/crates/ra_hir_def/src/nameres/tests/globs.rs @@ -112,3 +112,24 @@ fn glob_enum() { "### ); } + +#[test] +fn glob_enum_group() { + covers!(glob_enum_group); + let map = def_map( + " + //- /lib.rs + enum Foo { + Bar, Baz + } + use self::Foo::{*}; + ", + ); + assert_snapshot!(map, @r###" + â‹®crate + â‹®Bar: t v + â‹®Baz: t v + â‹®Foo: t + "### + ); +} diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs index 062c02063..3218eaf0a 100644 --- a/crates/ra_hir_def/src/path/lower/lower_use.rs +++ b/crates/ra_hir_def/src/path/lower/lower_use.rs @@ -9,6 +9,7 @@ use hir_expand::{ name::{AsName, Name}, }; use ra_syntax::ast::{self, NameOwner}; +use test_utils::tested_by; use crate::path::{ModPath, PathKind}; @@ -34,6 +35,7 @@ pub(crate) fn lower_use_tree( } } else { let alias = tree.alias().and_then(|a| a.name()).map(|a| a.as_name()); + let is_glob = tree.has_star(); if let Some(ast_path) = tree.path() { // Handle self in a path. // E.g. `use something::{self, <...>}` @@ -48,11 +50,15 @@ pub(crate) fn lower_use_tree( } } if let Some(path) = convert_path(prefix, ast_path, hygiene) { - let is_glob = tree.has_star(); cb(path, &tree, is_glob, alias) } - // FIXME: report errors somewhere - // We get here if we do + // FIXME: report errors somewhere + // We get here if we do + } else if is_glob { + tested_by!(glob_enum_group); + if let Some(prefix) = prefix { + cb(prefix, &tree, is_glob, None) + } } } } -- cgit v1.2.3 From 5bd8de3f5e11732d67d0cc9bacda7d3a1b7cf13a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 19 Dec 2019 17:30:28 +0100 Subject: Allow storing defs in bodies --- crates/ra_hir_def/src/body.rs | 3 ++- crates/ra_hir_def/src/body/lower.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index d4cab0561..332c509e1 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -17,7 +17,7 @@ use crate::{ nameres::{BuiltinShadowMode, CrateDefMap}, path::{ModPath, Path}, src::HasSource, - DefWithBodyId, HasModule, Lookup, ModuleId, + DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, }; struct Expander { @@ -119,6 +119,7 @@ pub struct Body { pub params: Vec, /// The `ExprId` of the actual body expression. pub body_expr: ExprId, + pub defs: Vec, } pub type ExprPtr = Either, AstPtr>; diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 61193b4d8..86960186f 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -41,6 +41,7 @@ pub(super) fn lower( pats: Arena::default(), params: Vec::new(), body_expr: ExprId::dummy(), + defs: Vec::new(), }, } .collect(params, body) -- cgit v1.2.3 From ba12e83c26b24358e1bfbae0f913f8dfa13fc68f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 19 Dec 2019 18:12:46 +0100 Subject: Add body as a possible container for items --- crates/ra_hir_def/src/lib.rs | 24 ++++++++++++------------ crates/ra_hir_def/src/resolver.rs | 1 + 2 files changed, 13 insertions(+), 12 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index f085bbe87..4fc3127c4 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -335,6 +335,7 @@ pub enum ContainerId { ModuleId(ModuleId), ImplId(ImplId), TraitId(TraitId), + DefWithBodyId(DefWithBodyId), } /// A Data Type @@ -478,33 +479,32 @@ pub trait HasModule { fn module(&self, db: &impl db::DefDatabase) -> ModuleId; } -impl HasModule for FunctionLoc { +impl HasModule for ContainerId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { - match self.container { + match *self { ContainerId::ModuleId(it) => it, ContainerId::ImplId(it) => it.lookup(db).container, ContainerId::TraitId(it) => it.lookup(db).container, + ContainerId::DefWithBodyId(it) => it.module(db), } } } +impl HasModule for FunctionLoc { + fn module(&self, db: &impl db::DefDatabase) -> ModuleId { + self.container.module(db) + } +} + impl HasModule for TypeAliasLoc { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { - match self.container { - ContainerId::ModuleId(it) => it, - ContainerId::ImplId(it) => it.lookup(db).container, - ContainerId::TraitId(it) => it.lookup(db).container, - } + self.container.module(db) } } impl HasModule for ConstLoc { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { - match self.container { - ContainerId::ModuleId(it) => it, - ContainerId::ImplId(it) => it.lookup(db).container, - ContainerId::TraitId(it) => it.lookup(db).container, - } + self.container.module(db) } } diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 2694c0438..250329271 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -586,6 +586,7 @@ impl HasResolver for ContainerId { ContainerId::TraitId(it) => it.resolver(db), ContainerId::ImplId(it) => it.resolver(db), ContainerId::ModuleId(it) => it.resolver(db), + ContainerId::DefWithBodyId(it) => it.resolver(db), } } } -- cgit v1.2.3 From 9ccad60acca0d359f1fd9046c99952d0c1adc763 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 19 Dec 2019 18:21:26 +0100 Subject: Implement ChildBySource for DefWithBody --- crates/ra_hir_def/src/child_by_source.rs | 97 ++++++++++++++++++-------------- 1 file changed, 55 insertions(+), 42 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 3c9379b15..f5a65ad40 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -11,8 +11,8 @@ use crate::{ dyn_map::DynMap, keys, src::{HasChildSource, HasSource}, - AdtId, AssocItemId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, ModuleId, - StructFieldId, TraitId, VariantId, + AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, + ModuleId, StructFieldId, TraitId, VariantId, }; pub trait ChildBySource { @@ -76,47 +76,11 @@ impl ChildBySource for ModuleId { let mut res = DynMap::default(); let crate_def_map = db.crate_def_map(self.krate); - for item in crate_def_map[self.local_id].scope.declarations() { - match item { - ModuleDefId::FunctionId(func) => { - let src = func.lookup(db).source(db); - res[keys::FUNCTION].insert(src, func) - } - ModuleDefId::ConstId(konst) => { - let src = konst.lookup(db).source(db); - res[keys::CONST].insert(src, konst) - } - ModuleDefId::StaticId(statik) => { - let src = statik.lookup(db).source(db); - res[keys::STATIC].insert(src, statik) - } - ModuleDefId::TypeAliasId(ty) => { - let src = ty.lookup(db).source(db); - res[keys::TYPE_ALIAS].insert(src, ty) - } - ModuleDefId::TraitId(trait_) => { - let src = trait_.lookup(db).source(db); - res[keys::TRAIT].insert(src, trait_) - } - ModuleDefId::AdtId(adt) => match adt { - AdtId::StructId(strukt) => { - let src = strukt.lookup(db).source(db); - res[keys::STRUCT].insert(src, strukt) - } - AdtId::UnionId(union_) => { - let src = union_.lookup(db).source(db); - res[keys::UNION].insert(src, union_) - } - AdtId::EnumId(enum_) => { - let src = enum_.lookup(db).source(db); - res[keys::ENUM].insert(src, enum_) - } - }, - _ => (), - } - } + let module_data = &crate_def_map[self.local_id]; - for &impl_ in crate_def_map[self.local_id].impls.iter() { + module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); + + for &impl_ in module_data.impls.iter() { let src = impl_.lookup(db).source(db); res[keys::IMPL].insert(src, impl_) } @@ -125,6 +89,46 @@ impl ChildBySource for ModuleId { } } +fn add_module_def(db: &impl DefDatabase, map: &mut DynMap, item: ModuleDefId) { + match item { + ModuleDefId::FunctionId(func) => { + let src = func.lookup(db).source(db); + map[keys::FUNCTION].insert(src, func) + } + ModuleDefId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + map[keys::CONST].insert(src, konst) + } + ModuleDefId::StaticId(statik) => { + let src = statik.lookup(db).source(db); + map[keys::STATIC].insert(src, statik) + } + ModuleDefId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + map[keys::TYPE_ALIAS].insert(src, ty) + } + ModuleDefId::TraitId(trait_) => { + let src = trait_.lookup(db).source(db); + map[keys::TRAIT].insert(src, trait_) + } + ModuleDefId::AdtId(adt) => match adt { + AdtId::StructId(strukt) => { + let src = strukt.lookup(db).source(db); + map[keys::STRUCT].insert(src, strukt) + } + AdtId::UnionId(union_) => { + let src = union_.lookup(db).source(db); + map[keys::UNION].insert(src, union_) + } + AdtId::EnumId(enum_) => { + let src = enum_.lookup(db).source(db); + map[keys::ENUM].insert(src, enum_) + } + }, + _ => (), + } +} + impl ChildBySource for VariantId { fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { let mut res = DynMap::default(); @@ -160,3 +164,12 @@ impl ChildBySource for EnumId { res } } + +impl ChildBySource for DefWithBodyId { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + let body = db.body(*self); + body.defs.iter().copied().for_each(|item| add_module_def(db, &mut res, item)); + res + } +} -- cgit v1.2.3 From a04177f135be89ddbf1788c6f747c26812e90438 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 11:19:09 +0100 Subject: Add local functions to bodies --- crates/ra_hir_def/src/body.rs | 43 +++++++++++++++++++++++-------------- crates/ra_hir_def/src/body/lower.rs | 24 +++++++++++++++++++-- 2 files changed, 49 insertions(+), 18 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 332c509e1..92c32b080 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -3,10 +3,13 @@ mod lower; pub mod scope; -use std::{ops::Index, sync::Arc}; +use std::{mem, ops::Index, sync::Arc}; +use drop_bomb::DropBomb; use either::Either; -use hir_expand::{hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId}; +use hir_expand::{ + ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId, +}; use ra_arena::{map::ArenaMap, Arena}; use ra_syntax::{ast, AstNode, AstPtr}; use rustc_hash::FxHashMap; @@ -24,6 +27,7 @@ struct Expander { crate_def_map: Arc, current_file_id: HirFileId, hygiene: Hygiene, + ast_id_map: Arc, module: ModuleId, } @@ -31,7 +35,8 @@ impl Expander { fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { let crate_def_map = db.crate_def_map(module.krate); let hygiene = Hygiene::new(db, current_file_id); - Expander { crate_def_map, current_file_id, hygiene, module } + let ast_id_map = db.ast_id_map(current_file_id); + Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } } fn enter_expand( @@ -52,9 +57,14 @@ impl Expander { if let Some(expr) = ast::Expr::cast(node) { log::debug!("macro expansion {:#?}", expr.syntax()); - let mark = Mark { file_id: self.current_file_id }; + let mark = Mark { + file_id: self.current_file_id, + ast_id_map: mem::take(&mut self.ast_id_map), + bomb: DropBomb::new("expansion mark dropped"), + }; self.hygiene = Hygiene::new(db, file_id); self.current_file_id = file_id; + self.ast_id_map = db.ast_id_map(file_id); return Some((mark, expr)); } @@ -67,10 +77,11 @@ impl Expander { None } - fn exit(&mut self, db: &impl DefDatabase, mark: Mark) { + fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) { self.hygiene = Hygiene::new(db, mark.file_id); self.current_file_id = mark.file_id; - std::mem::forget(mark); + self.ast_id_map = mem::take(&mut mark.ast_id_map); + mark.bomb.defuse(); } fn to_source(&self, value: T) -> InFile { @@ -91,18 +102,17 @@ impl Expander { .0 .take_macros() } + + fn ast_id(&self, item: &N) -> AstId { + let file_local_id = self.ast_id_map.ast_id(item); + AstId::new(self.current_file_id, file_local_id) + } } struct Mark { file_id: HirFileId, -} - -impl Drop for Mark { - fn drop(&mut self) { - if !std::thread::panicking() { - panic!("dropped mark") - } - } + ast_id_map: Arc, + bomb: DropBomb, } /// The body of an item (function, const etc.). @@ -174,7 +184,7 @@ impl Body { } }; let expander = Expander::new(db, file_id, module); - let (body, source_map) = Body::new(db, expander, params, body); + let (body, source_map) = Body::new(db, def, expander, params, body); (Arc::new(body), Arc::new(source_map)) } @@ -184,11 +194,12 @@ impl Body { fn new( db: &impl DefDatabase, + def: DefWithBodyId, expander: Expander, params: Option, body: Option, ) -> (Body, BodySourceMap) { - lower::lower(db, expander, params, body) + lower::lower(db, def, expander, params, body) } } diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 86960186f..17efa10e2 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -2,11 +2,12 @@ //! representation. use either::Either; + use hir_expand::name::{name, AsName, Name}; use ra_arena::Arena; use ra_syntax::{ ast::{ - self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, + self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner, TypeAscriptionOwner, }, AstNode, AstPtr, @@ -24,17 +25,20 @@ use crate::{ path::GenericArgs, path::Path, type_ref::{Mutability, TypeRef}, + ContainerId, DefWithBodyId, FunctionLoc, Intern, }; pub(super) fn lower( db: &impl DefDatabase, + def: DefWithBodyId, expander: Expander, params: Option, body: Option, ) -> (Body, BodySourceMap) { ExprCollector { - expander, db, + def, + expander, source_map: BodySourceMap::default(), body: Body { exprs: Arena::default(), @@ -49,6 +53,7 @@ pub(super) fn lower( struct ExprCollector { db: DB, + def: DefWithBodyId, expander: Expander, body: Body, @@ -467,6 +472,7 @@ where Some(block) => block, None => return self.alloc_expr(Expr::Missing, syntax_node_ptr), }; + self.collect_block_items(&block); let statements = block .statements() .map(|s| match s { @@ -483,6 +489,20 @@ where self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) } + fn collect_block_items(&mut self, block: &ast::Block) { + let container = ContainerId::DefWithBodyId(self.def); + for item in block.items() { + match item { + ast::ModuleItem::FnDef(def) => { + let ast_id = self.expander.ast_id(&def); + self.body.defs.push(FunctionLoc { container, ast_id }.intern(self.db).into()) + } + // FIXME: handle other items + _ => (), + } + } + } + fn collect_block_opt(&mut self, expr: Option) -> ExprId { if let Some(block) = expr { self.collect_block(block) -- cgit v1.2.3 From 8fc20b65035d93bcc1b3a89127916bd165a8d938 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 11:59:50 +0100 Subject: Rename ContainerId -> AssocContainerId --- crates/ra_hir_def/src/body/lower.rs | 4 ++-- crates/ra_hir_def/src/data.rs | 12 ++++++------ crates/ra_hir_def/src/lib.rs | 18 +++++++++--------- crates/ra_hir_def/src/nameres/collector.rs | 8 ++++---- crates/ra_hir_def/src/resolver.rs | 16 ++++++++-------- 5 files changed, 29 insertions(+), 29 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 17efa10e2..afd5231cc 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -25,7 +25,7 @@ use crate::{ path::GenericArgs, path::Path, type_ref::{Mutability, TypeRef}, - ContainerId, DefWithBodyId, FunctionLoc, Intern, + AssocContainerId, DefWithBodyId, FunctionLoc, Intern, }; pub(super) fn lower( @@ -490,7 +490,7 @@ where } fn collect_block_items(&mut self, block: &ast::Block) { - let container = ContainerId::DefWithBodyId(self.def); + let container = AssocContainerId::DefWithBodyId(self.def); for item in block.items() { match item { ast::ModuleItem::FnDef(def) => { diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 4f4ef57cc..14e86936b 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -12,8 +12,8 @@ use crate::{ db::DefDatabase, src::HasSource, type_ref::{Mutability, TypeRef}, - AssocItemId, ConstId, ConstLoc, ContainerId, FunctionId, FunctionLoc, ImplId, Intern, Lookup, - StaticId, TraitId, TypeAliasId, TypeAliasLoc, + AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, ImplId, Intern, + Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -99,7 +99,7 @@ impl TraitData { let auto = src.value.is_auto(); let ast_id_map = db.ast_id_map(src.file_id); - let container = ContainerId::TraitId(tr); + let container = AssocContainerId::TraitId(tr); let items = if let Some(item_list) = src.value.item_list() { item_list .impl_items() @@ -180,7 +180,7 @@ impl ImplData { .map(|item_node| match item_node { ast::ImplItem::FnDef(it) => { let def = FunctionLoc { - container: ContainerId::ImplId(id), + container: AssocContainerId::ImplId(id), ast_id: AstId::new(src.file_id, items.ast_id(&it)), } .intern(db); @@ -188,7 +188,7 @@ impl ImplData { } ast::ImplItem::ConstDef(it) => { let def = ConstLoc { - container: ContainerId::ImplId(id), + container: AssocContainerId::ImplId(id), ast_id: AstId::new(src.file_id, items.ast_id(&it)), } .intern(db); @@ -196,7 +196,7 @@ impl ImplData { } ast::ImplItem::TypeAliasDef(it) => { let def = TypeAliasLoc { - container: ContainerId::ImplId(id), + container: AssocContainerId::ImplId(id), ast_id: AstId::new(src.file_id, items.ast_id(&it)), } .intern(db); diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 4fc3127c4..3d42762ae 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -71,7 +71,7 @@ impl_intern_key!(FunctionId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct FunctionLoc { - pub container: ContainerId, + pub container: AssocContainerId, pub ast_id: AstId, } @@ -187,7 +187,7 @@ pub struct ConstId(salsa::InternId); impl_intern_key!(ConstId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ConstLoc { - pub container: ContainerId, + pub container: AssocContainerId, pub ast_id: AstId, } @@ -259,7 +259,7 @@ impl_intern_key!(TypeAliasId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TypeAliasLoc { - pub container: ContainerId, + pub container: AssocContainerId, pub ast_id: AstId, } @@ -331,7 +331,7 @@ pub struct LocalTypeParamId(RawId); impl_arena_id!(LocalTypeParamId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum ContainerId { +pub enum AssocContainerId { ModuleId(ModuleId), ImplId(ImplId), TraitId(TraitId), @@ -479,13 +479,13 @@ pub trait HasModule { fn module(&self, db: &impl db::DefDatabase) -> ModuleId; } -impl HasModule for ContainerId { +impl HasModule for AssocContainerId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match *self { - ContainerId::ModuleId(it) => it, - ContainerId::ImplId(it) => it.lookup(db).container, - ContainerId::TraitId(it) => it.lookup(db).container, - ContainerId::DefWithBodyId(it) => it.module(db), + AssocContainerId::ModuleId(it) => it, + AssocContainerId::ImplId(it) => it.lookup(db).container, + AssocContainerId::TraitId(it) => it.lookup(db).container, + AssocContainerId::DefWithBodyId(it) => it.module(db), } } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 8bbf7ffa2..848959f7c 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -24,7 +24,7 @@ use crate::{ }, path::{ModPath, PathKind}, per_ns::PerNs, - AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, + AdtId, AssocContainerId, AstId, ConstLoc, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, }; @@ -763,7 +763,7 @@ where let def: PerNs = match def.kind { raw::DefKind::Function(ast_id) => { let def = FunctionLoc { - container: ContainerId::ModuleId(module), + container: AssocContainerId::ModuleId(module), ast_id: AstId::new(self.file_id, ast_id), } .intern(self.def_collector.db); @@ -787,7 +787,7 @@ where } raw::DefKind::Const(ast_id) => { let def = ConstLoc { - container: ContainerId::ModuleId(module), + container: AssocContainerId::ModuleId(module), ast_id: AstId::new(self.file_id, ast_id), } .intern(self.def_collector.db); @@ -808,7 +808,7 @@ where } raw::DefKind::TypeAlias(ast_id) => { let def = TypeAliasLoc { - container: ContainerId::ModuleId(module), + container: AssocContainerId::ModuleId(module), ast_id: AstId::new(self.file_id, ast_id), } .intern(self.def_collector.db); diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 250329271..d79c9813b 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -17,9 +17,9 @@ use crate::{ nameres::{BuiltinShadowMode, CrateDefMap}, path::{ModPath, PathKind}, per_ns::PerNs, - AdtId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, GenericDefId, - HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, StructId, TraitId, - TypeAliasId, TypeParamId, VariantId, + AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, + GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, + StructId, TraitId, TypeAliasId, TypeParamId, VariantId, }; #[derive(Debug, Clone, Default)] @@ -580,13 +580,13 @@ impl HasResolver for DefWithBodyId { } } -impl HasResolver for ContainerId { +impl HasResolver for AssocContainerId { fn resolver(self, db: &impl DefDatabase) -> Resolver { match self { - ContainerId::TraitId(it) => it.resolver(db), - ContainerId::ImplId(it) => it.resolver(db), - ContainerId::ModuleId(it) => it.resolver(db), - ContainerId::DefWithBodyId(it) => it.resolver(db), + AssocContainerId::TraitId(it) => it.resolver(db), + AssocContainerId::ImplId(it) => it.resolver(db), + AssocContainerId::ModuleId(it) => it.resolver(db), + AssocContainerId::DefWithBodyId(it) => it.resolver(db), } } } -- cgit v1.2.3 From 94ad07af4bef6a70602e315bf315c6fce95618dd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 12:07:23 +0100 Subject: Introduce `ContainerId` --- crates/ra_hir_def/src/body/lower.rs | 4 ++-- crates/ra_hir_def/src/lib.rs | 22 ++++++++++++++++++---- crates/ra_hir_def/src/nameres/collector.rs | 9 +++++---- crates/ra_hir_def/src/resolver.rs | 18 +++++++++++++----- 4 files changed, 38 insertions(+), 15 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index afd5231cc..0103a1aab 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -25,7 +25,7 @@ use crate::{ path::GenericArgs, path::Path, type_ref::{Mutability, TypeRef}, - AssocContainerId, DefWithBodyId, FunctionLoc, Intern, + ContainerId, DefWithBodyId, FunctionLoc, Intern, }; pub(super) fn lower( @@ -490,7 +490,7 @@ where } fn collect_block_items(&mut self, block: &ast::Block) { - let container = AssocContainerId::DefWithBodyId(self.def); + let container = ContainerId::DefWithBodyId(self.def).into(); for item in block.items() { match item { ast::ModuleItem::FnDef(def) => { diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 3d42762ae..5e46db1aa 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -331,12 +331,18 @@ pub struct LocalTypeParamId(RawId); impl_arena_id!(LocalTypeParamId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum AssocContainerId { +pub enum ContainerId { ModuleId(ModuleId), + DefWithBodyId(DefWithBodyId), +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum AssocContainerId { + ContainerId(ContainerId), ImplId(ImplId), TraitId(TraitId), - DefWithBodyId(DefWithBodyId), } +impl_froms!(AssocContainerId: ContainerId); /// A Data Type #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -479,13 +485,21 @@ pub trait HasModule { fn module(&self, db: &impl db::DefDatabase) -> ModuleId; } +impl HasModule for ContainerId { + fn module(&self, db: &impl db::DefDatabase) -> ModuleId { + match *self { + ContainerId::ModuleId(it) => it, + ContainerId::DefWithBodyId(it) => it.module(db), + } + } +} + impl HasModule for AssocContainerId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match *self { - AssocContainerId::ModuleId(it) => it, + AssocContainerId::ContainerId(it) => it.module(db), AssocContainerId::ImplId(it) => it.lookup(db).container, AssocContainerId::TraitId(it) => it.lookup(db).container, - AssocContainerId::DefWithBodyId(it) => it.module(db), } } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 848959f7c..0f3319f30 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -24,7 +24,7 @@ use crate::{ }, path::{ModPath, PathKind}, per_ns::PerNs, - AdtId, AssocContainerId, AstId, ConstLoc, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, + AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, }; @@ -760,10 +760,11 @@ where self.collect_derives(attrs, def); let name = def.name.clone(); + let container = ContainerId::ModuleId(module); let def: PerNs = match def.kind { raw::DefKind::Function(ast_id) => { let def = FunctionLoc { - container: AssocContainerId::ModuleId(module), + container: container.into(), ast_id: AstId::new(self.file_id, ast_id), } .intern(self.def_collector.db); @@ -787,7 +788,7 @@ where } raw::DefKind::Const(ast_id) => { let def = ConstLoc { - container: AssocContainerId::ModuleId(module), + container: container.into(), ast_id: AstId::new(self.file_id, ast_id), } .intern(self.def_collector.db); @@ -808,7 +809,7 @@ where } raw::DefKind::TypeAlias(ast_id) => { let def = TypeAliasLoc { - container: AssocContainerId::ModuleId(module), + container: container.into(), ast_id: AstId::new(self.file_id, ast_id), } .intern(self.def_collector.db); diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index d79c9813b..af9d194f8 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -17,9 +17,9 @@ use crate::{ nameres::{BuiltinShadowMode, CrateDefMap}, path::{ModPath, PathKind}, per_ns::PerNs, - AdtId, AssocContainerId, ConstId, DefWithBodyId, EnumId, EnumVariantId, FunctionId, - GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, StaticId, - StructId, TraitId, TypeAliasId, TypeParamId, VariantId, + AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, + FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId, + StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId, }; #[derive(Debug, Clone, Default)] @@ -580,13 +580,21 @@ impl HasResolver for DefWithBodyId { } } +impl HasResolver for ContainerId { + fn resolver(self, db: &impl DefDatabase) -> Resolver { + match self { + ContainerId::ModuleId(it) => it.resolver(db), + ContainerId::DefWithBodyId(it) => it.resolver(db), + } + } +} + impl HasResolver for AssocContainerId { fn resolver(self, db: &impl DefDatabase) -> Resolver { match self { + AssocContainerId::ContainerId(it) => it.resolver(db), AssocContainerId::TraitId(it) => it.resolver(db), AssocContainerId::ImplId(it) => it.resolver(db), - AssocContainerId::ModuleId(it) => it.resolver(db), - AssocContainerId::DefWithBodyId(it) => it.resolver(db), } } } -- cgit v1.2.3 From ac5a3f611b05dbedd286169539335ae9f0fbb7b0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 12:20:49 +0100 Subject: Support for nested ADT --- crates/ra_hir_def/src/body/lower.rs | 26 +++++++++++++++++++------- crates/ra_hir_def/src/lib.rs | 9 +++++---- crates/ra_hir_def/src/nameres/collector.rs | 6 +++--- 3 files changed, 27 insertions(+), 14 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 0103a1aab..0d3f946df 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -25,7 +25,7 @@ use crate::{ path::GenericArgs, path::Path, type_ref::{Mutability, TypeRef}, - ContainerId, DefWithBodyId, FunctionLoc, Intern, + ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StructLoc, UnionLoc, }; pub(super) fn lower( @@ -490,16 +490,28 @@ where } fn collect_block_items(&mut self, block: &ast::Block) { - let container = ContainerId::DefWithBodyId(self.def).into(); + let container = ContainerId::DefWithBodyId(self.def); for item in block.items() { - match item { + let def: ModuleDefId = match item { ast::ModuleItem::FnDef(def) => { let ast_id = self.expander.ast_id(&def); - self.body.defs.push(FunctionLoc { container, ast_id }.intern(self.db).into()) + FunctionLoc { container: container.into(), ast_id }.intern(self.db).into() } - // FIXME: handle other items - _ => (), - } + ast::ModuleItem::StructDef(def) => { + let ast_id = self.expander.ast_id(&def); + StructLoc { container, ast_id }.intern(self.db).into() + } + ast::ModuleItem::EnumDef(def) => { + let ast_id = self.expander.ast_id(&def); + EnumLoc { container, ast_id }.intern(self.db).into() + } + ast::ModuleItem::UnionDef(def) => { + let ast_id = self.expander.ast_id(&def); + UnionLoc { container, ast_id }.intern(self.db).into() + } + _ => continue, + }; + self.body.defs.push(def) } } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 5e46db1aa..a82de7dec 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -95,7 +95,7 @@ impl_intern_key!(StructId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StructLoc { - pub container: ModuleId, + pub container: ContainerId, pub ast_id: AstId, } @@ -119,7 +119,7 @@ impl_intern_key!(UnionId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct UnionLoc { - pub container: ModuleId, + pub container: ContainerId, pub ast_id: AstId, } @@ -143,7 +143,7 @@ impl_intern_key!(EnumId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct EnumLoc { - pub container: ModuleId, + pub container: ContainerId, pub ast_id: AstId, } @@ -529,6 +529,7 @@ impl HasModule for AdtId { AdtId::UnionId(it) => it.lookup(db).container, AdtId::EnumId(it) => it.lookup(db).container, } + .module(db) } } @@ -550,7 +551,7 @@ impl HasModule for GenericDefId { GenericDefId::TraitId(it) => it.lookup(db).container, GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), GenericDefId::ImplId(it) => it.lookup(db).container, - GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container, + GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), GenericDefId::ConstId(it) => it.lookup(db).module(db), } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 0f3319f30..1b39af61e 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -772,17 +772,17 @@ where PerNs::values(def.into()) } raw::DefKind::Struct(ast_id) => { - let def = StructLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + let def = StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db); PerNs::both(def.into(), def.into()) } raw::DefKind::Union(ast_id) => { - let def = UnionLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + let def = UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db); PerNs::both(def.into(), def.into()) } raw::DefKind::Enum(ast_id) => { - let def = EnumLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + let def = EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db); PerNs::types(def.into()) } -- cgit v1.2.3 From fe1b160dcfdeb3f582ccae1440c9580ade0beb39 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 12:22:55 +0100 Subject: Support for nested statics, consts and type aliases --- crates/ra_hir_def/src/body/lower.rs | 15 ++++++++++++++- crates/ra_hir_def/src/lib.rs | 6 +++--- crates/ra_hir_def/src/nameres/collector.rs | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 0d3f946df..b61f924b7 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -25,7 +25,8 @@ use crate::{ path::GenericArgs, path::Path, type_ref::{Mutability, TypeRef}, - ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StructLoc, UnionLoc, + ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc, + StructLoc, TypeAliasLoc, UnionLoc, }; pub(super) fn lower( @@ -497,6 +498,18 @@ where let ast_id = self.expander.ast_id(&def); FunctionLoc { container: container.into(), ast_id }.intern(self.db).into() } + ast::ModuleItem::TypeAliasDef(def) => { + let ast_id = self.expander.ast_id(&def); + TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into() + } + ast::ModuleItem::ConstDef(def) => { + let ast_id = self.expander.ast_id(&def); + ConstLoc { container: container.into(), ast_id }.intern(self.db).into() + } + ast::ModuleItem::StaticDef(def) => { + let ast_id = self.expander.ast_id(&def); + StaticLoc { container, ast_id }.intern(self.db).into() + } ast::ModuleItem::StructDef(def) => { let ast_id = self.expander.ast_id(&def); StructLoc { container, ast_id }.intern(self.db).into() diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index a82de7dec..9b192b597 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -211,7 +211,7 @@ impl_intern_key!(StaticId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct StaticLoc { - pub container: ModuleId, + pub container: ContainerId, pub ast_id: AstId, } @@ -558,7 +558,7 @@ impl HasModule for GenericDefId { } impl HasModule for StaticLoc { - fn module(&self, _db: &impl db::DefDatabase) -> ModuleId { - self.container + fn module(&self, db: &impl db::DefDatabase) -> ModuleId { + self.container.module(db) } } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 1b39af61e..74c3d4670 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -796,7 +796,7 @@ where PerNs::values(def.into()) } raw::DefKind::Static(ast_id) => { - let def = StaticLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + let def = StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db); PerNs::values(def.into()) -- cgit v1.2.3 From f42697e54b9d0a040011cb04c266d51710e249f1 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 12:29:25 +0100 Subject: Support for nested traits --- crates/ra_hir_def/src/body/lower.rs | 11 +++++++++-- crates/ra_hir_def/src/lib.rs | 6 +++--- crates/ra_hir_def/src/nameres/collector.rs | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index b61f924b7..853e17bae 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -26,7 +26,7 @@ use crate::{ path::Path, type_ref::{Mutability, TypeRef}, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, StaticLoc, - StructLoc, TypeAliasLoc, UnionLoc, + StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, }; pub(super) fn lower( @@ -522,7 +522,14 @@ where let ast_id = self.expander.ast_id(&def); UnionLoc { container, ast_id }.intern(self.db).into() } - _ => continue, + ast::ModuleItem::TraitDef(def) => { + let ast_id = self.expander.ast_id(&def); + TraitLoc { container, ast_id }.intern(self.db).into() + } + ast::ModuleItem::ImplBlock(_) + | ast::ModuleItem::UseItem(_) + | ast::ModuleItem::ExternCrateItem(_) + | ast::ModuleItem::Module(_) => continue, }; self.body.defs.push(def) } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 9b192b597..140eccf26 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -235,7 +235,7 @@ impl_intern_key!(TraitId); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct TraitLoc { - pub container: ModuleId, + pub container: ContainerId, pub ast_id: AstId, } @@ -499,7 +499,7 @@ impl HasModule for AssocContainerId { match *self { AssocContainerId::ContainerId(it) => it.module(db), AssocContainerId::ImplId(it) => it.lookup(db).container, - AssocContainerId::TraitId(it) => it.lookup(db).container, + AssocContainerId::TraitId(it) => it.lookup(db).container.module(db), } } } @@ -548,7 +548,7 @@ impl HasModule for GenericDefId { match self { GenericDefId::FunctionId(it) => it.lookup(db).module(db), GenericDefId::AdtId(it) => it.module(db), - GenericDefId::TraitId(it) => it.lookup(db).container, + GenericDefId::TraitId(it) => it.lookup(db).container.module(db), GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), GenericDefId::ImplId(it) => it.lookup(db).container, GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 74c3d4670..a1ea130e0 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -802,7 +802,7 @@ where PerNs::values(def.into()) } raw::DefKind::Trait(ast_id) => { - let def = TraitLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + let def = TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db); PerNs::types(def.into()) -- cgit v1.2.3 From 957c0171e63631f67d732f4ce53dc8bfe2602e71 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 13:11:01 +0100 Subject: Remove more copy-paste --- crates/ra_hir_def/src/lib.rs | 87 +++++++++++++++----------------------------- 1 file changed, 30 insertions(+), 57 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 140eccf26..042fd3f8b 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -45,7 +45,7 @@ use std::hash::Hash; use hir_expand::{ast_id_map::FileAstId, AstId, HirFileId, InFile, MacroDefId}; use ra_arena::{impl_arena_id, RawId}; use ra_db::{impl_intern_key, salsa, CrateId}; -use ra_syntax::ast; +use ra_syntax::{ast, AstNode}; use crate::builtin_type::BuiltinType; @@ -65,16 +65,23 @@ pub struct ModuleId { pub struct LocalModuleId(RawId); impl_arena_id!(LocalModuleId); -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct FunctionId(salsa::InternId); -impl_intern_key!(FunctionId); +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ItemLoc { + pub container: ContainerId, + pub ast_id: AstId, +} #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct FunctionLoc { +pub struct AssocItemLoc { pub container: AssocContainerId, - pub ast_id: AstId, + pub ast_id: AstId, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct FunctionId(salsa::InternId); +impl_intern_key!(FunctionId); +type FunctionLoc = AssocItemLoc; + impl Intern for FunctionLoc { type ID = FunctionId; fn intern(self, db: &impl db::DefDatabase) -> FunctionId { @@ -92,12 +99,7 @@ impl Lookup for FunctionId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StructId(salsa::InternId); impl_intern_key!(StructId); - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StructLoc { - pub container: ContainerId, - pub ast_id: AstId, -} +pub type StructLoc = ItemLoc; impl Intern for StructLoc { type ID = StructId; @@ -116,12 +118,7 @@ impl Lookup for StructId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UnionId(salsa::InternId); impl_intern_key!(UnionId); - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct UnionLoc { - pub container: ContainerId, - pub ast_id: AstId, -} +pub type UnionLoc = ItemLoc; impl Intern for UnionLoc { type ID = UnionId; @@ -140,12 +137,7 @@ impl Lookup for UnionId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct EnumId(salsa::InternId); impl_intern_key!(EnumId); - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct EnumLoc { - pub container: ContainerId, - pub ast_id: AstId, -} +pub type EnumLoc = ItemLoc; impl Intern for EnumLoc { type ID = EnumId; @@ -185,11 +177,7 @@ impl_arena_id!(LocalStructFieldId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ConstId(salsa::InternId); impl_intern_key!(ConstId); -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ConstLoc { - pub container: AssocContainerId, - pub ast_id: AstId, -} +type ConstLoc = AssocItemLoc; impl Intern for ConstLoc { type ID = ConstId; @@ -208,12 +196,7 @@ impl Lookup for ConstId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StaticId(salsa::InternId); impl_intern_key!(StaticId); - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct StaticLoc { - pub container: ContainerId, - pub ast_id: AstId, -} +pub type StaticLoc = ItemLoc; impl Intern for StaticLoc { type ID = StaticId; @@ -232,12 +215,7 @@ impl Lookup for StaticId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TraitId(salsa::InternId); impl_intern_key!(TraitId); - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TraitLoc { - pub container: ContainerId, - pub ast_id: AstId, -} +pub type TraitLoc = ItemLoc; impl Intern for TraitLoc { type ID = TraitId; @@ -256,12 +234,7 @@ impl Lookup for TraitId { #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TypeAliasId(salsa::InternId); impl_intern_key!(TypeAliasId); - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct TypeAliasLoc { - pub container: AssocContainerId, - pub ast_id: AstId, -} +type TypeAliasLoc = AssocItemLoc; impl Intern for TypeAliasLoc { type ID = TypeAliasId; @@ -301,6 +274,16 @@ impl Lookup for ImplId { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct TypeParamId { + pub parent: GenericDefId, + pub local_id: LocalTypeParamId, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct LocalTypeParamId(RawId); +impl_arena_id!(LocalTypeParamId); + macro_rules! impl_froms { ($e:ident: $($v:ident $(($($sv:ident),*))?),*) => { $( @@ -320,16 +303,6 @@ macro_rules! impl_froms { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct TypeParamId { - pub parent: GenericDefId, - pub local_id: LocalTypeParamId, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct LocalTypeParamId(RawId); -impl_arena_id!(LocalTypeParamId); - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum ContainerId { ModuleId(ModuleId), -- cgit v1.2.3 From d137df0137dab36819efada901e92cd2733f292b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 13:19:41 +0100 Subject: Remove more copy-paste --- crates/ra_hir_def/src/lib.rs | 150 +++++++++---------------------------------- 1 file changed, 29 insertions(+), 121 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 042fd3f8b..faeb2fc8a 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -77,81 +77,45 @@ pub struct AssocItemLoc { pub ast_id: AstId, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct FunctionId(salsa::InternId); -impl_intern_key!(FunctionId); -type FunctionLoc = AssocItemLoc; +macro_rules! impl_intern { + ($id:ident, $loc:ident, $intern:ident, $lookup:ident) => { + impl_intern_key!($id); + + impl Intern for $loc { + type ID = $id; + fn intern(self, db: &impl db::DefDatabase) -> $id { + db.$intern(self) + } + } -impl Intern for FunctionLoc { - type ID = FunctionId; - fn intern(self, db: &impl db::DefDatabase) -> FunctionId { - db.intern_function(self) - } + impl Lookup for $id { + type Data = $loc; + fn lookup(&self, db: &impl db::DefDatabase) -> $loc { + db.$lookup(*self) + } + } + }; } -impl Lookup for FunctionId { - type Data = FunctionLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> FunctionLoc { - db.lookup_intern_function(*self) - } -} +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct FunctionId(salsa::InternId); +type FunctionLoc = AssocItemLoc; +impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StructId(salsa::InternId); -impl_intern_key!(StructId); -pub type StructLoc = ItemLoc; - -impl Intern for StructLoc { - type ID = StructId; - fn intern(self, db: &impl db::DefDatabase) -> StructId { - db.intern_struct(self) - } -} - -impl Lookup for StructId { - type Data = StructLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> StructLoc { - db.lookup_intern_struct(*self) - } -} +type StructLoc = ItemLoc; +impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct UnionId(salsa::InternId); -impl_intern_key!(UnionId); pub type UnionLoc = ItemLoc; - -impl Intern for UnionLoc { - type ID = UnionId; - fn intern(self, db: &impl db::DefDatabase) -> UnionId { - db.intern_union(self) - } -} - -impl Lookup for UnionId { - type Data = UnionLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> UnionLoc { - db.lookup_intern_union(*self) - } -} +impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct EnumId(salsa::InternId); -impl_intern_key!(EnumId); pub type EnumLoc = ItemLoc; - -impl Intern for EnumLoc { - type ID = EnumId; - fn intern(self, db: &impl db::DefDatabase) -> EnumId { - db.intern_enum(self) - } -} - -impl Lookup for EnumId { - type Data = EnumLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> EnumLoc { - db.lookup_intern_enum(*self) - } -} +impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); // FIXME: rename to `VariantId`, only enums can ave variants #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -176,79 +140,23 @@ impl_arena_id!(LocalStructFieldId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ConstId(salsa::InternId); -impl_intern_key!(ConstId); type ConstLoc = AssocItemLoc; - -impl Intern for ConstLoc { - type ID = ConstId; - fn intern(self, db: &impl db::DefDatabase) -> ConstId { - db.intern_const(self) - } -} - -impl Lookup for ConstId { - type Data = ConstLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> ConstLoc { - db.lookup_intern_const(*self) - } -} +impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct StaticId(salsa::InternId); -impl_intern_key!(StaticId); pub type StaticLoc = ItemLoc; - -impl Intern for StaticLoc { - type ID = StaticId; - fn intern(self, db: &impl db::DefDatabase) -> StaticId { - db.intern_static(self) - } -} - -impl Lookup for StaticId { - type Data = StaticLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> StaticLoc { - db.lookup_intern_static(*self) - } -} +impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TraitId(salsa::InternId); -impl_intern_key!(TraitId); pub type TraitLoc = ItemLoc; - -impl Intern for TraitLoc { - type ID = TraitId; - fn intern(self, db: &impl db::DefDatabase) -> TraitId { - db.intern_trait(self) - } -} - -impl Lookup for TraitId { - type Data = TraitLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> TraitLoc { - db.lookup_intern_trait(*self) - } -} +impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TypeAliasId(salsa::InternId); -impl_intern_key!(TypeAliasId); type TypeAliasLoc = AssocItemLoc; - -impl Intern for TypeAliasLoc { - type ID = TypeAliasId; - fn intern(self, db: &impl db::DefDatabase) -> TypeAliasId { - db.intern_type_alias(self) - } -} - -impl Lookup for TypeAliasId { - type Data = TypeAliasLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> TypeAliasLoc { - db.lookup_intern_type_alias(*self) - } -} +impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ImplId(salsa::InternId); -- cgit v1.2.3 From 1234dda9ee60a19a83a9664c2e1208247566b49b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 13:47:44 +0100 Subject: Use generic ItemLoc for impls --- crates/ra_hir_def/src/lib.rs | 27 ++++----------------------- crates/ra_hir_def/src/nameres/collector.rs | 3 ++- 2 files changed, 6 insertions(+), 24 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index faeb2fc8a..d11b573e5 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -160,27 +160,8 @@ impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_al #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ImplId(salsa::InternId); -impl_intern_key!(ImplId); - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct ImplLoc { - pub container: ModuleId, - pub ast_id: AstId, -} - -impl Intern for ImplLoc { - type ID = ImplId; - fn intern(self, db: &impl db::DefDatabase) -> ImplId { - db.intern_impl(self) - } -} - -impl Lookup for ImplId { - type Data = ImplLoc; - fn lookup(&self, db: &impl db::DefDatabase) -> ImplLoc { - db.lookup_intern_impl(*self) - } -} +type ImplLoc = ItemLoc; +impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TypeParamId { @@ -379,7 +360,7 @@ impl HasModule for AssocContainerId { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { match *self { AssocContainerId::ContainerId(it) => it.module(db), - AssocContainerId::ImplId(it) => it.lookup(db).container, + AssocContainerId::ImplId(it) => it.lookup(db).container.module(db), AssocContainerId::TraitId(it) => it.lookup(db).container.module(db), } } @@ -431,7 +412,7 @@ impl HasModule for GenericDefId { GenericDefId::AdtId(it) => it.module(db), GenericDefId::TraitId(it) => it.lookup(db).container.module(db), GenericDefId::TypeAliasId(it) => it.lookup(db).module(db), - GenericDefId::ImplId(it) => it.lookup(db).container, + GenericDefId::ImplId(it) => it.lookup(db).container.module(db), GenericDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), GenericDefId::ConstId(it) => it.lookup(db).module(db), } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index a1ea130e0..e68bf4868 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -661,9 +661,10 @@ where krate: self.def_collector.def_map.krate, local_id: self.module_id, }; + let container = ContainerId::ModuleId(module); let ast_id = self.raw_items[imp].ast_id; let impl_id = - ImplLoc { container: module, ast_id: AstId::new(self.file_id, ast_id) } + ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db); self.def_collector.def_map.modules[self.module_id].impls.push(impl_id) } -- cgit v1.2.3 From 2d8a001465de8857090807f39fe667d98b05da30 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 13:58:09 +0100 Subject: Reduce copy-paste some more --- crates/ra_hir_def/src/lib.rs | 14 +------- crates/ra_hir_def/src/src.rs | 82 +++++--------------------------------------- 2 files changed, 9 insertions(+), 87 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index d11b573e5..8ed1599ff 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -366,19 +366,7 @@ impl HasModule for AssocContainerId { } } -impl HasModule for FunctionLoc { - fn module(&self, db: &impl db::DefDatabase) -> ModuleId { - self.container.module(db) - } -} - -impl HasModule for TypeAliasLoc { - fn module(&self, db: &impl db::DefDatabase) -> ModuleId { - self.container.module(db) - } -} - -impl HasModule for ConstLoc { +impl HasModule for AssocItemLoc { fn module(&self, db: &impl db::DefDatabase) -> ModuleId { self.container.module(db) } diff --git a/crates/ra_hir_def/src/src.rs b/crates/ra_hir_def/src/src.rs index 20200d1db..499375b80 100644 --- a/crates/ra_hir_def/src/src.rs +++ b/crates/ra_hir_def/src/src.rs @@ -2,94 +2,28 @@ use hir_expand::InFile; use ra_arena::map::ArenaMap; -use ra_syntax::ast; +use ra_syntax::AstNode; -use crate::{ - db::DefDatabase, ConstLoc, EnumLoc, FunctionLoc, ImplLoc, StaticLoc, StructLoc, TraitLoc, - TypeAliasLoc, UnionLoc, -}; +use crate::{db::DefDatabase, AssocItemLoc, ItemLoc}; pub trait HasSource { type Value; fn source(&self, db: &impl DefDatabase) -> InFile; } -impl HasSource for FunctionLoc { - type Value = ast::FnDef; +impl HasSource for AssocItemLoc { + type Value = N; - fn source(&self, db: &impl DefDatabase) -> InFile { + fn source(&self, db: &impl DefDatabase) -> InFile { let node = self.ast_id.to_node(db); InFile::new(self.ast_id.file_id, node) } } -impl HasSource for TypeAliasLoc { - type Value = ast::TypeAliasDef; +impl HasSource for ItemLoc { + type Value = N; - fn source(&self, db: &impl DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for ConstLoc { - type Value = ast::ConstDef; - - fn source(&self, db: &impl DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for StaticLoc { - type Value = ast::StaticDef; - - fn source(&self, db: &impl DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for ImplLoc { - type Value = ast::ImplBlock; - - fn source(&self, db: &impl DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for TraitLoc { - type Value = ast::TraitDef; - - fn source(&self, db: &impl DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for StructLoc { - type Value = ast::StructDef; - - fn source(&self, db: &impl DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for UnionLoc { - type Value = ast::UnionDef; - - fn source(&self, db: &impl DefDatabase) -> InFile { - let node = self.ast_id.to_node(db); - InFile::new(self.ast_id.file_id, node) - } -} - -impl HasSource for EnumLoc { - type Value = ast::EnumDef; - - fn source(&self, db: &impl DefDatabase) -> InFile { + fn source(&self, db: &impl DefDatabase) -> InFile { let node = self.ast_id.to_node(db); InFile::new(self.ast_id.file_id, node) } -- cgit v1.2.3 From 3d4b48e481da35f19366514c0e22ed42fef037a0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 14:47:01 +0100 Subject: Fix resolve for field init shorthand --- crates/ra_hir_def/src/body.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 92c32b080..401fe0b9b 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -229,6 +229,11 @@ impl BodySourceMap { self.expr_map.get(&src).cloned() } + pub fn field_init_shorthand_expr(&self, node: InFile<&ast::RecordField>) -> Option { + let src = node.map(|it| Either::Right(AstPtr::new(it))); + self.expr_map.get(&src).cloned() + } + pub fn pat_syntax(&self, pat: PatId) -> Option { self.pat_map_back.get(pat).copied() } -- cgit v1.2.3 From 794bbab70dfd009178adf03bd82a30dc569ecde6 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 15:26:19 +0100 Subject: Remove code that never was alive? --- crates/ra_hir_def/src/nameres.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 9aae7e48e..af52fa36e 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -57,9 +57,7 @@ mod tests; use std::sync::Arc; -use hir_expand::{ - ast_id_map::FileAstId, diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId, -}; +use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId}; use once_cell::sync::Lazy; use ra_arena::Arena; use ra_db::{CrateId, Edition, FileId, FilePosition}; @@ -76,7 +74,7 @@ use crate::{ nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, path::ModPath, per_ns::PerNs, - AstId, FunctionId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, + AstId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, }; /// Contains all top-level defs from a macro-expanded crate @@ -176,11 +174,6 @@ pub struct ModuleData { pub impls: Vec, } -#[derive(Default, Debug, PartialEq, Eq)] -pub(crate) struct Declarations { - fns: FxHashMap, FunctionId>, -} - #[derive(Debug, Default, PartialEq, Eq)] pub struct ModuleScope { items: FxHashMap, -- cgit v1.2.3 From 49aac9ef63bf11827fca48c16b820ee1c3fe327f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 15:38:17 +0100 Subject: Add item_scope module --- crates/ra_hir_def/src/item_scope.rs | 1 + crates/ra_hir_def/src/lib.rs | 1 + 2 files changed, 2 insertions(+) create mode 100644 crates/ra_hir_def/src/item_scope.rs (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/crates/ra_hir_def/src/item_scope.rs @@ -0,0 +1 @@ + diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 8ed1599ff..bf8d6d1d4 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -15,6 +15,7 @@ pub mod type_ref; pub mod builtin_type; pub mod diagnostics; pub mod per_ns; +pub mod item_scope; pub mod dyn_map; pub mod keys; -- cgit v1.2.3 From 0f212b379811dcb26cde3eba160e07a11182fc5a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 15:43:45 +0100 Subject: Move ModuleScope to a new module --- crates/ra_hir_def/src/body.rs | 3 +- crates/ra_hir_def/src/item_scope.rs | 105 ++++++++++++++++++++++++++++ crates/ra_hir_def/src/nameres.rs | 108 +---------------------------- crates/ra_hir_def/src/nameres/collector.rs | 3 +- crates/ra_hir_def/src/resolver.rs | 3 +- 5 files changed, 114 insertions(+), 108 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 401fe0b9b..d9ce6bcff 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -17,7 +17,8 @@ use rustc_hash::FxHashMap; use crate::{ db::DefDatabase, expr::{Expr, ExprId, Pat, PatId}, - nameres::{BuiltinShadowMode, CrateDefMap}, + item_scope::BuiltinShadowMode, + nameres::CrateDefMap, path::{ModPath, Path}, src::HasSource, DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 8b1378917..62e7a02cb 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -1 +1,106 @@ +use hir_expand::name::Name; +use once_cell::sync::Lazy; +use rustc_hash::FxHashMap; +use crate::{per_ns::PerNs, BuiltinType, LocalImportId, MacroDefId, ModuleDefId, TraitId}; + +#[derive(Debug, Default, PartialEq, Eq)] +pub struct ModuleScope { + pub(crate) items: FxHashMap, + /// Macros visable in current module in legacy textual scope + /// + /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first. + /// If it yields no result, then it turns to module scoped `macros`. + /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped, + /// and only normal scoped `macros` will be searched in. + /// + /// Note that this automatically inherit macros defined textually before the definition of module itself. + /// + /// Module scoped macros will be inserted into `items` instead of here. + // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will + // be all resolved to the last one defined if shadowing happens. + pub(crate) legacy_macros: FxHashMap, +} + +static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { + BuiltinType::ALL + .iter() + .map(|(name, ty)| { + (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None }) + }) + .collect() +}); + +/// Shadow mode for builtin type which can be shadowed by module. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum BuiltinShadowMode { + // Prefer Module + Module, + // Prefer Other Types + Other, +} + +/// Legacy macros can only be accessed through special methods like `get_legacy_macros`. +/// Other methods will only resolve values, types and module scoped macros only. +impl ModuleScope { + pub fn entries<'a>(&'a self) -> impl Iterator + 'a { + //FIXME: shadowing + self.items.iter().chain(BUILTIN_SCOPE.iter()) + } + + pub fn declarations(&self) -> impl Iterator + '_ { + self.entries() + .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) + .flat_map(|per_ns| { + per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) + }) + } + + /// Iterate over all module scoped macros + pub fn macros<'a>(&'a self) -> impl Iterator + 'a { + self.items + .iter() + .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_))) + } + + /// Iterate over all legacy textual scoped macros visable at the end of the module + pub fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { + self.legacy_macros.iter().map(|(name, def)| (name, *def)) + } + + /// Get a name from current module scope, legacy macros are not included + pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> { + match shadow { + BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)), + BuiltinShadowMode::Other => { + let item = self.items.get(name); + if let Some(res) = item { + if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() { + return BUILTIN_SCOPE.get(name).or(item); + } + } + + item.or_else(|| BUILTIN_SCOPE.get(name)) + } + } + } + + pub fn traits<'a>(&'a self) -> impl Iterator + 'a { + self.items.values().filter_map(|r| match r.def.take_types() { + Some(ModuleDefId::TraitId(t)) => Some(t), + _ => None, + }) + } + + pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option { + self.legacy_macros.get(name).copied() + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct Resolution { + /// None for unresolved + pub def: PerNs, + /// ident by which this is imported into local scope. + pub import: Option, +} diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index af52fa36e..0b486ce16 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -57,8 +57,7 @@ mod tests; use std::sync::Arc; -use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile, MacroDefId}; -use once_cell::sync::Lazy; +use hir_expand::{diagnostics::DiagnosticSink, name::Name, InFile}; use ra_arena::Arena; use ra_db::{CrateId, Edition, FileId, FilePosition}; use ra_prof::profile; @@ -69,12 +68,12 @@ use ra_syntax::{ use rustc_hash::FxHashMap; use crate::{ - builtin_type::BuiltinType, db::DefDatabase, + item_scope::{BuiltinShadowMode, ModuleScope}, nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, path::ModPath, per_ns::PerNs, - AstId, ImplId, LocalImportId, LocalModuleId, ModuleDefId, ModuleId, TraitId, + AstId, ImplId, LocalModuleId, ModuleDefId, ModuleId, }; /// Contains all top-level defs from a macro-expanded crate @@ -174,107 +173,6 @@ pub struct ModuleData { pub impls: Vec, } -#[derive(Debug, Default, PartialEq, Eq)] -pub struct ModuleScope { - items: FxHashMap, - /// Macros visable in current module in legacy textual scope - /// - /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first. - /// If it yields no result, then it turns to module scoped `macros`. - /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped, - /// and only normal scoped `macros` will be searched in. - /// - /// Note that this automatically inherit macros defined textually before the definition of module itself. - /// - /// Module scoped macros will be inserted into `items` instead of here. - // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will - // be all resolved to the last one defined if shadowing happens. - legacy_macros: FxHashMap, -} - -static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { - BuiltinType::ALL - .iter() - .map(|(name, ty)| { - (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None }) - }) - .collect() -}); - -/// Shadow mode for builtin type which can be shadowed by module. -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum BuiltinShadowMode { - // Prefer Module - Module, - // Prefer Other Types - Other, -} - -/// Legacy macros can only be accessed through special methods like `get_legacy_macros`. -/// Other methods will only resolve values, types and module scoped macros only. -impl ModuleScope { - pub fn entries<'a>(&'a self) -> impl Iterator + 'a { - //FIXME: shadowing - self.items.iter().chain(BUILTIN_SCOPE.iter()) - } - - pub fn declarations(&self) -> impl Iterator + '_ { - self.entries() - .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) - .flat_map(|per_ns| { - per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) - }) - } - - /// Iterate over all module scoped macros - pub fn macros<'a>(&'a self) -> impl Iterator + 'a { - self.items - .iter() - .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_))) - } - - /// Iterate over all legacy textual scoped macros visable at the end of the module - pub fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { - self.legacy_macros.iter().map(|(name, def)| (name, *def)) - } - - /// Get a name from current module scope, legacy macros are not included - pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> { - match shadow { - BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)), - BuiltinShadowMode::Other => { - let item = self.items.get(name); - if let Some(res) = item { - if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() { - return BUILTIN_SCOPE.get(name).or(item); - } - } - - item.or_else(|| BUILTIN_SCOPE.get(name)) - } - } - } - - pub fn traits<'a>(&'a self) -> impl Iterator + 'a { - self.items.values().filter_map(|r| match r.def.take_types() { - Some(ModuleDefId::TraitId(t)) => Some(t), - _ => None, - }) - } - - fn get_legacy_macro(&self, name: &Name) -> Option { - self.legacy_macros.get(name).copied() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct Resolution { - /// None for unresolved - pub def: PerNs, - /// ident by which this is imported into local scope. - pub import: Option, -} - impl CrateDefMap { pub(crate) fn crate_def_map_query( // Note that this doesn't have `+ AstDatabase`! diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index e68bf4868..ea6ce5f97 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -18,9 +18,10 @@ use test_utils::tested_by; use crate::{ attr::Attrs, db::DefDatabase, + item_scope::Resolution, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, - raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, Resolution, ResolveMode, + raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, }, path::{ModPath, PathKind}, per_ns::PerNs, diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index af9d194f8..83013fed3 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -14,7 +14,8 @@ use crate::{ db::DefDatabase, expr::{ExprId, PatId}, generics::GenericParams, - nameres::{BuiltinShadowMode, CrateDefMap}, + item_scope::BuiltinShadowMode, + nameres::CrateDefMap, path::{ModPath, PathKind}, per_ns::PerNs, AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId, -- cgit v1.2.3 From 16ac792f483035f9d9bf6a61b0aefccbdf002188 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 15:44:40 +0100 Subject: Docs --- crates/ra_hir_def/src/item_scope.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 62e7a02cb..3c042a94e 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -1,3 +1,6 @@ +//! Describes items defined or visible (ie, imported) in a certain scope. +//! This is shared between modules and blocks. + use hir_expand::name::Name; use once_cell::sync::Lazy; use rustc_hash::FxHashMap; @@ -7,11 +10,11 @@ use crate::{per_ns::PerNs, BuiltinType, LocalImportId, MacroDefId, ModuleDefId, #[derive(Debug, Default, PartialEq, Eq)] pub struct ModuleScope { pub(crate) items: FxHashMap, - /// Macros visable in current module in legacy textual scope + /// Macros visible in current module in legacy textual scope /// - /// For macros invoked by an unquatified identifier like `bar!()`, `legacy_macros` will be searched in first. + /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first. /// If it yields no result, then it turns to module scoped `macros`. - /// It macros with name quatified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped, + /// It macros with name qualified with a path like `crate::foo::bar!()`, `legacy_macros` will be skipped, /// and only normal scoped `macros` will be searched in. /// /// Note that this automatically inherit macros defined textually before the definition of module itself. -- cgit v1.2.3 From 2ce1aa32c40e68ea905c83c315bddfcdd1b7ae26 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 15:45:12 +0100 Subject: Rename ModuleScope -> ItemScope --- crates/ra_hir_def/src/item_scope.rs | 4 ++-- crates/ra_hir_def/src/nameres.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 3c042a94e..62c878313 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -8,7 +8,7 @@ use rustc_hash::FxHashMap; use crate::{per_ns::PerNs, BuiltinType, LocalImportId, MacroDefId, ModuleDefId, TraitId}; #[derive(Debug, Default, PartialEq, Eq)] -pub struct ModuleScope { +pub struct ItemScope { pub(crate) items: FxHashMap, /// Macros visible in current module in legacy textual scope /// @@ -45,7 +45,7 @@ pub enum BuiltinShadowMode { /// Legacy macros can only be accessed through special methods like `get_legacy_macros`. /// Other methods will only resolve values, types and module scoped macros only. -impl ModuleScope { +impl ItemScope { pub fn entries<'a>(&'a self) -> impl Iterator + 'a { //FIXME: shadowing self.items.iter().chain(BUILTIN_SCOPE.iter()) diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 0b486ce16..3b318719e 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -69,7 +69,7 @@ use rustc_hash::FxHashMap; use crate::{ db::DefDatabase, - item_scope::{BuiltinShadowMode, ModuleScope}, + item_scope::{BuiltinShadowMode, ItemScope}, nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, path::ModPath, per_ns::PerNs, @@ -165,7 +165,7 @@ impl ModuleOrigin { pub struct ModuleData { pub parent: Option, pub children: FxHashMap, - pub scope: ModuleScope, + pub scope: ItemScope, /// Where does this module come from? pub origin: ModuleOrigin, -- cgit v1.2.3 From 030e540ad19046e2037981ec8e15a6800b86bbe9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 15:51:43 +0100 Subject: Reduce visibility --- crates/ra_hir_def/src/item_scope.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 62c878313..996d06db6 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -36,7 +36,7 @@ static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { /// Shadow mode for builtin type which can be shadowed by module. #[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum BuiltinShadowMode { +pub(crate) enum BuiltinShadowMode { // Prefer Module Module, // Prefer Other Types @@ -60,19 +60,19 @@ impl ItemScope { } /// Iterate over all module scoped macros - pub fn macros<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn macros<'a>(&'a self) -> impl Iterator + 'a { self.items .iter() .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_))) } - /// Iterate over all legacy textual scoped macros visable at the end of the module - pub fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { + /// Iterate over all legacy textual scoped macros visible at the end of the module + pub(crate) fn legacy_macros<'a>(&'a self) -> impl Iterator + 'a { self.legacy_macros.iter().map(|(name, def)| (name, *def)) } /// Get a name from current module scope, legacy macros are not included - pub fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> { + pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> { match shadow { BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)), BuiltinShadowMode::Other => { @@ -88,7 +88,7 @@ impl ItemScope { } } - pub fn traits<'a>(&'a self) -> impl Iterator + 'a { + pub(crate) fn traits<'a>(&'a self) -> impl Iterator + 'a { self.items.values().filter_map(|r| match r.def.take_types() { Some(ModuleDefId::TraitId(t)) => Some(t), _ => None, -- cgit v1.2.3 From 1b8ce5b37b597679796b3ebc57afd55af49449b0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 15:58:20 +0100 Subject: Move impls to ItemScope --- crates/ra_hir_def/src/child_by_source.rs | 2 +- crates/ra_hir_def/src/item_scope.rs | 7 ++++++- crates/ra_hir_def/src/lang_item.rs | 2 +- crates/ra_hir_def/src/nameres.rs | 4 +--- crates/ra_hir_def/src/nameres/collector.rs | 2 +- crates/ra_hir_def/src/nameres/tests/macros.rs | 4 ++-- 6 files changed, 12 insertions(+), 9 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index f5a65ad40..403ba8b57 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -80,7 +80,7 @@ impl ChildBySource for ModuleId { module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); - for &impl_ in module_data.impls.iter() { + for &impl_ in module_data.scope.impls.iter() { let src = impl_.lookup(db).source(db); res[keys::IMPL].insert(src, impl_) } diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 996d06db6..93e579bb0 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -5,11 +5,12 @@ use hir_expand::name::Name; use once_cell::sync::Lazy; use rustc_hash::FxHashMap; -use crate::{per_ns::PerNs, BuiltinType, LocalImportId, MacroDefId, ModuleDefId, TraitId}; +use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId}; #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { pub(crate) items: FxHashMap, + pub(crate) impls: Vec, /// Macros visible in current module in legacy textual scope /// /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first. @@ -59,6 +60,10 @@ impl ItemScope { }) } + pub fn impls(&self) -> impl Iterator + ExactSizeIterator + '_ { + self.impls.iter().copied() + } + /// Iterate over all module scoped macros pub(crate) fn macros<'a>(&'a self) -> impl Iterator + 'a { self.items diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index f4fdbdcfc..61b248815 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs @@ -81,7 +81,7 @@ impl LangItems { // Look for impl targets let def_map = db.crate_def_map(module.krate); let module_data = &def_map[module.local_id]; - for &impl_block in module_data.impls.iter() { + for &impl_block in module_data.scope.impls.iter() { self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId) } diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs index 3b318719e..5d4ca73a3 100644 --- a/crates/ra_hir_def/src/nameres.rs +++ b/crates/ra_hir_def/src/nameres.rs @@ -73,7 +73,7 @@ use crate::{ nameres::{diagnostics::DefDiagnostic, path_resolution::ResolveMode}, path::ModPath, per_ns::PerNs, - AstId, ImplId, LocalModuleId, ModuleDefId, ModuleId, + AstId, LocalModuleId, ModuleDefId, ModuleId, }; /// Contains all top-level defs from a macro-expanded crate @@ -169,8 +169,6 @@ pub struct ModuleData { /// Where does this module come from? pub origin: ModuleOrigin, - - pub impls: Vec, } impl CrateDefMap { diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index ea6ce5f97..c4f6bcd95 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -667,7 +667,7 @@ where let impl_id = ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db); - self.def_collector.def_map.modules[self.module_id].impls.push(impl_id) + self.def_collector.def_map.modules[self.module_id].scope.impls.push(impl_id) } } } diff --git a/crates/ra_hir_def/src/nameres/tests/macros.rs b/crates/ra_hir_def/src/nameres/tests/macros.rs index cfa4ecb1a..d104f5993 100644 --- a/crates/ra_hir_def/src/nameres/tests/macros.rs +++ b/crates/ra_hir_def/src/nameres/tests/macros.rs @@ -610,7 +610,7 @@ fn expand_derive() { struct Foo; ", ); - assert_eq!(map.modules[map.root].impls.len(), 1); + assert_eq!(map.modules[map.root].scope.impls().len(), 1); } #[test] @@ -622,5 +622,5 @@ fn expand_multiple_derive() { struct Foo; ", ); - assert_eq!(map.modules[map.root].impls.len(), 2); + assert_eq!(map.modules[map.root].scope.impls().len(), 2); } -- cgit v1.2.3 From 4f9e3f3632f3c03d44a23daf0d9ce4966816af86 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 16:19:28 +0100 Subject: Fix typos --- crates/ra_hir_def/src/nameres/collector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index c4f6bcd95..17c7e691e 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -226,10 +226,10 @@ where /// Define a legacy textual scoped macro in module /// - /// We use a map `legacy_macros` to store all legacy textual scoped macros visable per module. + /// We use a map `legacy_macros` to store all legacy textual scoped macros visible per module. /// It will clone all macros from parent legacy scope, whose definition is prior to /// the definition of current module. - /// And also, `macro_use` on a module will import all legacy macros visable inside to + /// And also, `macro_use` on a module will import all legacy macros visible inside to /// current legacy scope, with possible shadowing. fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, macro_: MacroDefId) { // Always shadowing -- cgit v1.2.3 From e6b1194f2f33722f0cfed32465f778b256162626 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 16:26:49 +0100 Subject: Move some code to scope --- crates/ra_hir_def/src/item_scope.rs | 35 ++++++++++++++++++++++++++++++ crates/ra_hir_def/src/nameres/collector.rs | 28 ++---------------------- 2 files changed, 37 insertions(+), 26 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 93e579bb0..f4fb768cd 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -47,6 +47,41 @@ pub(crate) enum BuiltinShadowMode { /// Legacy macros can only be accessed through special methods like `get_legacy_macros`. /// Other methods will only resolve values, types and module scoped macros only. impl ItemScope { + pub fn push_res( + &mut self, + name: Name, + res: &Resolution, + import: Option, + ) -> bool { + let mut changed = false; + let existing = self.items.entry(name.clone()).or_default(); + + if existing.def.types.is_none() && res.def.types.is_some() { + existing.def.types = res.def.types; + existing.import = import.or(res.import); + changed = true; + } + if existing.def.values.is_none() && res.def.values.is_some() { + existing.def.values = res.def.values; + existing.import = import.or(res.import); + changed = true; + } + if existing.def.macros.is_none() && res.def.macros.is_some() { + existing.def.macros = res.def.macros; + existing.import = import.or(res.import); + changed = true; + } + + if existing.def.is_none() + && res.def.is_none() + && existing.import.is_none() + && res.import.is_some() + { + existing.import = res.import; + } + changed + } + pub fn entries<'a>(&'a self) -> impl Iterator + 'a { //FIXME: shadowing self.items.iter().chain(BUILTIN_SCOPE.iter()) diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 17c7e691e..95c499ec9 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -467,34 +467,10 @@ where // prevent stack overflows (but this shouldn't be possible) panic!("infinite recursion in glob imports!"); } - let module_items = &mut self.def_map.modules[module_id].scope; + let scope = &mut self.def_map.modules[module_id].scope; let mut changed = false; for (name, res) in resolutions { - let existing = module_items.items.entry(name.clone()).or_default(); - - if existing.def.types.is_none() && res.def.types.is_some() { - existing.def.types = res.def.types; - existing.import = import.or(res.import); - changed = true; - } - if existing.def.values.is_none() && res.def.values.is_some() { - existing.def.values = res.def.values; - existing.import = import.or(res.import); - changed = true; - } - if existing.def.macros.is_none() && res.def.macros.is_some() { - existing.def.macros = res.def.macros; - existing.import = import.or(res.import); - changed = true; - } - - if existing.def.is_none() - && res.def.is_none() - && existing.import.is_none() - && res.import.is_some() - { - existing.import = res.import; - } + changed |= scope.push_res(name.clone(), res, import); } if !changed { -- cgit v1.2.3 From 7adb53319d963d0a40906a6847124974da1d5183 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 16:47:22 +0100 Subject: Make items private --- crates/ra_hir_def/src/item_scope.rs | 76 ++++++++++++++++-------------- crates/ra_hir_def/src/nameres/collector.rs | 12 +---- 2 files changed, 42 insertions(+), 46 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index f4fb768cd..ac56986cd 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -9,7 +9,7 @@ use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, Modul #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { - pub(crate) items: FxHashMap, + items: FxHashMap, pub(crate) impls: Vec, /// Macros visible in current module in legacy textual scope /// @@ -47,41 +47,6 @@ pub(crate) enum BuiltinShadowMode { /// Legacy macros can only be accessed through special methods like `get_legacy_macros`. /// Other methods will only resolve values, types and module scoped macros only. impl ItemScope { - pub fn push_res( - &mut self, - name: Name, - res: &Resolution, - import: Option, - ) -> bool { - let mut changed = false; - let existing = self.items.entry(name.clone()).or_default(); - - if existing.def.types.is_none() && res.def.types.is_some() { - existing.def.types = res.def.types; - existing.import = import.or(res.import); - changed = true; - } - if existing.def.values.is_none() && res.def.values.is_some() { - existing.def.values = res.def.values; - existing.import = import.or(res.import); - changed = true; - } - if existing.def.macros.is_none() && res.def.macros.is_some() { - existing.def.macros = res.def.macros; - existing.import = import.or(res.import); - changed = true; - } - - if existing.def.is_none() - && res.def.is_none() - && existing.import.is_none() - && res.import.is_some() - { - existing.import = res.import; - } - changed - } - pub fn entries<'a>(&'a self) -> impl Iterator + 'a { //FIXME: shadowing self.items.iter().chain(BUILTIN_SCOPE.iter()) @@ -138,6 +103,45 @@ impl ItemScope { pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option { self.legacy_macros.get(name).copied() } + + pub(crate) fn push_res( + &mut self, + name: Name, + res: &Resolution, + import: Option, + ) -> bool { + let mut changed = false; + let existing = self.items.entry(name.clone()).or_default(); + + if existing.def.types.is_none() && res.def.types.is_some() { + existing.def.types = res.def.types; + existing.import = import.or(res.import); + changed = true; + } + if existing.def.values.is_none() && res.def.values.is_some() { + existing.def.values = res.def.values; + existing.import = import.or(res.import); + changed = true; + } + if existing.def.macros.is_none() && res.def.macros.is_some() { + existing.def.macros = res.def.macros; + existing.import = import.or(res.import); + changed = true; + } + + if existing.def.is_none() + && res.def.is_none() + && existing.import.is_none() + && res.import.is_some() + { + existing.import = res.import; + } + changed + } + + pub(crate) fn collect_resolutions(&self) -> Vec<(Name, Resolution)> { + self.items.iter().map(|(name, res)| (name.clone(), res.clone())).collect() + } } #[derive(Debug, Clone, PartialEq, Eq, Default)] diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 95c499ec9..d62fae8a6 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -372,11 +372,7 @@ where let scope = &item_map[m.local_id].scope; // Module scoped macros is included - let items = scope - .items - .iter() - .map(|(name, res)| (name.clone(), res.clone())) - .collect::>(); + let items = scope.collect_resolutions(); self.update(module_id, Some(import_id), &items); } else { @@ -386,11 +382,7 @@ where let scope = &self.def_map[m.local_id].scope; // Module scoped macros is included - let items = scope - .items - .iter() - .map(|(name, res)| (name.clone(), res.clone())) - .collect::>(); + let items = scope.collect_resolutions(); self.update(module_id, Some(import_id), &items); // record the glob import in case we add further items -- cgit v1.2.3 From af42cb5981a1f94116b1da8cfeedb6efdd5aeb01 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 16:55:38 +0100 Subject: Privitize impls --- crates/ra_hir_def/src/child_by_source.rs | 6 +++--- crates/ra_hir_def/src/item_scope.rs | 6 +++++- crates/ra_hir_def/src/lang_item.rs | 2 +- crates/ra_hir_def/src/nameres/collector.rs | 4 +++- 4 files changed, 12 insertions(+), 6 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 403ba8b57..4488e8502 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -80,9 +80,9 @@ impl ChildBySource for ModuleId { module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); - for &impl_ in module_data.scope.impls.iter() { - let src = impl_.lookup(db).source(db); - res[keys::IMPL].insert(src, impl_) + for imp in module_data.scope.impls() { + let src = imp.lookup(db).source(db); + res[keys::IMPL].insert(src, imp) } res diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index ac56986cd..f51e97ef9 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -10,7 +10,7 @@ use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, Modul #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { items: FxHashMap, - pub(crate) impls: Vec, + impls: Vec, /// Macros visible in current module in legacy textual scope /// /// For macros invoked by an unqualified identifier like `bar!()`, `legacy_macros` will be searched in first. @@ -104,6 +104,10 @@ impl ItemScope { self.legacy_macros.get(name).copied() } + pub(crate) fn define_impl(&mut self, imp: ImplId) { + self.impls.push(imp) + } + pub(crate) fn push_res( &mut self, name: Name, diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index 61b248815..cef061837 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs @@ -81,7 +81,7 @@ impl LangItems { // Look for impl targets let def_map = db.crate_def_map(module.krate); let module_data = &def_map[module.local_id]; - for &impl_block in module_data.scope.impls.iter() { + for impl_block in module_data.scope.impls() { self.collect_lang_item(db, impl_block, LangItemTarget::ImplBlockId) } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index d62fae8a6..b064ccc9c 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -635,7 +635,9 @@ where let impl_id = ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) } .intern(self.def_collector.db); - self.def_collector.def_map.modules[self.module_id].scope.impls.push(impl_id) + self.def_collector.def_map.modules[self.module_id] + .scope + .define_impl(impl_id) } } } -- cgit v1.2.3 From 7a862f0d47e8ae018d449a04c918ea3705785552 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 17:09:13 +0100 Subject: Make legacy macros private --- crates/ra_hir_def/src/item_scope.rs | 10 +++++++++- crates/ra_hir_def/src/nameres/collector.rs | 10 ++++++---- crates/ra_hir_def/src/nameres/tests.rs | 19 +++++++------------ crates/ra_hir_def/src/nameres/tests/incremental.rs | 4 ++-- 4 files changed, 24 insertions(+), 19 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index f51e97ef9..6b9be8325 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -23,7 +23,7 @@ pub struct ItemScope { /// Module scoped macros will be inserted into `items` instead of here. // FIXME: Macro shadowing in one module is not properly handled. Non-item place macros will // be all resolved to the last one defined if shadowing happens. - pub(crate) legacy_macros: FxHashMap, + legacy_macros: FxHashMap, } static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { @@ -108,6 +108,10 @@ impl ItemScope { self.impls.push(imp) } + pub(crate) fn define_legacy_macro(&mut self, name: Name, mac: MacroDefId) { + self.legacy_macros.insert(name, mac); + } + pub(crate) fn push_res( &mut self, name: Name, @@ -146,6 +150,10 @@ impl ItemScope { pub(crate) fn collect_resolutions(&self) -> Vec<(Name, Resolution)> { self.items.iter().map(|(name, res)| (name.clone(), res.clone())).collect() } + + pub(crate) fn collect_legacy_macros(&self) -> FxHashMap { + self.legacy_macros.clone() + } } #[derive(Debug, Clone, PartialEq, Eq, Default)] diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index b064ccc9c..8b641d8b5 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -231,9 +231,9 @@ where /// the definition of current module. /// And also, `macro_use` on a module will import all legacy macros visible inside to /// current legacy scope, with possible shadowing. - fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, macro_: MacroDefId) { + fn define_legacy_macro(&mut self, module_id: LocalModuleId, name: Name, mac: MacroDefId) { // Always shadowing - self.def_map.modules[module_id].scope.legacy_macros.insert(name, macro_); + self.def_map.modules[module_id].scope.define_legacy_macro(name, mac); } /// Import macros from `#[macro_use] extern crate`. @@ -711,7 +711,9 @@ where let res = modules.alloc(ModuleData::default()); modules[res].parent = Some(self.module_id); modules[res].origin = ModuleOrigin::not_sure_file(definition, declaration); - modules[res].scope.legacy_macros = modules[self.module_id].scope.legacy_macros.clone(); + for (name, mac) in modules[self.module_id].scope.collect_legacy_macros() { + modules[res].scope.define_legacy_macro(name, mac) + } modules[self.module_id].children.insert(name.clone(), res); let resolution = Resolution { def: PerNs::types( @@ -875,7 +877,7 @@ where } fn import_all_legacy_macros(&mut self, module_id: LocalModuleId) { - let macros = self.def_collector.def_map[module_id].scope.legacy_macros.clone(); + let macros = self.def_collector.def_map[module_id].scope.collect_legacy_macros(); for (name, macro_) in macros { self.def_collector.define_legacy_macro(self.module_id, name.clone(), macro_); } diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 61cdd768e..4e968bcc8 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -32,27 +32,22 @@ fn render_crate_def_map(map: &CrateDefMap) -> String { *buf += path; *buf += "\n"; - let mut entries = map.modules[module] - .scope - .items - .iter() - .map(|(name, res)| (name, res.def)) - .collect::>(); - entries.sort_by_key(|(name, _)| *name); + let mut entries = map.modules[module].scope.collect_resolutions(); + entries.sort_by_key(|(name, _)| name.clone()); for (name, res) in entries { *buf += &format!("{}:", name); - if res.types.is_some() { + if res.def.types.is_some() { *buf += " t"; } - if res.values.is_some() { + if res.def.values.is_some() { *buf += " v"; } - if res.macros.is_some() { + if res.def.macros.is_some() { *buf += " m"; } - if res.is_none() { + if res.def.is_none() { *buf += " _"; } @@ -587,6 +582,6 @@ mod b { â‹®T: v â‹® â‹®crate::a - â‹®T: t v + â‹®T: t v "###); } diff --git a/crates/ra_hir_def/src/nameres/tests/incremental.rs b/crates/ra_hir_def/src/nameres/tests/incremental.rs index 903a22771..ef2e9435c 100644 --- a/crates/ra_hir_def/src/nameres/tests/incremental.rs +++ b/crates/ra_hir_def/src/nameres/tests/incremental.rs @@ -116,7 +116,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() { let events = db.log_executed(|| { let crate_def_map = db.crate_def_map(krate); let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); - assert_eq!(module_data.scope.items.len(), 1); + assert_eq!(module_data.scope.collect_resolutions().len(), 1); }); assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) } @@ -126,7 +126,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() { let events = db.log_executed(|| { let crate_def_map = db.crate_def_map(krate); let (_, module_data) = crate_def_map.modules.iter().last().unwrap(); - assert_eq!(module_data.scope.items.len(), 1); + assert_eq!(module_data.scope.collect_resolutions().len(), 1); }); assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) } -- cgit v1.2.3 From 2a8c9100bfb1294a469bc039a5b9597eabed7073 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 20 Dec 2019 16:41:32 +0100 Subject: Handle closure return types Fixes #2547. --- crates/ra_hir_def/src/body/lower.rs | 3 ++- crates/ra_hir_def/src/expr.rs | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 853e17bae..be5d17d85 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -372,8 +372,9 @@ where arg_types.push(type_ref); } } + let ret_type = e.ret_type().and_then(|r| r.type_ref()).map(TypeRef::from_ast); let body = self.collect_expr_opt(e.body()); - self.alloc_expr(Expr::Lambda { args, arg_types, body }, syntax_ptr) + self.alloc_expr(Expr::Lambda { args, arg_types, ret_type, body }, syntax_ptr) } ast::Expr::BinExpr(e) => { let lhs = self.collect_expr_opt(e.lhs()); diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs index 6fad80a8d..a75ef9970 100644 --- a/crates/ra_hir_def/src/expr.rs +++ b/crates/ra_hir_def/src/expr.rs @@ -143,6 +143,7 @@ pub enum Expr { Lambda { args: Vec, arg_types: Vec>, + ret_type: Option, body: ExprId, }, Tuple { -- cgit v1.2.3 From f5947be0ea6eb909cbb63420c3304adedf470b26 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 20 Dec 2019 20:15:54 +0100 Subject: Simplify --- crates/ra_hir_def/src/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/path.rs b/crates/ra_hir_def/src/path.rs index 00325cd99..8e1294201 100644 --- a/crates/ra_hir_def/src/path.rs +++ b/crates/ra_hir_def/src/path.rs @@ -135,7 +135,7 @@ impl Path { } pub fn type_anchor(&self) -> Option<&TypeRef> { - self.type_anchor.as_ref().map(|it| &**it) + self.type_anchor.as_deref() } pub fn segments(&self) -> PathSegments<'_> { -- cgit v1.2.3 From ad81d1dbc19803b5ccf1b230237642944edbff13 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 21 Dec 2019 03:37:03 +0800 Subject: Add support macros in impl blocks --- crates/ra_hir_def/src/body.rs | 22 ++++---- crates/ra_hir_def/src/data.rs | 119 ++++++++++++++++++++++++++++-------------- crates/ra_hir_def/src/lib.rs | 1 + 3 files changed, 94 insertions(+), 48 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 401fe0b9b..a92c01f86 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -23,7 +23,7 @@ use crate::{ DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, }; -struct Expander { +pub(crate) struct Expander { crate_def_map: Arc, current_file_id: HirFileId, hygiene: Hygiene, @@ -32,18 +32,22 @@ struct Expander { } impl Expander { - fn new(db: &impl DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { + pub(crate) fn new( + db: &impl DefDatabase, + current_file_id: HirFileId, + module: ModuleId, + ) -> Expander { let crate_def_map = db.crate_def_map(module.krate); let hygiene = Hygiene::new(db, current_file_id); let ast_id_map = db.ast_id_map(current_file_id); Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } } - fn enter_expand( + pub(crate) fn enter_expand( &mut self, - db: &impl DefDatabase, + db: &DB, macro_call: ast::MacroCall, - ) -> Option<(Mark, ast::Expr)> { + ) -> Option<(Mark, T)> { let ast_id = AstId::new( self.current_file_id, db.ast_id_map(self.current_file_id).ast_id(¯o_call), @@ -54,7 +58,7 @@ impl Expander { let call_id = def.as_call_id(db, MacroCallKind::FnLike(ast_id)); let file_id = call_id.as_file(); if let Some(node) = db.parse_or_expand(file_id) { - if let Some(expr) = ast::Expr::cast(node) { + if let Some(expr) = T::cast(node) { log::debug!("macro expansion {:#?}", expr.syntax()); let mark = Mark { @@ -77,14 +81,14 @@ impl Expander { None } - fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) { + pub(crate) fn exit(&mut self, db: &impl DefDatabase, mut mark: Mark) { self.hygiene = Hygiene::new(db, mark.file_id); self.current_file_id = mark.file_id; self.ast_id_map = mem::take(&mut mark.ast_id_map); mark.bomb.defuse(); } - fn to_source(&self, value: T) -> InFile { + pub(crate) fn to_source(&self, value: T) -> InFile { InFile { file_id: self.current_file_id, value } } @@ -109,7 +113,7 @@ impl Expander { } } -struct Mark { +pub(crate) struct Mark { file_id: HirFileId, ast_id_map: Arc, bomb: DropBomb, diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 14e86936b..b0a3f1784 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -4,16 +4,16 @@ use std::sync::Arc; use hir_expand::{ name::{name, AsName, Name}, - AstId, + AstId, InFile, }; -use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; +use ra_syntax::ast::{self, AstNode, ImplItem, ModuleItemOwner, NameOwner, TypeAscriptionOwner}; use crate::{ db::DefDatabase, src::HasSource, type_ref::{Mutability, TypeRef}, - AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, ImplId, Intern, - Lookup, StaticId, TraitId, TypeAliasId, TypeAliasLoc, + AssocContainerId, AssocItemId, ConstId, ConstLoc, Expander, FunctionId, FunctionLoc, HasModule, + ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, }; #[derive(Debug, Clone, PartialEq, Eq)] @@ -167,46 +167,24 @@ pub struct ImplData { impl ImplData { pub(crate) fn impl_data_query(db: &impl DefDatabase, id: ImplId) -> Arc { - let src = id.lookup(db).source(db); - let items = db.ast_id_map(src.file_id); + let impl_loc = id.lookup(db); + let src = impl_loc.source(db); let target_trait = src.value.target_trait().map(TypeRef::from_ast); let target_type = TypeRef::from_ast_opt(src.value.target_type()); let is_negative = src.value.is_negative(); + let module_id = impl_loc.container.module(db); - let items = if let Some(item_list) = src.value.item_list() { - item_list - .impl_items() - .map(|item_node| match item_node { - ast::ImplItem::FnDef(it) => { - let def = FunctionLoc { - container: AssocContainerId::ImplId(id), - ast_id: AstId::new(src.file_id, items.ast_id(&it)), - } - .intern(db); - def.into() - } - ast::ImplItem::ConstDef(it) => { - let def = ConstLoc { - container: AssocContainerId::ImplId(id), - ast_id: AstId::new(src.file_id, items.ast_id(&it)), - } - .intern(db); - def.into() - } - ast::ImplItem::TypeAliasDef(it) => { - let def = TypeAliasLoc { - container: AssocContainerId::ImplId(id), - ast_id: AstId::new(src.file_id, items.ast_id(&it)), - } - .intern(db); - def.into() - } - }) - .collect() - } else { - Vec::new() - }; + let mut items = Vec::new(); + if let Some(item_list) = src.value.item_list() { + items.extend(collect_impl_items(db, item_list.impl_items(), src.file_id, id)); + items.extend(collect_impl_items_in_macros( + db, + module_id, + &src.with_value(item_list), + id, + )); + } let res = ImplData { target_trait, target_type, items, is_negative }; Arc::new(res) @@ -237,3 +215,66 @@ impl ConstData { ConstData { name, type_ref } } } + +fn collect_impl_items_in_macros( + db: &impl DefDatabase, + module_id: ModuleId, + impl_block: &InFile, + id: ImplId, +) -> Vec { + let mut expander = Expander::new(db, impl_block.file_id, module_id); + let mut res = Vec::new(); + + for m in impl_block.value.syntax().children().filter_map(ast::MacroCall::cast) { + if let Some((mark, items)) = expander.enter_expand(db, m) { + let items: InFile = expander.to_source(items); + expander.exit(db, mark); + res.extend(collect_impl_items( + db, + items.value.items().filter_map(|it| ImplItem::cast(it.syntax().clone())), + items.file_id, + id, + )); + } + } + + res +} + +fn collect_impl_items( + db: &impl DefDatabase, + impl_items: impl Iterator, + file_id: crate::HirFileId, + id: ImplId, +) -> Vec { + let items = db.ast_id_map(file_id); + + impl_items + .map(|item_node| match item_node { + ast::ImplItem::FnDef(it) => { + let def = FunctionLoc { + container: AssocContainerId::ImplId(id), + ast_id: AstId::new(file_id, items.ast_id(&it)), + } + .intern(db); + def.into() + } + ast::ImplItem::ConstDef(it) => { + let def = ConstLoc { + container: AssocContainerId::ImplId(id), + ast_id: AstId::new(file_id, items.ast_id(&it)), + } + .intern(db); + def.into() + } + ast::ImplItem::TypeAliasDef(it) => { + let def = TypeAliasLoc { + container: AssocContainerId::ImplId(id), + ast_id: AstId::new(file_id, items.ast_id(&it)), + } + .intern(db); + def.into() + } + }) + .collect() +} diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 8ed1599ff..6bb5408a8 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -47,6 +47,7 @@ use ra_arena::{impl_arena_id, RawId}; use ra_db::{impl_intern_key, salsa, CrateId}; use ra_syntax::{ast, AstNode}; +use crate::body::Expander; use crate::builtin_type::BuiltinType; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -- cgit v1.2.3 From 0d5d63a80ea08f2af439bcc72fff9b24d144c70d Mon Sep 17 00:00:00 2001 From: kjeremy Date: Fri, 20 Dec 2019 15:14:30 -0500 Subject: Clippy lints --- crates/ra_hir_def/src/nameres/collector.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index e68bf4868..3d8ca5dce 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -406,14 +406,14 @@ where let resolutions = enum_data .variants .iter() - .filter_map(|(local_id, variant_data)| { + .map(|(local_id, variant_data)| { let name = variant_data.name.clone(); let variant = EnumVariantId { parent: e, local_id }; let res = Resolution { def: PerNs::both(variant.into(), variant.into()), import: Some(import_id), }; - Some((name, res)) + (name, res) }) .collect::>(); self.update(module_id, Some(import_id), &resolutions); -- cgit v1.2.3 From 360de5ba71a631a118a088dba7c975e9ae592452 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 21 Dec 2019 05:02:31 +0800 Subject: Recursive collect macros in impl items --- crates/ra_hir_def/src/data.rs | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index b0a3f1784..6a65633ae 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -226,21 +226,39 @@ fn collect_impl_items_in_macros( let mut res = Vec::new(); for m in impl_block.value.syntax().children().filter_map(ast::MacroCall::cast) { - if let Some((mark, items)) = expander.enter_expand(db, m) { - let items: InFile = expander.to_source(items); - expander.exit(db, mark); - res.extend(collect_impl_items( - db, - items.value.items().filter_map(|it| ImplItem::cast(it.syntax().clone())), - items.file_id, - id, - )); - } + res.extend(collect_impl_items_in_macro(db, &mut expander, m, id)) } res } +fn collect_impl_items_in_macro( + db: &impl DefDatabase, + expander: &mut Expander, + m: ast::MacroCall, + id: ImplId, +) -> Vec { + if let Some((mark, items)) = expander.enter_expand(db, m) { + let items: InFile = expander.to_source(items); + let mut res = collect_impl_items( + db, + items.value.items().filter_map(|it| ImplItem::cast(it.syntax().clone())), + items.file_id, + id, + ); + // Recursive collect macros + // Note that ast::ModuleItem do not include ast::MacroCall + // We cannot use ModuleItemOwner::items here + for it in items.value.syntax().children().filter_map(ast::MacroCall::cast) { + res.extend(collect_impl_items_in_macro(db, expander, it, id)) + } + expander.exit(db, mark); + res + } else { + Vec::new() + } +} + fn collect_impl_items( db: &impl DefDatabase, impl_items: impl Iterator, -- cgit v1.2.3 From c1166697a74bca690443525ced8cd8bc08894779 Mon Sep 17 00:00:00 2001 From: Edwin Cheng Date: Sat, 21 Dec 2019 05:16:29 +0800 Subject: Add a limit for protect against infinite recursion --- crates/ra_hir_def/src/data.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 6a65633ae..1aa9a9b7d 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -225,8 +225,11 @@ fn collect_impl_items_in_macros( let mut expander = Expander::new(db, impl_block.file_id, module_id); let mut res = Vec::new(); + // We set a limit to protect against infinite recursion + let limit = 100; + for m in impl_block.value.syntax().children().filter_map(ast::MacroCall::cast) { - res.extend(collect_impl_items_in_macro(db, &mut expander, m, id)) + res.extend(collect_impl_items_in_macro(db, &mut expander, m, id, limit)) } res @@ -237,7 +240,12 @@ fn collect_impl_items_in_macro( expander: &mut Expander, m: ast::MacroCall, id: ImplId, + limit: usize, ) -> Vec { + if limit == 0 { + return Vec::new(); + } + if let Some((mark, items)) = expander.enter_expand(db, m) { let items: InFile = expander.to_source(items); let mut res = collect_impl_items( @@ -250,7 +258,7 @@ fn collect_impl_items_in_macro( // Note that ast::ModuleItem do not include ast::MacroCall // We cannot use ModuleItemOwner::items here for it in items.value.syntax().children().filter_map(ast::MacroCall::cast) { - res.extend(collect_impl_items_in_macro(db, expander, it, id)) + res.extend(collect_impl_items_in_macro(db, expander, it, id, limit - 1)) } expander.exit(db, mark); res -- cgit v1.2.3 From ab7a70fb14d281507b6e6726b47614035b073a28 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 12:38:40 +0100 Subject: Don't track imports --- crates/ra_hir_def/src/item_scope.rs | 35 ++++++++------------------- crates/ra_hir_def/src/nameres/collector.rs | 39 ++++++++++++------------------ 2 files changed, 26 insertions(+), 48 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 6b9be8325..5c14fefff 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -5,7 +5,7 @@ use hir_expand::name::Name; use once_cell::sync::Lazy; use rustc_hash::FxHashMap; -use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId}; +use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId}; #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { @@ -30,7 +30,7 @@ static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { BuiltinType::ALL .iter() .map(|(name, ty)| { - (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None }) + (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), declaration: false }) }) .collect() }); @@ -53,11 +53,9 @@ impl ItemScope { } pub fn declarations(&self) -> impl Iterator + '_ { - self.entries() - .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) - .flat_map(|per_ns| { - per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) - }) + self.entries().filter(|(_name, res)| res.declaration).flat_map(|(_name, res)| { + res.def.take_types().into_iter().chain(res.def.take_values().into_iter()) + }) } pub fn impls(&self) -> impl Iterator + ExactSizeIterator + '_ { @@ -112,38 +110,26 @@ impl ItemScope { self.legacy_macros.insert(name, mac); } - pub(crate) fn push_res( - &mut self, - name: Name, - res: &Resolution, - import: Option, - ) -> bool { + pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, declaration: bool) -> bool { let mut changed = false; let existing = self.items.entry(name.clone()).or_default(); if existing.def.types.is_none() && res.def.types.is_some() { existing.def.types = res.def.types; - existing.import = import.or(res.import); + existing.declaration |= declaration; changed = true; } if existing.def.values.is_none() && res.def.values.is_some() { existing.def.values = res.def.values; - existing.import = import.or(res.import); + existing.declaration |= declaration; changed = true; } if existing.def.macros.is_none() && res.def.macros.is_some() { existing.def.macros = res.def.macros; - existing.import = import.or(res.import); + existing.declaration |= declaration; changed = true; } - if existing.def.is_none() - && res.def.is_none() - && existing.import.is_none() - && res.import.is_some() - { - existing.import = res.import; - } changed } @@ -160,6 +146,5 @@ impl ItemScope { pub struct Resolution { /// None for unresolved pub def: PerNs, - /// ident by which this is imported into local scope. - pub import: Option, + pub declaration: bool, } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 45199fa11..e43aafedb 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -218,8 +218,7 @@ where if export { self.update( self.def_map.root, - None, - &[(name, Resolution { def: PerNs::macros(macro_), import: None })], + &[(name, Resolution { def: PerNs::macros(macro_), declaration: false })], ); } } @@ -374,7 +373,7 @@ where // Module scoped macros is included let items = scope.collect_resolutions(); - self.update(module_id, Some(import_id), &items); + self.update(module_id, &items); } else { // glob import from same crate => we do an initial // import, and then need to propagate any further @@ -384,7 +383,7 @@ where // Module scoped macros is included let items = scope.collect_resolutions(); - self.update(module_id, Some(import_id), &items); + self.update(module_id, &items); // record the glob import in case we add further items let glob = self.glob_imports.entry(m.local_id).or_default(); if !glob.iter().any(|it| *it == (module_id, import_id)) { @@ -404,12 +403,12 @@ where let variant = EnumVariantId { parent: e, local_id }; let res = Resolution { def: PerNs::both(variant.into(), variant.into()), - import: Some(import_id), + declaration: false, }; (name, res) }) .collect::>(); - self.update(module_id, Some(import_id), &resolutions); + self.update(module_id, &resolutions); } Some(d) => { log::debug!("glob import {:?} from non-module/enum {:?}", import, d); @@ -431,27 +430,21 @@ where } } - let resolution = Resolution { def, import: Some(import_id) }; - self.update(module_id, Some(import_id), &[(name, resolution)]); + let resolution = Resolution { def, declaration: false }; + self.update(module_id, &[(name, resolution)]); } None => tested_by!(bogus_paths), } } } - fn update( - &mut self, - module_id: LocalModuleId, - import: Option, - resolutions: &[(Name, Resolution)], - ) { - self.update_recursive(module_id, import, resolutions, 0) + fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, Resolution)]) { + self.update_recursive(module_id, resolutions, 0) } fn update_recursive( &mut self, module_id: LocalModuleId, - import: Option, resolutions: &[(Name, Resolution)], depth: usize, ) { @@ -462,7 +455,7 @@ where let scope = &mut self.def_map.modules[module_id].scope; let mut changed = false; for (name, res) in resolutions { - changed |= scope.push_res(name.clone(), res, import); + changed |= scope.push_res(name.clone(), res, depth == 0 && res.declaration); } if !changed { @@ -475,9 +468,9 @@ where .flat_map(|v| v.iter()) .cloned() .collect::>(); - for (glob_importing_module, glob_import) in glob_imports { + for (glob_importing_module, _glob_import) in glob_imports { // We pass the glob import so that the tracked import in those modules is that glob import - self.update_recursive(glob_importing_module, Some(glob_import), resolutions, depth + 1); + self.update_recursive(glob_importing_module, resolutions, depth + 1); } } @@ -719,9 +712,9 @@ where def: PerNs::types( ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), ), - import: None, + declaration: true, }; - self.def_collector.update(self.module_id, None, &[(name, resolution)]); + self.def_collector.update(self.module_id, &[(name, resolution)]); res } @@ -791,8 +784,8 @@ where PerNs::types(def.into()) } }; - let resolution = Resolution { def, import: None }; - self.def_collector.update(self.module_id, None, &[(name, resolution)]) + let resolution = Resolution { def, declaration: true }; + self.def_collector.update(self.module_id, &[(name, resolution)]) } fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { -- cgit v1.2.3 From d3353118939d5ab77a63218db6ef542843256aac Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 12:44:28 +0100 Subject: Remove import source map --- crates/ra_hir_def/src/db.rs | 11 +------ crates/ra_hir_def/src/nameres/raw.rs | 62 +++++++----------------------------- crates/ra_hir_def/src/trace.rs | 8 ----- 3 files changed, 13 insertions(+), 68 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 98bff6cb7..c55fd4111 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -13,10 +13,7 @@ use crate::{ docs::Documentation, generics::GenericParams, lang_item::{LangItemTarget, LangItems}, - nameres::{ - raw::{ImportSourceMap, RawItems}, - CrateDefMap, - }, + nameres::{raw::RawItems, CrateDefMap}, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, @@ -46,12 +43,6 @@ pub trait InternDatabase: SourceDatabase { #[salsa::query_group(DefDatabaseStorage)] pub trait DefDatabase: InternDatabase + AstDatabase { - #[salsa::invoke(RawItems::raw_items_with_source_map_query)] - fn raw_items_with_source_map( - &self, - file_id: HirFileId, - ) -> (Arc, Arc); - #[salsa::invoke(RawItems::raw_items_query)] fn raw_items(&self, file_id: HirFileId) -> Arc; diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index ecb4d7c03..73e57f1e5 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -7,23 +7,21 @@ use std::{ops::Index, sync::Arc}; -use either::Either; use hir_expand::{ ast_id_map::AstIdMap, db::AstDatabase, hygiene::Hygiene, name::{AsName, Name}, }; -use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; +use ra_arena::{impl_arena_id, Arena, RawId}; use ra_syntax::{ ast::{self, AttrsOwner, NameOwner}, - AstNode, AstPtr, + AstNode, }; use test_utils::tested_by; use crate::{ - attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile, - LocalImportId, + attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile, LocalImportId, }; /// `RawItems` is a set of top-level items in a file (except for impls). @@ -41,35 +39,14 @@ pub struct RawItems { items: Vec, } -#[derive(Debug, Default, PartialEq, Eq)] -pub struct ImportSourceMap { - map: ArenaMap, -} - -type ImportSourcePtr = Either, AstPtr>; - -impl ImportSourceMap { - pub fn get(&self, import: LocalImportId) -> ImportSourcePtr { - self.map[import].clone() - } -} - impl RawItems { pub(crate) fn raw_items_query( db: &(impl DefDatabase + AstDatabase), file_id: HirFileId, ) -> Arc { - db.raw_items_with_source_map(file_id).0 - } - - pub(crate) fn raw_items_with_source_map_query( - db: &(impl DefDatabase + AstDatabase), - file_id: HirFileId, - ) -> (Arc, Arc) { let mut collector = RawItemsCollector { raw_items: RawItems::default(), source_ast_id_map: db.ast_id_map(file_id), - imports: Trace::new(), file_id, hygiene: Hygiene::new(db, file_id), }; @@ -80,11 +57,8 @@ impl RawItems { collector.process_module(None, item_list); } } - let mut raw_items = collector.raw_items; - let (arena, map) = collector.imports.into_arena_and_map(); - raw_items.imports = arena; - let source_map = ImportSourceMap { map }; - (Arc::new(raw_items), Arc::new(source_map)) + let raw_items = collector.raw_items; + Arc::new(raw_items) } pub(super) fn items(&self) -> &[RawItem] { @@ -223,7 +197,6 @@ pub(super) struct ImplData { struct RawItemsCollector { raw_items: RawItems, - imports: Trace, source_ast_id_map: Arc, file_id: HirFileId, hygiene: Hygiene, @@ -330,7 +303,7 @@ impl RawItemsCollector { ModPath::expand_use_item( InFile { value: use_item, file_id: self.file_id }, &self.hygiene, - |path, use_tree, is_glob, alias| { + |path, _use_tree, is_glob, alias| { let import_data = ImportData { path, alias, @@ -339,11 +312,11 @@ impl RawItemsCollector { is_extern_crate: false, is_macro_use: false, }; - buf.push((import_data, Either::Left(AstPtr::new(use_tree)))); + buf.push(import_data); }, ); - for (import_data, ptr) in buf { - self.push_import(current_module, attrs.clone(), import_data, ptr); + for import_data in buf { + self.push_import(current_module, attrs.clone(), import_data); } } @@ -366,12 +339,7 @@ impl RawItemsCollector { is_extern_crate: true, is_macro_use, }; - self.push_import( - current_module, - attrs, - import_data, - Either::Right(AstPtr::new(&extern_crate)), - ); + self.push_import(current_module, attrs, import_data); } } @@ -402,14 +370,8 @@ impl RawItemsCollector { self.push_item(current_module, attrs, RawItemKind::Impl(imp)) } - fn push_import( - &mut self, - current_module: Option, - attrs: Attrs, - data: ImportData, - source: ImportSourcePtr, - ) { - let import = self.imports.alloc(|| source, || data); + fn push_import(&mut self, current_module: Option, attrs: Attrs, data: ImportData) { + let import = self.raw_items.imports.alloc(data); self.push_item(current_module, attrs, RawItemKind::Import(import)) } diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs index 2bcd707bc..9769e88df 100644 --- a/crates/ra_hir_def/src/trace.rs +++ b/crates/ra_hir_def/src/trace.rs @@ -18,10 +18,6 @@ pub(crate) struct Trace { } impl Trace { - pub(crate) fn new() -> Trace { - Trace { arena: Some(Arena::default()), map: Some(ArenaMap::default()), len: 0 } - } - pub(crate) fn new_for_arena() -> Trace { Trace { arena: Some(Arena::default()), map: None, len: 0 } } @@ -52,8 +48,4 @@ impl Trace { pub(crate) fn into_map(mut self) -> ArenaMap { self.map.take().unwrap() } - - pub(crate) fn into_arena_and_map(mut self) -> (Arena, ArenaMap) { - (self.arena.take().unwrap(), self.map.take().unwrap()) - } } -- cgit v1.2.3 From 2d3fdf3fb52f32ececdfa19df7ab2971a24bae71 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 12:47:34 +0100 Subject: Privatize LocalImportID --- crates/ra_hir_def/src/lib.rs | 4 ---- crates/ra_hir_def/src/nameres/collector.rs | 7 +++---- crates/ra_hir_def/src/nameres/raw.rs | 8 +++++--- 3 files changed, 8 insertions(+), 11 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index acd4f4af1..f6c7f38d1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -51,10 +51,6 @@ use ra_syntax::{ast, AstNode}; use crate::body::Expander; use crate::builtin_type::BuiltinType; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct LocalImportId(RawId); -impl_arena_id!(LocalImportId); - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ModuleId { pub krate: CrateId, diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index e43aafedb..9419461a8 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -26,8 +26,7 @@ use crate::{ path::{ModPath, PathKind}, per_ns::PerNs, AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, - LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, - TypeAliasLoc, UnionLoc, + LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -93,7 +92,7 @@ impl PartialResolvedImport { #[derive(Clone, Debug, Eq, PartialEq)] struct ImportDirective { module_id: LocalModuleId, - import_id: LocalImportId, + import_id: raw::LocalImportId, import: raw::ImportData, status: PartialResolvedImport, } @@ -110,7 +109,7 @@ struct MacroDirective { struct DefCollector<'a, DB> { db: &'a DB, def_map: CrateDefMap, - glob_imports: FxHashMap>, + glob_imports: FxHashMap>, unresolved_imports: Vec, resolved_imports: Vec, unexpanded_macros: Vec, diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 73e57f1e5..b10e458a2 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -20,9 +20,11 @@ use ra_syntax::{ }; use test_utils::tested_by; -use crate::{ - attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile, LocalImportId, -}; +use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub(super) struct LocalImportId(RawId); +impl_arena_id!(LocalImportId); /// `RawItems` is a set of top-level items in a file (except for impls). /// -- cgit v1.2.3 From 973b5cf7e20842711d59a810b268796b26241382 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 15:04:33 +0100 Subject: Revert "Merge #2629" This reverts commit cdc9d682b066b110e0a44e5f8f1c574b38c16ba9, reversing changes made to 90ef070db3dce0a7acb9cd11d0b0d72de13c9d79. --- crates/ra_hir_def/src/db.rs | 11 ++++- crates/ra_hir_def/src/item_scope.rs | 35 ++++++++++----- crates/ra_hir_def/src/lib.rs | 4 ++ crates/ra_hir_def/src/nameres/collector.rs | 46 +++++++++++--------- crates/ra_hir_def/src/nameres/raw.rs | 68 +++++++++++++++++++++++------- crates/ra_hir_def/src/trace.rs | 8 ++++ 6 files changed, 126 insertions(+), 46 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index c55fd4111..98bff6cb7 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -13,7 +13,10 @@ use crate::{ docs::Documentation, generics::GenericParams, lang_item::{LangItemTarget, LangItems}, - nameres::{raw::RawItems, CrateDefMap}, + nameres::{ + raw::{ImportSourceMap, RawItems}, + CrateDefMap, + }, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, @@ -43,6 +46,12 @@ pub trait InternDatabase: SourceDatabase { #[salsa::query_group(DefDatabaseStorage)] pub trait DefDatabase: InternDatabase + AstDatabase { + #[salsa::invoke(RawItems::raw_items_with_source_map_query)] + fn raw_items_with_source_map( + &self, + file_id: HirFileId, + ) -> (Arc, Arc); + #[salsa::invoke(RawItems::raw_items_query)] fn raw_items(&self, file_id: HirFileId) -> Arc; diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 5c14fefff..6b9be8325 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -5,7 +5,7 @@ use hir_expand::name::Name; use once_cell::sync::Lazy; use rustc_hash::FxHashMap; -use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId}; +use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId}; #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { @@ -30,7 +30,7 @@ static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { BuiltinType::ALL .iter() .map(|(name, ty)| { - (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), declaration: false }) + (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None }) }) .collect() }); @@ -53,9 +53,11 @@ impl ItemScope { } pub fn declarations(&self) -> impl Iterator + '_ { - self.entries().filter(|(_name, res)| res.declaration).flat_map(|(_name, res)| { - res.def.take_types().into_iter().chain(res.def.take_values().into_iter()) - }) + self.entries() + .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) + .flat_map(|per_ns| { + per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) + }) } pub fn impls(&self) -> impl Iterator + ExactSizeIterator + '_ { @@ -110,26 +112,38 @@ impl ItemScope { self.legacy_macros.insert(name, mac); } - pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, declaration: bool) -> bool { + pub(crate) fn push_res( + &mut self, + name: Name, + res: &Resolution, + import: Option, + ) -> bool { let mut changed = false; let existing = self.items.entry(name.clone()).or_default(); if existing.def.types.is_none() && res.def.types.is_some() { existing.def.types = res.def.types; - existing.declaration |= declaration; + existing.import = import.or(res.import); changed = true; } if existing.def.values.is_none() && res.def.values.is_some() { existing.def.values = res.def.values; - existing.declaration |= declaration; + existing.import = import.or(res.import); changed = true; } if existing.def.macros.is_none() && res.def.macros.is_some() { existing.def.macros = res.def.macros; - existing.declaration |= declaration; + existing.import = import.or(res.import); changed = true; } + if existing.def.is_none() + && res.def.is_none() + && existing.import.is_none() + && res.import.is_some() + { + existing.import = res.import; + } changed } @@ -146,5 +160,6 @@ impl ItemScope { pub struct Resolution { /// None for unresolved pub def: PerNs, - pub declaration: bool, + /// ident by which this is imported into local scope. + pub import: Option, } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index f6c7f38d1..acd4f4af1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -51,6 +51,10 @@ use ra_syntax::{ast, AstNode}; use crate::body::Expander; use crate::builtin_type::BuiltinType; +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct LocalImportId(RawId); +impl_arena_id!(LocalImportId); + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ModuleId { pub krate: CrateId, diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 9419461a8..45199fa11 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -26,7 +26,8 @@ use crate::{ path::{ModPath, PathKind}, per_ns::PerNs, AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, - LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, + LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, + TypeAliasLoc, UnionLoc, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -92,7 +93,7 @@ impl PartialResolvedImport { #[derive(Clone, Debug, Eq, PartialEq)] struct ImportDirective { module_id: LocalModuleId, - import_id: raw::LocalImportId, + import_id: LocalImportId, import: raw::ImportData, status: PartialResolvedImport, } @@ -109,7 +110,7 @@ struct MacroDirective { struct DefCollector<'a, DB> { db: &'a DB, def_map: CrateDefMap, - glob_imports: FxHashMap>, + glob_imports: FxHashMap>, unresolved_imports: Vec, resolved_imports: Vec, unexpanded_macros: Vec, @@ -217,7 +218,8 @@ where if export { self.update( self.def_map.root, - &[(name, Resolution { def: PerNs::macros(macro_), declaration: false })], + None, + &[(name, Resolution { def: PerNs::macros(macro_), import: None })], ); } } @@ -372,7 +374,7 @@ where // Module scoped macros is included let items = scope.collect_resolutions(); - self.update(module_id, &items); + self.update(module_id, Some(import_id), &items); } else { // glob import from same crate => we do an initial // import, and then need to propagate any further @@ -382,7 +384,7 @@ where // Module scoped macros is included let items = scope.collect_resolutions(); - self.update(module_id, &items); + self.update(module_id, Some(import_id), &items); // record the glob import in case we add further items let glob = self.glob_imports.entry(m.local_id).or_default(); if !glob.iter().any(|it| *it == (module_id, import_id)) { @@ -402,12 +404,12 @@ where let variant = EnumVariantId { parent: e, local_id }; let res = Resolution { def: PerNs::both(variant.into(), variant.into()), - declaration: false, + import: Some(import_id), }; (name, res) }) .collect::>(); - self.update(module_id, &resolutions); + self.update(module_id, Some(import_id), &resolutions); } Some(d) => { log::debug!("glob import {:?} from non-module/enum {:?}", import, d); @@ -429,21 +431,27 @@ where } } - let resolution = Resolution { def, declaration: false }; - self.update(module_id, &[(name, resolution)]); + let resolution = Resolution { def, import: Some(import_id) }; + self.update(module_id, Some(import_id), &[(name, resolution)]); } None => tested_by!(bogus_paths), } } } - fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, Resolution)]) { - self.update_recursive(module_id, resolutions, 0) + fn update( + &mut self, + module_id: LocalModuleId, + import: Option, + resolutions: &[(Name, Resolution)], + ) { + self.update_recursive(module_id, import, resolutions, 0) } fn update_recursive( &mut self, module_id: LocalModuleId, + import: Option, resolutions: &[(Name, Resolution)], depth: usize, ) { @@ -454,7 +462,7 @@ where let scope = &mut self.def_map.modules[module_id].scope; let mut changed = false; for (name, res) in resolutions { - changed |= scope.push_res(name.clone(), res, depth == 0 && res.declaration); + changed |= scope.push_res(name.clone(), res, import); } if !changed { @@ -467,9 +475,9 @@ where .flat_map(|v| v.iter()) .cloned() .collect::>(); - for (glob_importing_module, _glob_import) in glob_imports { + for (glob_importing_module, glob_import) in glob_imports { // We pass the glob import so that the tracked import in those modules is that glob import - self.update_recursive(glob_importing_module, resolutions, depth + 1); + self.update_recursive(glob_importing_module, Some(glob_import), resolutions, depth + 1); } } @@ -711,9 +719,9 @@ where def: PerNs::types( ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), ), - declaration: true, + import: None, }; - self.def_collector.update(self.module_id, &[(name, resolution)]); + self.def_collector.update(self.module_id, None, &[(name, resolution)]); res } @@ -783,8 +791,8 @@ where PerNs::types(def.into()) } }; - let resolution = Resolution { def, declaration: true }; - self.def_collector.update(self.module_id, &[(name, resolution)]) + let resolution = Resolution { def, import: None }; + self.def_collector.update(self.module_id, None, &[(name, resolution)]) } fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index b10e458a2..ecb4d7c03 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -7,24 +7,24 @@ use std::{ops::Index, sync::Arc}; +use either::Either; use hir_expand::{ ast_id_map::AstIdMap, db::AstDatabase, hygiene::Hygiene, name::{AsName, Name}, }; -use ra_arena::{impl_arena_id, Arena, RawId}; +use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; use ra_syntax::{ ast::{self, AttrsOwner, NameOwner}, - AstNode, + AstNode, AstPtr, }; use test_utils::tested_by; -use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(super) struct LocalImportId(RawId); -impl_arena_id!(LocalImportId); +use crate::{ + attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile, + LocalImportId, +}; /// `RawItems` is a set of top-level items in a file (except for impls). /// @@ -41,14 +41,35 @@ pub struct RawItems { items: Vec, } +#[derive(Debug, Default, PartialEq, Eq)] +pub struct ImportSourceMap { + map: ArenaMap, +} + +type ImportSourcePtr = Either, AstPtr>; + +impl ImportSourceMap { + pub fn get(&self, import: LocalImportId) -> ImportSourcePtr { + self.map[import].clone() + } +} + impl RawItems { pub(crate) fn raw_items_query( db: &(impl DefDatabase + AstDatabase), file_id: HirFileId, ) -> Arc { + db.raw_items_with_source_map(file_id).0 + } + + pub(crate) fn raw_items_with_source_map_query( + db: &(impl DefDatabase + AstDatabase), + file_id: HirFileId, + ) -> (Arc, Arc) { let mut collector = RawItemsCollector { raw_items: RawItems::default(), source_ast_id_map: db.ast_id_map(file_id), + imports: Trace::new(), file_id, hygiene: Hygiene::new(db, file_id), }; @@ -59,8 +80,11 @@ impl RawItems { collector.process_module(None, item_list); } } - let raw_items = collector.raw_items; - Arc::new(raw_items) + let mut raw_items = collector.raw_items; + let (arena, map) = collector.imports.into_arena_and_map(); + raw_items.imports = arena; + let source_map = ImportSourceMap { map }; + (Arc::new(raw_items), Arc::new(source_map)) } pub(super) fn items(&self) -> &[RawItem] { @@ -199,6 +223,7 @@ pub(super) struct ImplData { struct RawItemsCollector { raw_items: RawItems, + imports: Trace, source_ast_id_map: Arc, file_id: HirFileId, hygiene: Hygiene, @@ -305,7 +330,7 @@ impl RawItemsCollector { ModPath::expand_use_item( InFile { value: use_item, file_id: self.file_id }, &self.hygiene, - |path, _use_tree, is_glob, alias| { + |path, use_tree, is_glob, alias| { let import_data = ImportData { path, alias, @@ -314,11 +339,11 @@ impl RawItemsCollector { is_extern_crate: false, is_macro_use: false, }; - buf.push(import_data); + buf.push((import_data, Either::Left(AstPtr::new(use_tree)))); }, ); - for import_data in buf { - self.push_import(current_module, attrs.clone(), import_data); + for (import_data, ptr) in buf { + self.push_import(current_module, attrs.clone(), import_data, ptr); } } @@ -341,7 +366,12 @@ impl RawItemsCollector { is_extern_crate: true, is_macro_use, }; - self.push_import(current_module, attrs, import_data); + self.push_import( + current_module, + attrs, + import_data, + Either::Right(AstPtr::new(&extern_crate)), + ); } } @@ -372,8 +402,14 @@ impl RawItemsCollector { self.push_item(current_module, attrs, RawItemKind::Impl(imp)) } - fn push_import(&mut self, current_module: Option, attrs: Attrs, data: ImportData) { - let import = self.raw_items.imports.alloc(data); + fn push_import( + &mut self, + current_module: Option, + attrs: Attrs, + data: ImportData, + source: ImportSourcePtr, + ) { + let import = self.imports.alloc(|| source, || data); self.push_item(current_module, attrs, RawItemKind::Import(import)) } diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs index 9769e88df..2bcd707bc 100644 --- a/crates/ra_hir_def/src/trace.rs +++ b/crates/ra_hir_def/src/trace.rs @@ -18,6 +18,10 @@ pub(crate) struct Trace { } impl Trace { + pub(crate) fn new() -> Trace { + Trace { arena: Some(Arena::default()), map: Some(ArenaMap::default()), len: 0 } + } + pub(crate) fn new_for_arena() -> Trace { Trace { arena: Some(Arena::default()), map: None, len: 0 } } @@ -48,4 +52,8 @@ impl Trace { pub(crate) fn into_map(mut self) -> ArenaMap { self.map.take().unwrap() } + + pub(crate) fn into_arena_and_map(mut self) -> (Arena, ArenaMap) { + (self.arena.take().unwrap(), self.map.take().unwrap()) + } } -- cgit v1.2.3 From 4e0168ec14b74003e8388b72b64c2ca78b580274 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 15:17:10 +0100 Subject: Remove imports from hir --- crates/ra_hir_def/src/item_scope.rs | 2 +- crates/ra_hir_def/src/lib.rs | 2 +- crates/ra_hir_def/src/nameres/raw.rs | 6 ------ 3 files changed, 2 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 6b9be8325..ad104bb3d 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -161,5 +161,5 @@ pub struct Resolution { /// None for unresolved pub def: PerNs, /// ident by which this is imported into local scope. - pub import: Option, + pub(crate) import: Option, } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index acd4f4af1..8cb5ab8d0 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -52,7 +52,7 @@ use crate::body::Expander; use crate::builtin_type::BuiltinType; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct LocalImportId(RawId); +pub(crate) struct LocalImportId(RawId); impl_arena_id!(LocalImportId); #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index ecb4d7c03..df5dac88a 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -48,12 +48,6 @@ pub struct ImportSourceMap { type ImportSourcePtr = Either, AstPtr>; -impl ImportSourceMap { - pub fn get(&self, import: LocalImportId) -> ImportSourcePtr { - self.map[import].clone() - } -} - impl RawItems { pub(crate) fn raw_items_query( db: &(impl DefDatabase + AstDatabase), -- cgit v1.2.3 From ec56f59ac17ad5ae797ce431883be8f31e795d1b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 17:22:48 +0100 Subject: Remove import from resolution --- crates/ra_hir_def/src/item_scope.rs | 19 +++++++------------ crates/ra_hir_def/src/nameres/collector.rs | 10 +++++----- 2 files changed, 12 insertions(+), 17 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index ad104bb3d..8b70e13c4 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -30,7 +30,7 @@ static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { BuiltinType::ALL .iter() .map(|(name, ty)| { - (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: None }) + (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: false }) }) .collect() }); @@ -54,7 +54,7 @@ impl ItemScope { pub fn declarations(&self) -> impl Iterator + '_ { self.entries() - .filter_map(|(_name, res)| if res.import.is_none() { Some(res.def) } else { None }) + .filter_map(|(_name, res)| if !res.import { Some(res.def) } else { None }) .flat_map(|per_ns| { per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) }) @@ -123,25 +123,21 @@ impl ItemScope { if existing.def.types.is_none() && res.def.types.is_some() { existing.def.types = res.def.types; - existing.import = import.or(res.import); + existing.import = import.is_some() || res.import; changed = true; } if existing.def.values.is_none() && res.def.values.is_some() { existing.def.values = res.def.values; - existing.import = import.or(res.import); + existing.import = import.is_some() || res.import; changed = true; } if existing.def.macros.is_none() && res.def.macros.is_some() { existing.def.macros = res.def.macros; - existing.import = import.or(res.import); + existing.import = import.is_some() || res.import; changed = true; } - if existing.def.is_none() - && res.def.is_none() - && existing.import.is_none() - && res.import.is_some() - { + if existing.def.is_none() && res.def.is_none() && !existing.import && res.import { existing.import = res.import; } changed @@ -160,6 +156,5 @@ impl ItemScope { pub struct Resolution { /// None for unresolved pub def: PerNs, - /// ident by which this is imported into local scope. - pub(crate) import: Option, + pub(crate) import: bool, } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 45199fa11..c2db5472b 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -219,7 +219,7 @@ where self.update( self.def_map.root, None, - &[(name, Resolution { def: PerNs::macros(macro_), import: None })], + &[(name, Resolution { def: PerNs::macros(macro_), import: false })], ); } } @@ -404,7 +404,7 @@ where let variant = EnumVariantId { parent: e, local_id }; let res = Resolution { def: PerNs::both(variant.into(), variant.into()), - import: Some(import_id), + import: true, }; (name, res) }) @@ -431,7 +431,7 @@ where } } - let resolution = Resolution { def, import: Some(import_id) }; + let resolution = Resolution { def, import: true }; self.update(module_id, Some(import_id), &[(name, resolution)]); } None => tested_by!(bogus_paths), @@ -719,7 +719,7 @@ where def: PerNs::types( ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), ), - import: None, + import: false, }; self.def_collector.update(self.module_id, None, &[(name, resolution)]); res @@ -791,7 +791,7 @@ where PerNs::types(def.into()) } }; - let resolution = Resolution { def, import: None }; + let resolution = Resolution { def, import: false }; self.def_collector.update(self.module_id, None, &[(name, resolution)]) } -- cgit v1.2.3 From 02f79e37ca1c4a617a46b85bf897dffbf4abed9e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 17:26:05 +0100 Subject: Remove import source map --- crates/ra_hir_def/src/db.rs | 11 +------ crates/ra_hir_def/src/nameres/raw.rs | 56 ++++++++---------------------------- crates/ra_hir_def/src/trace.rs | 8 ------ 3 files changed, 13 insertions(+), 62 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs index 98bff6cb7..c55fd4111 100644 --- a/crates/ra_hir_def/src/db.rs +++ b/crates/ra_hir_def/src/db.rs @@ -13,10 +13,7 @@ use crate::{ docs::Documentation, generics::GenericParams, lang_item::{LangItemTarget, LangItems}, - nameres::{ - raw::{ImportSourceMap, RawItems}, - CrateDefMap, - }, + nameres::{raw::RawItems, CrateDefMap}, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, @@ -46,12 +43,6 @@ pub trait InternDatabase: SourceDatabase { #[salsa::query_group(DefDatabaseStorage)] pub trait DefDatabase: InternDatabase + AstDatabase { - #[salsa::invoke(RawItems::raw_items_with_source_map_query)] - fn raw_items_with_source_map( - &self, - file_id: HirFileId, - ) -> (Arc, Arc); - #[salsa::invoke(RawItems::raw_items_query)] fn raw_items(&self, file_id: HirFileId) -> Arc; diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index df5dac88a..73e57f1e5 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -7,23 +7,21 @@ use std::{ops::Index, sync::Arc}; -use either::Either; use hir_expand::{ ast_id_map::AstIdMap, db::AstDatabase, hygiene::Hygiene, name::{AsName, Name}, }; -use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; +use ra_arena::{impl_arena_id, Arena, RawId}; use ra_syntax::{ ast::{self, AttrsOwner, NameOwner}, - AstNode, AstPtr, + AstNode, }; use test_utils::tested_by; use crate::{ - attr::Attrs, db::DefDatabase, path::ModPath, trace::Trace, FileAstId, HirFileId, InFile, - LocalImportId, + attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile, LocalImportId, }; /// `RawItems` is a set of top-level items in a file (except for impls). @@ -41,29 +39,14 @@ pub struct RawItems { items: Vec, } -#[derive(Debug, Default, PartialEq, Eq)] -pub struct ImportSourceMap { - map: ArenaMap, -} - -type ImportSourcePtr = Either, AstPtr>; - impl RawItems { pub(crate) fn raw_items_query( db: &(impl DefDatabase + AstDatabase), file_id: HirFileId, ) -> Arc { - db.raw_items_with_source_map(file_id).0 - } - - pub(crate) fn raw_items_with_source_map_query( - db: &(impl DefDatabase + AstDatabase), - file_id: HirFileId, - ) -> (Arc, Arc) { let mut collector = RawItemsCollector { raw_items: RawItems::default(), source_ast_id_map: db.ast_id_map(file_id), - imports: Trace::new(), file_id, hygiene: Hygiene::new(db, file_id), }; @@ -74,11 +57,8 @@ impl RawItems { collector.process_module(None, item_list); } } - let mut raw_items = collector.raw_items; - let (arena, map) = collector.imports.into_arena_and_map(); - raw_items.imports = arena; - let source_map = ImportSourceMap { map }; - (Arc::new(raw_items), Arc::new(source_map)) + let raw_items = collector.raw_items; + Arc::new(raw_items) } pub(super) fn items(&self) -> &[RawItem] { @@ -217,7 +197,6 @@ pub(super) struct ImplData { struct RawItemsCollector { raw_items: RawItems, - imports: Trace, source_ast_id_map: Arc, file_id: HirFileId, hygiene: Hygiene, @@ -324,7 +303,7 @@ impl RawItemsCollector { ModPath::expand_use_item( InFile { value: use_item, file_id: self.file_id }, &self.hygiene, - |path, use_tree, is_glob, alias| { + |path, _use_tree, is_glob, alias| { let import_data = ImportData { path, alias, @@ -333,11 +312,11 @@ impl RawItemsCollector { is_extern_crate: false, is_macro_use: false, }; - buf.push((import_data, Either::Left(AstPtr::new(use_tree)))); + buf.push(import_data); }, ); - for (import_data, ptr) in buf { - self.push_import(current_module, attrs.clone(), import_data, ptr); + for import_data in buf { + self.push_import(current_module, attrs.clone(), import_data); } } @@ -360,12 +339,7 @@ impl RawItemsCollector { is_extern_crate: true, is_macro_use, }; - self.push_import( - current_module, - attrs, - import_data, - Either::Right(AstPtr::new(&extern_crate)), - ); + self.push_import(current_module, attrs, import_data); } } @@ -396,14 +370,8 @@ impl RawItemsCollector { self.push_item(current_module, attrs, RawItemKind::Impl(imp)) } - fn push_import( - &mut self, - current_module: Option, - attrs: Attrs, - data: ImportData, - source: ImportSourcePtr, - ) { - let import = self.imports.alloc(|| source, || data); + fn push_import(&mut self, current_module: Option, attrs: Attrs, data: ImportData) { + let import = self.raw_items.imports.alloc(data); self.push_item(current_module, attrs, RawItemKind::Import(import)) } diff --git a/crates/ra_hir_def/src/trace.rs b/crates/ra_hir_def/src/trace.rs index 2bcd707bc..9769e88df 100644 --- a/crates/ra_hir_def/src/trace.rs +++ b/crates/ra_hir_def/src/trace.rs @@ -18,10 +18,6 @@ pub(crate) struct Trace { } impl Trace { - pub(crate) fn new() -> Trace { - Trace { arena: Some(Arena::default()), map: Some(ArenaMap::default()), len: 0 } - } - pub(crate) fn new_for_arena() -> Trace { Trace { arena: Some(Arena::default()), map: None, len: 0 } } @@ -52,8 +48,4 @@ impl Trace { pub(crate) fn into_map(mut self) -> ArenaMap { self.map.take().unwrap() } - - pub(crate) fn into_arena_and_map(mut self) -> (Arena, ArenaMap) { - (self.arena.take().unwrap(), self.map.take().unwrap()) - } } -- cgit v1.2.3 From 1a8f2aa024c6f1a5e9704c9cbd2e5a020debe2c2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 17:34:28 +0100 Subject: Move LocalImportId --- crates/ra_hir_def/src/item_scope.rs | 15 +++++---------- crates/ra_hir_def/src/lib.rs | 4 ---- crates/ra_hir_def/src/nameres/collector.rs | 13 ++++++------- crates/ra_hir_def/src/nameres/raw.rs | 16 +++++++++------- 4 files changed, 20 insertions(+), 28 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 8b70e13c4..9e082c5f7 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -5,7 +5,7 @@ use hir_expand::name::Name; use once_cell::sync::Lazy; use rustc_hash::FxHashMap; -use crate::{per_ns::PerNs, BuiltinType, ImplId, LocalImportId, MacroDefId, ModuleDefId, TraitId}; +use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId}; #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { @@ -112,28 +112,23 @@ impl ItemScope { self.legacy_macros.insert(name, mac); } - pub(crate) fn push_res( - &mut self, - name: Name, - res: &Resolution, - import: Option, - ) -> bool { + pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, import: bool) -> bool { let mut changed = false; let existing = self.items.entry(name.clone()).or_default(); if existing.def.types.is_none() && res.def.types.is_some() { existing.def.types = res.def.types; - existing.import = import.is_some() || res.import; + existing.import = import || res.import; changed = true; } if existing.def.values.is_none() && res.def.values.is_some() { existing.def.values = res.def.values; - existing.import = import.is_some() || res.import; + existing.import = import || res.import; changed = true; } if existing.def.macros.is_none() && res.def.macros.is_some() { existing.def.macros = res.def.macros; - existing.import = import.is_some() || res.import; + existing.import = import || res.import; changed = true; } diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index 8cb5ab8d0..f6c7f38d1 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs @@ -51,10 +51,6 @@ use ra_syntax::{ast, AstNode}; use crate::body::Expander; use crate::builtin_type::BuiltinType; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct LocalImportId(RawId); -impl_arena_id!(LocalImportId); - #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct ModuleId { pub krate: CrateId, diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index c2db5472b..2b194f488 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -26,8 +26,7 @@ use crate::{ path::{ModPath, PathKind}, per_ns::PerNs, AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, - LocalImportId, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, - TypeAliasLoc, UnionLoc, + LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -93,7 +92,7 @@ impl PartialResolvedImport { #[derive(Clone, Debug, Eq, PartialEq)] struct ImportDirective { module_id: LocalModuleId, - import_id: LocalImportId, + import_id: raw::Import, import: raw::ImportData, status: PartialResolvedImport, } @@ -110,7 +109,7 @@ struct MacroDirective { struct DefCollector<'a, DB> { db: &'a DB, def_map: CrateDefMap, - glob_imports: FxHashMap>, + glob_imports: FxHashMap>, unresolved_imports: Vec, resolved_imports: Vec, unexpanded_macros: Vec, @@ -442,7 +441,7 @@ where fn update( &mut self, module_id: LocalModuleId, - import: Option, + import: Option, resolutions: &[(Name, Resolution)], ) { self.update_recursive(module_id, import, resolutions, 0) @@ -451,7 +450,7 @@ where fn update_recursive( &mut self, module_id: LocalModuleId, - import: Option, + import: Option, resolutions: &[(Name, Resolution)], depth: usize, ) { @@ -462,7 +461,7 @@ where let scope = &mut self.def_map.modules[module_id].scope; let mut changed = false; for (name, res) in resolutions { - changed |= scope.push_res(name.clone(), res, import); + changed |= scope.push_res(name.clone(), res, import.is_some()); } if !changed { diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 73e57f1e5..1b83b2247 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -20,9 +20,7 @@ use ra_syntax::{ }; use test_utils::tested_by; -use crate::{ - attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile, LocalImportId, -}; +use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; /// `RawItems` is a set of top-level items in a file (except for impls). /// @@ -31,7 +29,7 @@ use crate::{ #[derive(Debug, Default, PartialEq, Eq)] pub struct RawItems { modules: Arena, - imports: Arena, + imports: Arena, defs: Arena, macros: Arena, impls: Arena, @@ -73,9 +71,9 @@ impl Index for RawItems { } } -impl Index for RawItems { +impl Index for RawItems { type Output = ImportData; - fn index(&self, idx: LocalImportId) -> &ImportData { + fn index(&self, idx: Import) -> &ImportData { &self.imports[idx] } } @@ -110,7 +108,7 @@ pub(super) struct RawItem { #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub(super) enum RawItemKind { Module(Module), - Import(LocalImportId), + Import(Import), Def(Def), Macro(Macro), Impl(Impl), @@ -126,6 +124,10 @@ pub(super) enum ModuleData { Definition { name: Name, ast_id: FileAstId, items: Vec }, } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub(crate) struct Import(RawId); +impl_arena_id!(Import); + #[derive(Debug, Clone, PartialEq, Eq)] pub struct ImportData { pub(super) path: ModPath, -- cgit v1.2.3 From d4b135f38c8c0050768c50e62043ddca5f09079a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 18:45:46 +0100 Subject: Optimize and profile --- crates/ra_hir_def/src/body.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 445d215b7..148ff007e 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -11,6 +11,7 @@ use hir_expand::{ ast_id_map::AstIdMap, hygiene::Hygiene, AstId, HirFileId, InFile, MacroCallKind, MacroDefId, }; use ra_arena::{map::ArenaMap, Arena}; +use ra_prof::profile; use ra_syntax::{ast, AstNode, AstPtr}; use rustc_hash::FxHashMap; @@ -168,6 +169,7 @@ impl Body { db: &impl DefDatabase, def: DefWithBodyId, ) -> (Arc, Arc) { + let _p = profile("body_with_source_map_query"); let mut params = None; let (file_id, module, body) = match def { -- cgit v1.2.3 From e903f58d29662b5509fb20c74d7c4131271bfbf0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 21 Dec 2019 19:40:20 +0100 Subject: More profiling --- crates/ra_hir_def/src/adt.rs | 2 ++ crates/ra_hir_def/src/nameres/raw.rs | 2 ++ 2 files changed, 4 insertions(+) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index ec3d57d1a..d9ea693e3 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs @@ -8,6 +8,7 @@ use hir_expand::{ InFile, }; use ra_arena::{map::ArenaMap, Arena}; +use ra_prof::profile; use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; use crate::{ @@ -72,6 +73,7 @@ impl StructData { impl EnumData { pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc { + let _p = profile("enum_data_query"); let src = e.lookup(db).source(db); let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); let mut trace = Trace::new_for_arena(); diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 1b83b2247..73dc08745 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs @@ -14,6 +14,7 @@ use hir_expand::{ name::{AsName, Name}, }; use ra_arena::{impl_arena_id, Arena, RawId}; +use ra_prof::profile; use ra_syntax::{ ast::{self, AttrsOwner, NameOwner}, AstNode, @@ -42,6 +43,7 @@ impl RawItems { db: &(impl DefDatabase + AstDatabase), file_id: HirFileId, ) -> Arc { + let _p = profile("raw_items_query"); let mut collector = RawItemsCollector { raw_items: RawItems::default(), source_ast_id_map: db.ast_id_map(file_id), -- cgit v1.2.3 From fe38fffaa90f656abbeff7b8a167afc45cc492a9 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 15:04:31 +0100 Subject: Minor rename --- crates/ra_hir_def/src/item_scope.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 9e082c5f7..eab3e2fff 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -9,7 +9,7 @@ use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { - items: FxHashMap, + visible: FxHashMap, impls: Vec, /// Macros visible in current module in legacy textual scope /// @@ -49,7 +49,7 @@ pub(crate) enum BuiltinShadowMode { impl ItemScope { pub fn entries<'a>(&'a self) -> impl Iterator + 'a { //FIXME: shadowing - self.items.iter().chain(BUILTIN_SCOPE.iter()) + self.visible.iter().chain(BUILTIN_SCOPE.iter()) } pub fn declarations(&self) -> impl Iterator + '_ { @@ -66,7 +66,7 @@ impl ItemScope { /// Iterate over all module scoped macros pub(crate) fn macros<'a>(&'a self) -> impl Iterator + 'a { - self.items + self.visible .iter() .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_))) } @@ -79,9 +79,9 @@ impl ItemScope { /// Get a name from current module scope, legacy macros are not included pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> { match shadow { - BuiltinShadowMode::Module => self.items.get(name).or_else(|| BUILTIN_SCOPE.get(name)), + BuiltinShadowMode::Module => self.visible.get(name).or_else(|| BUILTIN_SCOPE.get(name)), BuiltinShadowMode::Other => { - let item = self.items.get(name); + let item = self.visible.get(name); if let Some(res) = item { if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() { return BUILTIN_SCOPE.get(name).or(item); @@ -94,7 +94,7 @@ impl ItemScope { } pub(crate) fn traits<'a>(&'a self) -> impl Iterator + 'a { - self.items.values().filter_map(|r| match r.def.take_types() { + self.visible.values().filter_map(|r| match r.def.take_types() { Some(ModuleDefId::TraitId(t)) => Some(t), _ => None, }) @@ -114,7 +114,7 @@ impl ItemScope { pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, import: bool) -> bool { let mut changed = false; - let existing = self.items.entry(name.clone()).or_default(); + let existing = self.visible.entry(name.clone()).or_default(); if existing.def.types.is_none() && res.def.types.is_some() { existing.def.types = res.def.types; @@ -139,7 +139,7 @@ impl ItemScope { } pub(crate) fn collect_resolutions(&self) -> Vec<(Name, Resolution)> { - self.items.iter().map(|(name, res)| (name.clone(), res.clone())).collect() + self.visible.iter().map(|(name, res)| (name.clone(), res.clone())).collect() } pub(crate) fn collect_legacy_macros(&self) -> FxHashMap { -- cgit v1.2.3 From e69af8596262931f8e55b7f9203f65d14827e2d8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 15:08:57 +0100 Subject: Refactor PerNs construction --- crates/ra_hir_def/src/item_scope.rs | 20 +++++++- crates/ra_hir_def/src/nameres/collector.rs | 81 ++++++++++++------------------ 2 files changed, 52 insertions(+), 49 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index eab3e2fff..a96b5cfd2 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -5,7 +5,7 @@ use hir_expand::name::Name; use once_cell::sync::Lazy; use rustc_hash::FxHashMap; -use crate::{per_ns::PerNs, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId}; +use crate::{per_ns::PerNs, AdtId, BuiltinType, ImplId, MacroDefId, ModuleDefId, TraitId}; #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { @@ -153,3 +153,21 @@ pub struct Resolution { pub def: PerNs, pub(crate) import: bool, } + +impl From for PerNs { + fn from(def: ModuleDefId) -> PerNs { + match def { + ModuleDefId::ModuleId(_) => PerNs::types(def), + ModuleDefId::FunctionId(_) => PerNs::values(def), + ModuleDefId::AdtId(adt) => match adt { + AdtId::StructId(_) | AdtId::UnionId(_) => PerNs::both(def, def), + AdtId::EnumId(_) => PerNs::types(def), + }, + ModuleDefId::EnumVariantId(_) => PerNs::both(def, def), + ModuleDefId::ConstId(_) | ModuleDefId::StaticId(_) => PerNs::values(def), + ModuleDefId::TraitId(_) => PerNs::types(def), + ModuleDefId::TypeAliasId(_) => PerNs::types(def), + ModuleDefId::BuiltinType(_) => PerNs::types(def), + } + } +} diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 2b194f488..b4e438257 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -714,12 +714,9 @@ where modules[res].scope.define_legacy_macro(name, mac) } modules[self.module_id].children.insert(name.clone(), res); - let resolution = Resolution { - def: PerNs::types( - ModuleId { krate: self.def_collector.def_map.krate, local_id: res }.into(), - ), - import: false, - }; + let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; + let def: ModuleDefId = module.into(); + let resolution = Resolution { def: def.into(), import: false }; self.def_collector.update(self.module_id, None, &[(name, resolution)]); res } @@ -734,63 +731,51 @@ where let name = def.name.clone(); let container = ContainerId::ModuleId(module); - let def: PerNs = match def.kind { - raw::DefKind::Function(ast_id) => { - let def = FunctionLoc { - container: container.into(), - ast_id: AstId::new(self.file_id, ast_id), - } - .intern(self.def_collector.db); - - PerNs::values(def.into()) + let def: ModuleDefId = match def.kind { + raw::DefKind::Function(ast_id) => FunctionLoc { + container: container.into(), + ast_id: AstId::new(self.file_id, ast_id), } + .intern(self.def_collector.db) + .into(), raw::DefKind::Struct(ast_id) => { - let def = StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db); - PerNs::both(def.into(), def.into()) + StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db) + .into() } raw::DefKind::Union(ast_id) => { - let def = UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db); - PerNs::both(def.into(), def.into()) + UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db) + .into() } raw::DefKind::Enum(ast_id) => { - let def = EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db); - PerNs::types(def.into()) + EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db) + .into() } raw::DefKind::Const(ast_id) => { - let def = ConstLoc { - container: container.into(), - ast_id: AstId::new(self.file_id, ast_id), - } - .intern(self.def_collector.db); - - PerNs::values(def.into()) + ConstLoc { container: container.into(), ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db) + .into() } raw::DefKind::Static(ast_id) => { - let def = StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db); - - PerNs::values(def.into()) + StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db) + .into() } raw::DefKind::Trait(ast_id) => { - let def = TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db); - - PerNs::types(def.into()) + TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) } + .intern(self.def_collector.db) + .into() } - raw::DefKind::TypeAlias(ast_id) => { - let def = TypeAliasLoc { - container: container.into(), - ast_id: AstId::new(self.file_id, ast_id), - } - .intern(self.def_collector.db); - - PerNs::types(def.into()) + raw::DefKind::TypeAlias(ast_id) => TypeAliasLoc { + container: container.into(), + ast_id: AstId::new(self.file_id, ast_id), } + .intern(self.def_collector.db) + .into(), }; - let resolution = Resolution { def, import: false }; + let resolution = Resolution { def: def.into(), import: false }; self.def_collector.update(self.module_id, None, &[(name, resolution)]) } -- cgit v1.2.3 From 2c60f42825e68d8133854d378d9550139c71d9b4 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 15:21:48 +0100 Subject: Separate defs from imports --- crates/ra_hir_def/src/item_scope.rs | 11 ++++++----- crates/ra_hir_def/src/nameres/collector.rs | 2 ++ 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index a96b5cfd2..b5c07ed5f 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -10,6 +10,7 @@ use crate::{per_ns::PerNs, AdtId, BuiltinType, ImplId, MacroDefId, ModuleDefId, #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { visible: FxHashMap, + defs: Vec, impls: Vec, /// Macros visible in current module in legacy textual scope /// @@ -53,11 +54,7 @@ impl ItemScope { } pub fn declarations(&self) -> impl Iterator + '_ { - self.entries() - .filter_map(|(_name, res)| if !res.import { Some(res.def) } else { None }) - .flat_map(|per_ns| { - per_ns.take_types().into_iter().chain(per_ns.take_values().into_iter()) - }) + self.defs.iter().copied() } pub fn impls(&self) -> impl Iterator + ExactSizeIterator + '_ { @@ -100,6 +97,10 @@ impl ItemScope { }) } + pub(crate) fn define_def(&mut self, def: ModuleDefId) { + self.defs.push(def) + } + pub(crate) fn get_legacy_macro(&self, name: &Name) -> Option { self.legacy_macros.get(name).copied() } diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index b4e438257..745e31c0d 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -716,6 +716,7 @@ where modules[self.module_id].children.insert(name.clone(), res); let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; let def: ModuleDefId = module.into(); + self.def_collector.def_map.modules[self.module_id].scope.define_def(def); let resolution = Resolution { def: def.into(), import: false }; self.def_collector.update(self.module_id, None, &[(name, resolution)]); res @@ -775,6 +776,7 @@ where .intern(self.def_collector.db) .into(), }; + self.def_collector.def_map.modules[self.module_id].scope.define_def(def); let resolution = Resolution { def: def.into(), import: false }; self.def_collector.update(self.module_id, None, &[(name, resolution)]) } -- cgit v1.2.3 From 558956c84be5e8752986bae001c7fd3f06cbe86d Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 15:28:55 +0100 Subject: Remove import field --- crates/ra_hir_def/src/item_scope.rs | 13 ++----------- crates/ra_hir_def/src/nameres/collector.rs | 14 ++++++-------- 2 files changed, 8 insertions(+), 19 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index b5c07ed5f..81089554f 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -30,9 +30,7 @@ pub struct ItemScope { static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { BuiltinType::ALL .iter() - .map(|(name, ty)| { - (name.clone(), Resolution { def: PerNs::types(ty.clone().into()), import: false }) - }) + .map(|(name, ty)| (name.clone(), Resolution { def: PerNs::types(ty.clone().into()) })) .collect() }); @@ -113,29 +111,23 @@ impl ItemScope { self.legacy_macros.insert(name, mac); } - pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, import: bool) -> bool { + pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, _import: bool) -> bool { let mut changed = false; let existing = self.visible.entry(name.clone()).or_default(); if existing.def.types.is_none() && res.def.types.is_some() { existing.def.types = res.def.types; - existing.import = import || res.import; changed = true; } if existing.def.values.is_none() && res.def.values.is_some() { existing.def.values = res.def.values; - existing.import = import || res.import; changed = true; } if existing.def.macros.is_none() && res.def.macros.is_some() { existing.def.macros = res.def.macros; - existing.import = import || res.import; changed = true; } - if existing.def.is_none() && res.def.is_none() && !existing.import && res.import { - existing.import = res.import; - } changed } @@ -152,7 +144,6 @@ impl ItemScope { pub struct Resolution { /// None for unresolved pub def: PerNs, - pub(crate) import: bool, } impl From for PerNs { diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 745e31c0d..3706c1223 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -218,7 +218,7 @@ where self.update( self.def_map.root, None, - &[(name, Resolution { def: PerNs::macros(macro_), import: false })], + &[(name, Resolution { def: PerNs::macros(macro_) })], ); } } @@ -401,10 +401,8 @@ where .map(|(local_id, variant_data)| { let name = variant_data.name.clone(); let variant = EnumVariantId { parent: e, local_id }; - let res = Resolution { - def: PerNs::both(variant.into(), variant.into()), - import: true, - }; + let res = + Resolution { def: PerNs::both(variant.into(), variant.into()) }; (name, res) }) .collect::>(); @@ -430,7 +428,7 @@ where } } - let resolution = Resolution { def, import: true }; + let resolution = Resolution { def }; self.update(module_id, Some(import_id), &[(name, resolution)]); } None => tested_by!(bogus_paths), @@ -717,7 +715,7 @@ where let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; let def: ModuleDefId = module.into(); self.def_collector.def_map.modules[self.module_id].scope.define_def(def); - let resolution = Resolution { def: def.into(), import: false }; + let resolution = Resolution { def: def.into() }; self.def_collector.update(self.module_id, None, &[(name, resolution)]); res } @@ -777,7 +775,7 @@ where .into(), }; self.def_collector.def_map.modules[self.module_id].scope.define_def(def); - let resolution = Resolution { def: def.into(), import: false }; + let resolution = Resolution { def: def.into() }; self.def_collector.update(self.module_id, None, &[(name, resolution)]) } -- cgit v1.2.3 From e8da7d4061960844502e3064c33eef4a0dc3828e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 15:31:30 +0100 Subject: Remove unused parameters --- crates/ra_hir_def/src/item_scope.rs | 2 +- crates/ra_hir_def/src/nameres/collector.rs | 34 +++++++++++------------------- 2 files changed, 13 insertions(+), 23 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 81089554f..71f44b556 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -111,7 +111,7 @@ impl ItemScope { self.legacy_macros.insert(name, mac); } - pub(crate) fn push_res(&mut self, name: Name, res: &Resolution, _import: bool) -> bool { + pub(crate) fn push_res(&mut self, name: Name, res: &Resolution) -> bool { let mut changed = false; let existing = self.visible.entry(name.clone()).or_default(); diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 3706c1223..d27c3e197 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -215,11 +215,7 @@ where // In Rust, `#[macro_export]` macros are unconditionally visible at the // crate root, even if the parent modules is **not** visible. if export { - self.update( - self.def_map.root, - None, - &[(name, Resolution { def: PerNs::macros(macro_) })], - ); + self.update(self.def_map.root, &[(name, Resolution { def: PerNs::macros(macro_) })]); } } @@ -373,7 +369,7 @@ where // Module scoped macros is included let items = scope.collect_resolutions(); - self.update(module_id, Some(import_id), &items); + self.update(module_id, &items); } else { // glob import from same crate => we do an initial // import, and then need to propagate any further @@ -383,7 +379,7 @@ where // Module scoped macros is included let items = scope.collect_resolutions(); - self.update(module_id, Some(import_id), &items); + self.update(module_id, &items); // record the glob import in case we add further items let glob = self.glob_imports.entry(m.local_id).or_default(); if !glob.iter().any(|it| *it == (module_id, import_id)) { @@ -406,7 +402,7 @@ where (name, res) }) .collect::>(); - self.update(module_id, Some(import_id), &resolutions); + self.update(module_id, &resolutions); } Some(d) => { log::debug!("glob import {:?} from non-module/enum {:?}", import, d); @@ -429,26 +425,20 @@ where } let resolution = Resolution { def }; - self.update(module_id, Some(import_id), &[(name, resolution)]); + self.update(module_id, &[(name, resolution)]); } None => tested_by!(bogus_paths), } } } - fn update( - &mut self, - module_id: LocalModuleId, - import: Option, - resolutions: &[(Name, Resolution)], - ) { - self.update_recursive(module_id, import, resolutions, 0) + fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, Resolution)]) { + self.update_recursive(module_id, resolutions, 0) } fn update_recursive( &mut self, module_id: LocalModuleId, - import: Option, resolutions: &[(Name, Resolution)], depth: usize, ) { @@ -459,7 +449,7 @@ where let scope = &mut self.def_map.modules[module_id].scope; let mut changed = false; for (name, res) in resolutions { - changed |= scope.push_res(name.clone(), res, import.is_some()); + changed |= scope.push_res(name.clone(), res); } if !changed { @@ -472,9 +462,9 @@ where .flat_map(|v| v.iter()) .cloned() .collect::>(); - for (glob_importing_module, glob_import) in glob_imports { + for (glob_importing_module, _glob_import) in glob_imports { // We pass the glob import so that the tracked import in those modules is that glob import - self.update_recursive(glob_importing_module, Some(glob_import), resolutions, depth + 1); + self.update_recursive(glob_importing_module, resolutions, depth + 1); } } @@ -716,7 +706,7 @@ where let def: ModuleDefId = module.into(); self.def_collector.def_map.modules[self.module_id].scope.define_def(def); let resolution = Resolution { def: def.into() }; - self.def_collector.update(self.module_id, None, &[(name, resolution)]); + self.def_collector.update(self.module_id, &[(name, resolution)]); res } @@ -776,7 +766,7 @@ where }; self.def_collector.def_map.modules[self.module_id].scope.define_def(def); let resolution = Resolution { def: def.into() }; - self.def_collector.update(self.module_id, None, &[(name, resolution)]) + self.def_collector.update(self.module_id, &[(name, resolution)]) } fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { -- cgit v1.2.3 From 6c3ddcfa501060cff3a7f81c179f712ef072c808 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 15:37:07 +0100 Subject: Simplify --- crates/ra_hir_def/src/body/scope.rs | 4 +-- crates/ra_hir_def/src/item_scope.rs | 44 ++++++++++-------------- crates/ra_hir_def/src/nameres/collector.rs | 19 ++++------ crates/ra_hir_def/src/nameres/path_resolution.rs | 12 +++---- crates/ra_hir_def/src/nameres/tests.rs | 10 +++--- crates/ra_hir_def/src/resolver.rs | 8 ++--- 6 files changed, 40 insertions(+), 57 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/scope.rs b/crates/ra_hir_def/src/body/scope.rs index ab6599b23..a63552327 100644 --- a/crates/ra_hir_def/src/body/scope.rs +++ b/crates/ra_hir_def/src/body/scope.rs @@ -183,8 +183,8 @@ mod tests { let crate_def_map = db.crate_def_map(krate); let module = crate_def_map.modules_for_file(file_id).next().unwrap(); - let (_, res) = crate_def_map[module].scope.entries().next().unwrap(); - match res.def.take_values().unwrap() { + let (_, def) = crate_def_map[module].scope.entries().next().unwrap(); + match def.take_values().unwrap() { ModuleDefId::FunctionId(it) => it, _ => panic!(), } diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 71f44b556..f1adc3b58 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -9,7 +9,7 @@ use crate::{per_ns::PerNs, AdtId, BuiltinType, ImplId, MacroDefId, ModuleDefId, #[derive(Debug, Default, PartialEq, Eq)] pub struct ItemScope { - visible: FxHashMap, + visible: FxHashMap, defs: Vec, impls: Vec, /// Macros visible in current module in legacy textual scope @@ -27,10 +27,10 @@ pub struct ItemScope { legacy_macros: FxHashMap, } -static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { +static BUILTIN_SCOPE: Lazy> = Lazy::new(|| { BuiltinType::ALL .iter() - .map(|(name, ty)| (name.clone(), Resolution { def: PerNs::types(ty.clone().into()) })) + .map(|(name, ty)| (name.clone(), PerNs::types(ty.clone().into()))) .collect() }); @@ -46,9 +46,9 @@ pub(crate) enum BuiltinShadowMode { /// Legacy macros can only be accessed through special methods like `get_legacy_macros`. /// Other methods will only resolve values, types and module scoped macros only. impl ItemScope { - pub fn entries<'a>(&'a self) -> impl Iterator + 'a { + pub fn entries<'a>(&'a self) -> impl Iterator + 'a { //FIXME: shadowing - self.visible.iter().chain(BUILTIN_SCOPE.iter()) + self.visible.iter().chain(BUILTIN_SCOPE.iter()).map(|(n, def)| (n, *def)) } pub fn declarations(&self) -> impl Iterator + '_ { @@ -61,9 +61,7 @@ impl ItemScope { /// Iterate over all module scoped macros pub(crate) fn macros<'a>(&'a self) -> impl Iterator + 'a { - self.visible - .iter() - .filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_))) + self.visible.iter().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_))) } /// Iterate over all legacy textual scoped macros visible at the end of the module @@ -72,13 +70,13 @@ impl ItemScope { } /// Get a name from current module scope, legacy macros are not included - pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> { + pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&PerNs> { match shadow { BuiltinShadowMode::Module => self.visible.get(name).or_else(|| BUILTIN_SCOPE.get(name)), BuiltinShadowMode::Other => { let item = self.visible.get(name); - if let Some(res) = item { - if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() { + if let Some(def) = item { + if let Some(ModuleDefId::ModuleId(_)) = def.take_types() { return BUILTIN_SCOPE.get(name).or(item); } } @@ -89,7 +87,7 @@ impl ItemScope { } pub(crate) fn traits<'a>(&'a self) -> impl Iterator + 'a { - self.visible.values().filter_map(|r| match r.def.take_types() { + self.visible.values().filter_map(|def| match def.take_types() { Some(ModuleDefId::TraitId(t)) => Some(t), _ => None, }) @@ -111,27 +109,27 @@ impl ItemScope { self.legacy_macros.insert(name, mac); } - pub(crate) fn push_res(&mut self, name: Name, res: &Resolution) -> bool { + pub(crate) fn push_res(&mut self, name: Name, def: &PerNs) -> bool { let mut changed = false; let existing = self.visible.entry(name.clone()).or_default(); - if existing.def.types.is_none() && res.def.types.is_some() { - existing.def.types = res.def.types; + if existing.types.is_none() && def.types.is_some() { + existing.types = def.types; changed = true; } - if existing.def.values.is_none() && res.def.values.is_some() { - existing.def.values = res.def.values; + if existing.values.is_none() && def.values.is_some() { + existing.values = def.values; changed = true; } - if existing.def.macros.is_none() && res.def.macros.is_some() { - existing.def.macros = res.def.macros; + if existing.macros.is_none() && def.macros.is_some() { + existing.macros = def.macros; changed = true; } changed } - pub(crate) fn collect_resolutions(&self) -> Vec<(Name, Resolution)> { + pub(crate) fn collect_resolutions(&self) -> Vec<(Name, PerNs)> { self.visible.iter().map(|(name, res)| (name.clone(), res.clone())).collect() } @@ -140,12 +138,6 @@ impl ItemScope { } } -#[derive(Debug, Clone, PartialEq, Eq, Default)] -pub struct Resolution { - /// None for unresolved - pub def: PerNs, -} - impl From for PerNs { fn from(def: ModuleDefId) -> PerNs { match def { diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index d27c3e197..4f1fd4801 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -18,7 +18,6 @@ use test_utils::tested_by; use crate::{ attr::Attrs, db::DefDatabase, - item_scope::Resolution, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, @@ -215,7 +214,7 @@ where // In Rust, `#[macro_export]` macros are unconditionally visible at the // crate root, even if the parent modules is **not** visible. if export { - self.update(self.def_map.root, &[(name, Resolution { def: PerNs::macros(macro_) })]); + self.update(self.def_map.root, &[(name, PerNs::macros(macro_))]); } } @@ -397,8 +396,7 @@ where .map(|(local_id, variant_data)| { let name = variant_data.name.clone(); let variant = EnumVariantId { parent: e, local_id }; - let res = - Resolution { def: PerNs::both(variant.into(), variant.into()) }; + let res = PerNs::both(variant.into(), variant.into()); (name, res) }) .collect::>(); @@ -424,22 +422,21 @@ where } } - let resolution = Resolution { def }; - self.update(module_id, &[(name, resolution)]); + self.update(module_id, &[(name, def)]); } None => tested_by!(bogus_paths), } } } - fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, Resolution)]) { + fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, PerNs)]) { self.update_recursive(module_id, resolutions, 0) } fn update_recursive( &mut self, module_id: LocalModuleId, - resolutions: &[(Name, Resolution)], + resolutions: &[(Name, PerNs)], depth: usize, ) { if depth > 100 { @@ -705,8 +702,7 @@ where let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; let def: ModuleDefId = module.into(); self.def_collector.def_map.modules[self.module_id].scope.define_def(def); - let resolution = Resolution { def: def.into() }; - self.def_collector.update(self.module_id, &[(name, resolution)]); + self.def_collector.update(self.module_id, &[(name, def.into())]); res } @@ -765,8 +761,7 @@ where .into(), }; self.def_collector.def_map.modules[self.module_id].scope.define_def(def); - let resolution = Resolution { def: def.into() }; - self.def_collector.update(self.module_id, &[(name, resolution)]) + self.def_collector.update(self.module_id, &[(name, def.into())]) } fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 2dd779b66..378d49455 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -181,7 +181,7 @@ impl CrateDefMap { // Since it is a qualified path here, it should not contains legacy macros match self[module.local_id].scope.get(&segment, prefer_module(i)) { - Some(res) => res.def, + Some(def) => *def, _ => { log::debug!("path segment {:?} not found", segment); return ResolvePathResult::empty(ReachedFixedPoint::No); @@ -243,8 +243,7 @@ impl CrateDefMap { // - std prelude let from_legacy_macro = self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); - let from_scope = - self[module].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def); + let from_scope = self[module].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none); let from_extern_prelude = self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); let from_prelude = self.resolve_in_prelude(db, name, shadow); @@ -258,7 +257,7 @@ impl CrateDefMap { shadow: BuiltinShadowMode, ) -> PerNs { let from_crate_root = - self[self.root].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def); + self[self.root].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none); let from_extern_prelude = self.resolve_name_in_extern_prelude(name); from_crate_root.or(from_extern_prelude) @@ -279,10 +278,7 @@ impl CrateDefMap { keep = db.crate_def_map(prelude.krate); &keep }; - def_map[prelude.local_id] - .scope - .get(name, shadow) - .map_or_else(PerNs::none, |res| res.def) + def_map[prelude.local_id].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none) } else { PerNs::none() } diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs index 4e968bcc8..ff474b53b 100644 --- a/crates/ra_hir_def/src/nameres/tests.rs +++ b/crates/ra_hir_def/src/nameres/tests.rs @@ -35,19 +35,19 @@ fn render_crate_def_map(map: &CrateDefMap) -> String { let mut entries = map.modules[module].scope.collect_resolutions(); entries.sort_by_key(|(name, _)| name.clone()); - for (name, res) in entries { + for (name, def) in entries { *buf += &format!("{}:", name); - if res.def.types.is_some() { + if def.types.is_some() { *buf += " t"; } - if res.def.values.is_some() { + if def.values.is_some() { *buf += " v"; } - if res.def.macros.is_some() { + if def.macros.is_some() { *buf += " m"; } - if res.def.is_none() { + if def.is_none() { *buf += " _"; } diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index 83013fed3..e70049617 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -413,8 +413,8 @@ impl Scope { // def: m.module.into(), // }), // ); - m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { - f(name.clone(), ScopeDef::PerNs(res.def)); + m.crate_def_map[m.module_id].scope.entries().for_each(|(name, def)| { + f(name.clone(), ScopeDef::PerNs(def)); }); m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); @@ -424,8 +424,8 @@ impl Scope { }); if let Some(prelude) = m.crate_def_map.prelude { let prelude_def_map = db.crate_def_map(prelude.krate); - prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, res)| { - f(name.clone(), ScopeDef::PerNs(res.def)); + prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| { + f(name.clone(), ScopeDef::PerNs(def)); }); } } -- cgit v1.2.3 From baee74618524ad75819163d701ff9e6fe9883e95 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 15:49:39 +0100 Subject: Share impl Scope between modules and blocks --- crates/ra_hir_def/src/body.rs | 5 +- crates/ra_hir_def/src/body/lower.rs | 4 +- crates/ra_hir_def/src/child_by_source.rs | 100 ++++++++++++++++--------------- 3 files changed, 56 insertions(+), 53 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs index 148ff007e..d3e4c50ae 100644 --- a/crates/ra_hir_def/src/body.rs +++ b/crates/ra_hir_def/src/body.rs @@ -19,10 +19,11 @@ use crate::{ db::DefDatabase, expr::{Expr, ExprId, Pat, PatId}, item_scope::BuiltinShadowMode, + item_scope::ItemScope, nameres::CrateDefMap, path::{ModPath, Path}, src::HasSource, - DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, + DefWithBodyId, HasModule, Lookup, ModuleId, }; pub(crate) struct Expander { @@ -135,7 +136,7 @@ pub struct Body { pub params: Vec, /// The `ExprId` of the actual body expression. pub body_expr: ExprId, - pub defs: Vec, + pub item_scope: ItemScope, } pub type ExprPtr = Either, AstPtr>; diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index be5d17d85..754924050 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -46,7 +46,7 @@ pub(super) fn lower( pats: Arena::default(), params: Vec::new(), body_expr: ExprId::dummy(), - defs: Vec::new(), + item_scope: Default::default(), }, } .collect(params, body) @@ -532,7 +532,7 @@ where | ast::ModuleItem::ExternCrateItem(_) | ast::ModuleItem::Module(_) => continue, }; - self.body.defs.push(def) + self.body.item_scope.define_def(def) } } diff --git a/crates/ra_hir_def/src/child_by_source.rs b/crates/ra_hir_def/src/child_by_source.rs index 4488e8502..8b6c773ee 100644 --- a/crates/ra_hir_def/src/child_by_source.rs +++ b/crates/ra_hir_def/src/child_by_source.rs @@ -9,6 +9,7 @@ use either::Either; use crate::{ db::DefDatabase, dyn_map::DynMap, + item_scope::ItemScope, keys, src::{HasChildSource, HasSource}, AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, ImplId, Lookup, ModuleDefId, @@ -73,59 +74,62 @@ impl ChildBySource for ImplId { impl ChildBySource for ModuleId { fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { - let mut res = DynMap::default(); - let crate_def_map = db.crate_def_map(self.krate); let module_data = &crate_def_map[self.local_id]; - - module_data.scope.declarations().for_each(|item| add_module_def(db, &mut res, item)); - - for imp in module_data.scope.impls() { - let src = imp.lookup(db).source(db); - res[keys::IMPL].insert(src, imp) - } - - res + module_data.scope.child_by_source(db) } } -fn add_module_def(db: &impl DefDatabase, map: &mut DynMap, item: ModuleDefId) { - match item { - ModuleDefId::FunctionId(func) => { - let src = func.lookup(db).source(db); - map[keys::FUNCTION].insert(src, func) - } - ModuleDefId::ConstId(konst) => { - let src = konst.lookup(db).source(db); - map[keys::CONST].insert(src, konst) - } - ModuleDefId::StaticId(statik) => { - let src = statik.lookup(db).source(db); - map[keys::STATIC].insert(src, statik) - } - ModuleDefId::TypeAliasId(ty) => { - let src = ty.lookup(db).source(db); - map[keys::TYPE_ALIAS].insert(src, ty) +impl ChildBySource for ItemScope { + fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { + let mut res = DynMap::default(); + self.declarations().for_each(|item| add_module_def(db, &mut res, item)); + self.impls().for_each(|imp| add_impl(db, &mut res, imp)); + return res; + + fn add_module_def(db: &impl DefDatabase, map: &mut DynMap, item: ModuleDefId) { + match item { + ModuleDefId::FunctionId(func) => { + let src = func.lookup(db).source(db); + map[keys::FUNCTION].insert(src, func) + } + ModuleDefId::ConstId(konst) => { + let src = konst.lookup(db).source(db); + map[keys::CONST].insert(src, konst) + } + ModuleDefId::StaticId(statik) => { + let src = statik.lookup(db).source(db); + map[keys::STATIC].insert(src, statik) + } + ModuleDefId::TypeAliasId(ty) => { + let src = ty.lookup(db).source(db); + map[keys::TYPE_ALIAS].insert(src, ty) + } + ModuleDefId::TraitId(trait_) => { + let src = trait_.lookup(db).source(db); + map[keys::TRAIT].insert(src, trait_) + } + ModuleDefId::AdtId(adt) => match adt { + AdtId::StructId(strukt) => { + let src = strukt.lookup(db).source(db); + map[keys::STRUCT].insert(src, strukt) + } + AdtId::UnionId(union_) => { + let src = union_.lookup(db).source(db); + map[keys::UNION].insert(src, union_) + } + AdtId::EnumId(enum_) => { + let src = enum_.lookup(db).source(db); + map[keys::ENUM].insert(src, enum_) + } + }, + _ => (), + } } - ModuleDefId::TraitId(trait_) => { - let src = trait_.lookup(db).source(db); - map[keys::TRAIT].insert(src, trait_) + fn add_impl(db: &impl DefDatabase, map: &mut DynMap, imp: ImplId) { + let src = imp.lookup(db).source(db); + map[keys::IMPL].insert(src, imp) } - ModuleDefId::AdtId(adt) => match adt { - AdtId::StructId(strukt) => { - let src = strukt.lookup(db).source(db); - map[keys::STRUCT].insert(src, strukt) - } - AdtId::UnionId(union_) => { - let src = union_.lookup(db).source(db); - map[keys::UNION].insert(src, union_) - } - AdtId::EnumId(enum_) => { - let src = enum_.lookup(db).source(db); - map[keys::ENUM].insert(src, enum_) - } - }, - _ => (), } } @@ -167,9 +171,7 @@ impl ChildBySource for EnumId { impl ChildBySource for DefWithBodyId { fn child_by_source(&self, db: &impl DefDatabase) -> DynMap { - let mut res = DynMap::default(); let body = db.body(*self); - body.defs.iter().copied().for_each(|item| add_module_def(db, &mut res, item)); - res + body.item_scope.child_by_source(db) } } -- cgit v1.2.3 From 007032f8504be1274972e4f23afaf0bc431d92d5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 19:31:01 +0100 Subject: Refactor --- crates/ra_hir_def/src/item_scope.rs | 12 +++++++----- crates/ra_hir_def/src/nameres/path_resolution.rs | 9 ++++----- 2 files changed, 11 insertions(+), 10 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index f1adc3b58..08d788cc9 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -70,18 +70,20 @@ impl ItemScope { } /// Get a name from current module scope, legacy macros are not included - pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&PerNs> { + pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option { match shadow { - BuiltinShadowMode::Module => self.visible.get(name).or_else(|| BUILTIN_SCOPE.get(name)), + BuiltinShadowMode::Module => { + self.visible.get(name).or_else(|| BUILTIN_SCOPE.get(name)).copied() + } BuiltinShadowMode::Other => { - let item = self.visible.get(name); + let item = self.visible.get(name).copied(); if let Some(def) = item { if let Some(ModuleDefId::ModuleId(_)) = def.take_types() { - return BUILTIN_SCOPE.get(name).or(item); + return BUILTIN_SCOPE.get(name).copied().or(item); } } - item.or_else(|| BUILTIN_SCOPE.get(name)) + item.or_else(|| BUILTIN_SCOPE.get(name).copied()) } } } diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 378d49455..9b85ae018 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -181,7 +181,7 @@ impl CrateDefMap { // Since it is a qualified path here, it should not contains legacy macros match self[module.local_id].scope.get(&segment, prefer_module(i)) { - Some(def) => *def, + Some(def) => def, _ => { log::debug!("path segment {:?} not found", segment); return ResolvePathResult::empty(ReachedFixedPoint::No); @@ -243,7 +243,7 @@ impl CrateDefMap { // - std prelude let from_legacy_macro = self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); - let from_scope = self[module].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none); + let from_scope = self[module].scope.get(name, shadow).unwrap_or_else(PerNs::none); let from_extern_prelude = self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); let from_prelude = self.resolve_in_prelude(db, name, shadow); @@ -256,8 +256,7 @@ impl CrateDefMap { name: &Name, shadow: BuiltinShadowMode, ) -> PerNs { - let from_crate_root = - self[self.root].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none); + let from_crate_root = self[self.root].scope.get(name, shadow).unwrap_or_else(PerNs::none); let from_extern_prelude = self.resolve_name_in_extern_prelude(name); from_crate_root.or(from_extern_prelude) @@ -278,7 +277,7 @@ impl CrateDefMap { keep = db.crate_def_map(prelude.krate); &keep }; - def_map[prelude.local_id].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none) + def_map[prelude.local_id].scope.get(name, shadow).unwrap_or_else(PerNs::none) } else { PerNs::none() } -- cgit v1.2.3 From 7c405c01567e814f18ebf8bdc6aa1f8f694919f0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 19:32:35 +0100 Subject: Simplify --- crates/ra_hir_def/src/item_scope.rs | 19 +++++++++++++------ crates/ra_hir_def/src/nameres/path_resolution.rs | 14 ++++---------- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index 08d788cc9..e8ddcc3c2 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -70,20 +70,27 @@ impl ItemScope { } /// Get a name from current module scope, legacy macros are not included - pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option { + pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> PerNs { match shadow { - BuiltinShadowMode::Module => { - self.visible.get(name).or_else(|| BUILTIN_SCOPE.get(name)).copied() - } + BuiltinShadowMode::Module => self + .visible + .get(name) + .or_else(|| BUILTIN_SCOPE.get(name)) + .copied() + .unwrap_or_else(PerNs::none), BuiltinShadowMode::Other => { let item = self.visible.get(name).copied(); if let Some(def) = item { if let Some(ModuleDefId::ModuleId(_)) = def.take_types() { - return BUILTIN_SCOPE.get(name).copied().or(item); + return BUILTIN_SCOPE + .get(name) + .copied() + .or(item) + .unwrap_or_else(PerNs::none); } } - item.or_else(|| BUILTIN_SCOPE.get(name).copied()) + item.or_else(|| BUILTIN_SCOPE.get(name).copied()).unwrap_or_else(PerNs::none) } } } diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs index 9b85ae018..695014c7b 100644 --- a/crates/ra_hir_def/src/nameres/path_resolution.rs +++ b/crates/ra_hir_def/src/nameres/path_resolution.rs @@ -180,13 +180,7 @@ impl CrateDefMap { } // Since it is a qualified path here, it should not contains legacy macros - match self[module.local_id].scope.get(&segment, prefer_module(i)) { - Some(def) => def, - _ => { - log::debug!("path segment {:?} not found", segment); - return ResolvePathResult::empty(ReachedFixedPoint::No); - } - } + self[module.local_id].scope.get(&segment, prefer_module(i)) } ModuleDefId::AdtId(AdtId::EnumId(e)) => { // enum variant @@ -243,7 +237,7 @@ impl CrateDefMap { // - std prelude let from_legacy_macro = self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); - let from_scope = self[module].scope.get(name, shadow).unwrap_or_else(PerNs::none); + let from_scope = self[module].scope.get(name, shadow); let from_extern_prelude = self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); let from_prelude = self.resolve_in_prelude(db, name, shadow); @@ -256,7 +250,7 @@ impl CrateDefMap { name: &Name, shadow: BuiltinShadowMode, ) -> PerNs { - let from_crate_root = self[self.root].scope.get(name, shadow).unwrap_or_else(PerNs::none); + let from_crate_root = self[self.root].scope.get(name, shadow); let from_extern_prelude = self.resolve_name_in_extern_prelude(name); from_crate_root.or(from_extern_prelude) @@ -277,7 +271,7 @@ impl CrateDefMap { keep = db.crate_def_map(prelude.krate); &keep }; - def_map[prelude.local_id].scope.get(name, shadow).unwrap_or_else(PerNs::none) + def_map[prelude.local_id].scope.get(name, shadow) } else { PerNs::none() } -- cgit v1.2.3 From e424545c0f5cbaf135c52764169ea20df7d07d35 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 22 Dec 2019 20:12:23 +0100 Subject: Rudimentary name resolution for local items --- crates/ra_hir_def/src/body/lower.rs | 32 ++++++--- crates/ra_hir_def/src/item_scope.rs | 8 ++- crates/ra_hir_def/src/nameres/collector.rs | 2 +- crates/ra_hir_def/src/resolver.rs | 103 ++++++++++++++++++++--------- 4 files changed, 102 insertions(+), 43 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 754924050..5323af097 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -494,45 +494,57 @@ where fn collect_block_items(&mut self, block: &ast::Block) { let container = ContainerId::DefWithBodyId(self.def); for item in block.items() { - let def: ModuleDefId = match item { + let (def, name): (ModuleDefId, Option) = match item { ast::ModuleItem::FnDef(def) => { let ast_id = self.expander.ast_id(&def); - FunctionLoc { container: container.into(), ast_id }.intern(self.db).into() + ( + FunctionLoc { container: container.into(), ast_id }.intern(self.db).into(), + def.name(), + ) } ast::ModuleItem::TypeAliasDef(def) => { let ast_id = self.expander.ast_id(&def); - TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into() + ( + TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into(), + def.name(), + ) } ast::ModuleItem::ConstDef(def) => { let ast_id = self.expander.ast_id(&def); - ConstLoc { container: container.into(), ast_id }.intern(self.db).into() + ( + ConstLoc { container: container.into(), ast_id }.intern(self.db).into(), + def.name(), + ) } ast::ModuleItem::StaticDef(def) => { let ast_id = self.expander.ast_id(&def); - StaticLoc { container, ast_id }.intern(self.db).into() + (StaticLoc { container, ast_id }.intern(self.db).into(), def.name()) } ast::ModuleItem::StructDef(def) => { let ast_id = self.expander.ast_id(&def); - StructLoc { container, ast_id }.intern(self.db).into() + (StructLoc { container, ast_id }.intern(self.db).into(), def.name()) } ast::ModuleItem::EnumDef(def) => { let ast_id = self.expander.ast_id(&def); - EnumLoc { container, ast_id }.intern(self.db).into() + (EnumLoc { container, ast_id }.intern(self.db).into(), def.name()) } ast::ModuleItem::UnionDef(def) => { let ast_id = self.expander.ast_id(&def); - UnionLoc { container, ast_id }.intern(self.db).into() + (UnionLoc { container, ast_id }.intern(self.db).into(), def.name()) } ast::ModuleItem::TraitDef(def) => { let ast_id = self.expander.ast_id(&def); - TraitLoc { container, ast_id }.intern(self.db).into() + (TraitLoc { container, ast_id }.intern(self.db).into(), def.name()) } ast::ModuleItem::ImplBlock(_) | ast::ModuleItem::UseItem(_) | ast::ModuleItem::ExternCrateItem(_) | ast::ModuleItem::Module(_) => continue, }; - self.body.item_scope.define_def(def) + self.body.item_scope.define_def(def); + if let Some(name) = name { + self.body.item_scope.push_res(name.as_name(), def.into()); + } } } diff --git a/crates/ra_hir_def/src/item_scope.rs b/crates/ra_hir_def/src/item_scope.rs index e8ddcc3c2..b0288ee8d 100644 --- a/crates/ra_hir_def/src/item_scope.rs +++ b/crates/ra_hir_def/src/item_scope.rs @@ -51,6 +51,12 @@ impl ItemScope { self.visible.iter().chain(BUILTIN_SCOPE.iter()).map(|(n, def)| (n, *def)) } + pub fn entries_without_primitives<'a>( + &'a self, + ) -> impl Iterator + 'a { + self.visible.iter().map(|(n, def)| (n, *def)) + } + pub fn declarations(&self) -> impl Iterator + '_ { self.defs.iter().copied() } @@ -118,7 +124,7 @@ impl ItemScope { self.legacy_macros.insert(name, mac); } - pub(crate) fn push_res(&mut self, name: Name, def: &PerNs) -> bool { + pub(crate) fn push_res(&mut self, name: Name, def: PerNs) -> bool { let mut changed = false; let existing = self.visible.entry(name.clone()).or_default(); diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 4f1fd4801..b9f40d3dd 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -446,7 +446,7 @@ where let scope = &mut self.def_map.modules[module_id].scope; let mut changed = false; for (name, res) in resolutions { - changed |= scope.push_res(name.clone(), res); + changed |= scope.push_res(name.clone(), *res); } if !changed { diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs index e70049617..cf3c33d78 100644 --- a/crates/ra_hir_def/src/resolver.rs +++ b/crates/ra_hir_def/src/resolver.rs @@ -10,6 +10,7 @@ use rustc_hash::FxHashSet; use crate::{ body::scope::{ExprScopes, ScopeId}, + body::Body, builtin_type::BuiltinType, db::DefDatabase, expr::{ExprId, PatId}, @@ -55,6 +56,8 @@ enum Scope { AdtScope(AdtId), /// Local bindings ExprScope(ExprScope), + /// Temporary hack to support local items. + LocalItemsScope(Arc), } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -149,7 +152,13 @@ impl Resolver { for scope in self.scopes.iter().rev() { match scope { Scope::ExprScope(_) => continue, - Scope::GenericParams { .. } | Scope::ImplBlockScope(_) if skip_to_mod => continue, + Scope::GenericParams { .. } + | Scope::ImplBlockScope(_) + | Scope::LocalItemsScope(_) + if skip_to_mod => + { + continue + } Scope::GenericParams { params, def } => { if let Some(local_id) = params.find_by_name(first_name) { @@ -179,25 +188,35 @@ impl Resolver { &path, BuiltinShadowMode::Other, ); - let res = match module_def.take_types()? { - ModuleDefId::AdtId(it) => TypeNs::AdtId(it), - ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), - - ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), - ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), - - ModuleDefId::TraitId(it) => TypeNs::TraitId(it), - - ModuleDefId::FunctionId(_) - | ModuleDefId::ConstId(_) - | ModuleDefId::StaticId(_) - | ModuleDefId::ModuleId(_) => return None, - }; + let res = to_type_ns(module_def)?; return Some((res, idx)); } + Scope::LocalItemsScope(body) => { + let def = body.item_scope.get(first_name, BuiltinShadowMode::Other); + if let Some(res) = to_type_ns(def) { + return Some((res, None)); + } + } } } - None + return None; + fn to_type_ns(per_ns: PerNs) -> Option { + let res = match per_ns.take_types()? { + ModuleDefId::AdtId(it) => TypeNs::AdtId(it), + ModuleDefId::EnumVariantId(it) => TypeNs::EnumVariantId(it), + + ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), + ModuleDefId::BuiltinType(it) => TypeNs::BuiltinType(it), + + ModuleDefId::TraitId(it) => TypeNs::TraitId(it), + + ModuleDefId::FunctionId(_) + | ModuleDefId::ConstId(_) + | ModuleDefId::StaticId(_) + | ModuleDefId::ModuleId(_) => return None, + }; + Some(res) + } } pub fn resolve_path_in_type_ns_fully( @@ -227,6 +246,7 @@ impl Resolver { | Scope::ExprScope(_) | Scope::GenericParams { .. } | Scope::ImplBlockScope(_) + | Scope::LocalItemsScope(_) if skip_to_mod => { continue @@ -276,20 +296,7 @@ impl Resolver { ); return match idx { None => { - let value = match module_def.take_values()? { - 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(_)) - | ModuleDefId::TraitId(_) - | ModuleDefId::TypeAliasId(_) - | ModuleDefId::BuiltinType(_) - | ModuleDefId::ModuleId(_) => return None, - }; + let value = to_value_ns(module_def)?; Some(ResolveValueResult::ValueNs(value)) } Some(idx) => { @@ -309,9 +316,33 @@ impl Resolver { } }; } + Scope::LocalItemsScope(body) => { + let def = body.item_scope.get(first_name, BuiltinShadowMode::Other); + if let Some(res) = to_value_ns(def) { + return Some(ResolveValueResult::ValueNs(res)); + } + } } } - None + return None; + + fn to_value_ns(per_ns: PerNs) -> Option { + let res = match per_ns.take_values()? { + 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(_)) + | ModuleDefId::TraitId(_) + | ModuleDefId::TypeAliasId(_) + | ModuleDefId::BuiltinType(_) + | ModuleDefId::ModuleId(_) => return None, + }; + Some(res) + } } pub fn resolve_path_in_value_ns_fully( @@ -429,6 +460,11 @@ impl Scope { }); } } + Scope::LocalItemsScope(body) => { + body.item_scope.entries_without_primitives().for_each(|(name, def)| { + f(name.clone(), ScopeDef::PerNs(def)); + }) + } Scope::GenericParams { params, def } => { for (local_id, param) in params.types.iter() { f( @@ -464,6 +500,7 @@ pub fn resolver_for_scope( scope_id: Option, ) -> Resolver { let mut r = owner.resolver(db); + r = r.push_local_items_scope(db.body(owner)); let scopes = db.expr_scopes(owner); let scope_chain = scopes.scope_chain(scope_id).collect::>(); for scope in scope_chain.into_iter().rev() { @@ -499,6 +536,10 @@ impl Resolver { self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id })) } + fn push_local_items_scope(self, body: Arc) -> Resolver { + self.push_scope(Scope::LocalItemsScope(body)) + } + fn push_expr_scope( self, owner: DefWithBodyId, -- cgit v1.2.3