From 3fb88e95aa5e122a521beec766d5b1264ca4de3b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Mar 2019 18:35:14 +0300 Subject: switch modules to new diagnostics --- crates/ra_hir/src/nameres/collector.rs | 63 ++++++++++++++++------------------ 1 file changed, 29 insertions(+), 34 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index c5b73cfbe..bc6bc5e7f 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -6,9 +6,9 @@ use ra_db::FileId; use crate::{ Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, - DefDatabase, HirFileId, Name, Path, Problem, Crate, + DefDatabase, HirFileId, Name, Path, Crate, KnownName, - nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw}, + nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw, DefDiagnostic}, ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, }; @@ -405,25 +405,27 @@ where raw::ModuleData::Declaration { name, source_item_id } => { let source_item_id = source_item_id.with_file_id(self.file_id); let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); - let (file_ids, problem) = - resolve_submodule(self.def_collector.db, self.file_id, name, is_root); - - if let Some(problem) = problem { - self.def_collector.def_map.problems.add(source_item_id, problem) - } - - if let Some(&file_id) = file_ids.first() { - let module_id = - self.push_child_module(name.clone(), source_item_id, Some(file_id)); - let raw_items = self.def_collector.db.raw_items(file_id); - ModCollector { - def_collector: &mut *self.def_collector, - module_id, - file_id: file_id.into(), - raw_items: &raw_items, + match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { + Ok(file_id) => { + let module_id = + self.push_child_module(name.clone(), source_item_id, Some(file_id)); + let raw_items = self.def_collector.db.raw_items(file_id); + ModCollector { + def_collector: &mut *self.def_collector, + module_id, + file_id: file_id.into(), + raw_items: &raw_items, + } + .collect(raw_items.items()) } - .collect(raw_items.items()) - } + Err(candidate) => self.def_collector.def_map.diagnostics.push( + DefDiagnostic::UnresolvedModule { + module: self.module_id, + declaration: source_item_id, + candidate, + }, + ), + }; } } } @@ -524,7 +526,7 @@ fn resolve_submodule( file_id: HirFileId, name: &Name, is_root: bool, -) -> (Vec, Option) { +) -> Result { // FIXME: handle submodules of inline modules properly let file_id = file_id.original_file(db); let source_root_id = db.file_source_root(file_id); @@ -545,17 +547,10 @@ fn resolve_submodule( candidates.push(file_dir_mod.clone()); }; let sr = db.source_root(source_root_id); - let points_to = candidates - .into_iter() - .filter_map(|path| sr.files.get(&path)) - .map(|&it| it) - .collect::>(); - let problem = if points_to.is_empty() { - Some(Problem::UnresolvedModule { - candidate: if is_dir_owner { file_mod } else { file_dir_mod }, - }) - } else { - None - }; - (points_to, problem) + let mut points_to = candidates.into_iter().filter_map(|path| sr.files.get(&path)).map(|&it| it); + // FIXME: handle ambiguity + match points_to.next() { + Some(file_id) => Ok(file_id), + None => Err(if is_dir_owner { file_mod } else { file_dir_mod }), + } } -- cgit v1.2.3 From 79df62bc742afa33dcf5bedefd60860ca296b9da Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 23 Mar 2019 20:41:59 +0300 Subject: cleanup --- crates/ra_hir/src/nameres/collector.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index bc6bc5e7f..8830b4624 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -8,12 +8,15 @@ use crate::{ Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, DefDatabase, HirFileId, Name, Path, Crate, KnownName, - nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw, DefDiagnostic}, + nameres::{ + Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, + CrateDefMap, CrateModuleId, ModuleData, CrateMacroId, + diagnostics::DefDiagnostic, + raw, + }, ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, }; -use super::{CrateDefMap, CrateModuleId, ModuleData, CrateMacroId}; - pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { // populate external prelude for dep in def_map.krate.dependencies(db) { -- cgit v1.2.3 From 4c4a714328490d7f2626272663827fd51dfab0bd Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Mar 2019 11:39:47 +0300 Subject: test diagnostics --- crates/ra_hir/src/nameres/tests.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index ac9b88520..277b0757c 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs @@ -552,3 +552,21 @@ foo: v "### ); } + +#[test] +fn unresolved_module_diagnostics() { + let diagnostics = MockDatabase::with_files( + r" + //- /lib.rs + mod foo; + mod bar; + //- /foo.rs + ", + ) + .diagnostics(); + + assert_snapshot_matches!(diagnostics, @r###" +"mod bar;": unresolved module +"### + ); +} -- cgit v1.2.3 From 309716cffe93d065bcad0344b0f332425576c1e5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 25 Mar 2019 14:28:04 +0300 Subject: move tests to where they belong --- crates/ra_hir/src/nameres/tests.rs | 1 + 1 file changed, 1 insertion(+) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 277b0757c..572bd1bf7 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs @@ -560,6 +560,7 @@ fn unresolved_module_diagnostics() { //- /lib.rs mod foo; mod bar; + mod baz {} //- /foo.rs ", ) -- cgit v1.2.3 From 5270bca5f72fa65f0515be776e06d3d6a4d1efca Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Mar 2019 13:09:39 +0300 Subject: store macro def inside macro id This solves the problem of "macro expansion can't call into name resolution, because name resolution calls back into macro expansion" Because we store macro def as a part of call id, macro expansion just knows the def! --- crates/ra_hir/src/nameres/collector.rs | 93 +++++++++----------------- crates/ra_hir/src/nameres/raw.rs | 30 ++------- crates/ra_hir/src/nameres/tests/incremental.rs | 23 +++---- 3 files changed, 45 insertions(+), 101 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 8830b4624..89300d2ec 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -6,15 +6,15 @@ use ra_db::FileId; use crate::{ Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, - DefDatabase, HirFileId, Name, Path, Crate, + DefDatabase, HirFileId, Name, Path, KnownName, nameres::{ Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, - CrateDefMap, CrateModuleId, ModuleData, CrateMacroId, + CrateDefMap, CrateModuleId, ModuleData, diagnostics::DefDiagnostic, raw, }, - ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, + ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId, MacroDefId}, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -51,8 +51,8 @@ struct DefCollector { def_map: CrateDefMap, glob_imports: FxHashMap>, unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, - unexpanded_macros: Vec<(CrateModuleId, MacroCallId, Path, tt::Subtree)>, - global_macro_scope: FxHashMap, + unexpanded_macros: Vec<(CrateModuleId, SourceItemId, Path)>, + global_macro_scope: FxHashMap, } impl<'a, DB> DefCollector<&'a DB> @@ -62,7 +62,7 @@ where fn collect(&mut self) { let crate_graph = self.db.crate_graph(); let file_id = crate_graph.crate_root(self.def_map.krate.crate_id()); - let raw_items = self.db.raw_items(file_id); + 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); ModCollector { @@ -93,14 +93,11 @@ where } } - fn define_macro(&mut self, name: Name, tt: &tt::Subtree, export: bool) { - if let Ok(rules) = mbe::MacroRules::parse(tt) { - let macro_id = self.def_map.macros.alloc(rules); - if export { - self.def_map.public_macros.insert(name.clone(), macro_id); - } - self.global_macro_scope.insert(name, macro_id); + fn define_macro(&mut self, name: Name, macro_id: MacroDefId, export: bool) { + if export { + self.def_map.public_macros.insert(name.clone(), macro_id); } + self.global_macro_scope.insert(name, macro_id); } fn resolve_imports(&mut self) -> ReachedFixedPoint { @@ -296,7 +293,7 @@ where let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); let mut resolved = Vec::new(); let mut res = ReachedFixedPoint::Yes; - macros.retain(|(module_id, call_id, path, tt)| { + macros.retain(|(module_id, source_item_id, path)| { if path.segments.len() != 2 { return true; } @@ -312,47 +309,24 @@ where res = ReachedFixedPoint::No; let def_map = self.db.crate_def_map(krate); if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() { - resolved.push((*module_id, *call_id, (krate, macro_id), tt.clone())); + let call_id = + MacroCallLoc { def: macro_id, source_item_id: *source_item_id }.id(self.db); + resolved.push((*module_id, call_id)); } false }); - for (module_id, macro_call_id, macro_def_id, arg) in resolved { - self.collect_macro_expansion(module_id, macro_call_id, macro_def_id, arg); + for (module_id, macro_call_id) in resolved { + self.collect_macro_expansion(module_id, macro_call_id); } res } - fn collect_macro_expansion( - &mut self, - module_id: CrateModuleId, - macro_call_id: MacroCallId, - macro_def_id: (Crate, CrateMacroId), - macro_arg: tt::Subtree, - ) { - let (macro_krate, macro_id) = macro_def_id; - let dm; - let rules = if macro_krate == self.def_map.krate { - &self.def_map[macro_id] - } else { - dm = self.db.crate_def_map(macro_krate); - &dm[macro_id] - }; - if let Ok(expansion) = rules.expand(¯o_arg) { - self.def_map.macro_resolutions.insert(macro_call_id, macro_def_id); - // XXX: this **does not** go through a database, because we can't - // identify macro_call without adding the whole state of name resolution - // as a parameter to the query. - // - // So, we run the queries "manually" and we must ensure that - // `db.hir_parse(macro_call_id)` returns the same source_file. - let file_id: HirFileId = macro_call_id.into(); - let source_file = mbe::token_tree_to_ast_item_list(&expansion); - - let raw_items = raw::RawItems::from_source_file(&source_file, file_id); - ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } - .collect(raw_items.items()) - } + fn collect_macro_expansion(&mut self, module_id: CrateModuleId, macro_call_id: MacroCallId) { + let file_id: HirFileId = macro_call_id.into(); + let raw_items = self.db.raw_items(file_id); + ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } + .collect(raw_items.items()) } fn finish(self) -> CrateDefMap { @@ -412,7 +386,7 @@ where Ok(file_id) => { let module_id = self.push_child_module(name.clone(), source_item_id, Some(file_id)); - let raw_items = self.def_collector.db.raw_items(file_id); + let raw_items = self.def_collector.db.raw_items(file_id.into()); ModCollector { def_collector: &mut *self.def_collector, module_id, @@ -484,38 +458,33 @@ where // Case 1: macro rules, define a macro in crate-global mutable scope if is_macro_rules(&mac.path) { if let Some(name) = &mac.name { - self.def_collector.define_macro(name.clone(), &mac.arg, mac.export) + let macro_id = MacroDefId::MacroByExample { + source_item_id: mac.source_item_id.with_file_id(self.file_id), + }; + self.def_collector.define_macro(name.clone(), macro_id, mac.export) } return; } let source_item_id = SourceItemId { file_id: self.file_id, item_id: mac.source_item_id }; - let macro_call_id = MacroCallLoc { - module: Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }, - source_item_id, - } - .id(self.def_collector.db); // Case 2: try to expand macro_rules from this crate, triggering // recursive item collection. if let Some(¯o_id) = mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) { - self.def_collector.collect_macro_expansion( - self.module_id, - macro_call_id, - (self.def_collector.def_map.krate, macro_id), - mac.arg.clone(), - ); + let macro_call_id = + MacroCallLoc { def: macro_id, source_item_id }.id(self.def_collector.db); + + self.def_collector.collect_macro_expansion(self.module_id, macro_call_id); return; } // Case 3: path to a macro from another crate, expand during name resolution self.def_collector.unexpanded_macros.push(( self.module_id, - macro_call_id, + source_item_id, mac.path.clone(), - mac.arg.clone(), )) } } diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index f8ba398ec..7a516e556 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -4,7 +4,6 @@ use std::{ }; use test_utils::tested_by; -use ra_db::FileId; use ra_arena::{Arena, impl_arena_id, RawId, map::ArenaMap}; use ra_syntax::{ AstNode, SourceFile, AstPtr, TreeArc, @@ -47,20 +46,20 @@ impl ImportSourceMap { } impl RawItems { - pub(crate) fn raw_items_query(db: &impl DefDatabase, file_id: FileId) -> Arc { + pub(crate) fn raw_items_query(db: &impl DefDatabase, 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, - file_id: FileId, + file_id: HirFileId, ) -> (Arc, Arc) { let mut collector = RawItemsCollector { raw_items: RawItems::default(), source_file_items: db.file_items(file_id.into()), source_map: ImportSourceMap::default(), }; - let source_file = db.parse(file_id); + let source_file = db.hir_parse(file_id); collector.process_module(None, &*source_file); (Arc::new(collector.raw_items), Arc::new(collector.source_map)) } @@ -68,19 +67,6 @@ impl RawItems { pub(crate) fn items(&self) -> &[RawItem] { &self.items } - - // We can't use queries during name resolution for fear of cycles, so this - // is a query-less variant of the above function. - pub(crate) fn from_source_file(source_file: &SourceFile, file_id: HirFileId) -> RawItems { - let source_file_items = SourceFileItems::from_source_file(source_file, file_id); - let mut collector = RawItemsCollector { - raw_items: RawItems::default(), - source_file_items: Arc::new(source_file_items), - source_map: ImportSourceMap::default(), - }; - collector.process_module(None, &*source_file); - collector.raw_items - } } impl Index for RawItems { @@ -173,7 +159,6 @@ pub(crate) struct MacroData { pub(crate) source_item_id: SourceFileItemId, pub(crate) path: Path, pub(crate) name: Option, - pub(crate) arg: tt::Subtree, pub(crate) export: bool, } @@ -291,18 +276,15 @@ impl RawItemsCollector { } fn add_macro(&mut self, current_module: Option, m: &ast::MacroCall) { - let (path, arg) = match ( - m.path().and_then(Path::from_ast), - m.token_tree().and_then(mbe::ast_to_token_tree), - ) { - (Some(path), Some((token_tree, _token_map))) => (path, token_tree), + let path = match m.path().and_then(Path::from_ast) { + Some(it) => it, _ => return, }; let name = m.name().map(|it| it.as_name()); let source_item_id = self.source_file_items.id_of_unchecked(m.syntax()); let export = m.has_atom_attr("macro_export"); - let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, arg, name, export }); + let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, name, export }); self.push_item(current_module, RawItem::Macro(m)); } diff --git a/crates/ra_hir/src/nameres/tests/incremental.rs b/crates/ra_hir/src/nameres/tests/incremental.rs index 698781923..a059634e2 100644 --- a/crates/ra_hir/src/nameres/tests/incremental.rs +++ b/crates/ra_hir/src/nameres/tests/incremental.rs @@ -90,34 +90,27 @@ fn adding_inner_items_should_not_invalidate_def_map() { ); } -// It would be awesome to make this work, but it's unclear how #[test] -#[ignore] -fn typing_inside_a_function_inside_a_macro_should_not_invalidate_def_map() { +fn typing_inside_a_macro_should_not_invalidate_def_map() { check_def_map_is_not_recomputed( " //- /lib.rs + macro_rules! m { + ($ident:ident) => { + struct Foo; + } + } mod foo; - use crate::foo::bar::Baz; - //- /foo/mod.rs pub mod bar; //- /foo/bar.rs <|> - salsa::query_group! { - trait Baz { - fn foo() -> i32 { 1 + 1 } - } - } + m!(X); ", " - salsa::query_group! { - trait Baz { - fn foo() -> i32 { 92 } - } - } + m!(Y); ", ); } -- cgit v1.2.3 From e4646ce0d5bc232fb525a9330bc0c64d826fd241 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Mar 2019 13:53:50 +0300 Subject: reduce visibility --- crates/ra_hir/src/nameres/raw.rs | 50 ++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 23 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 7a516e556..ee0719ee0 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -15,6 +15,10 @@ use crate::{ ids::{SourceFileItemId, SourceFileItems}, }; +/// `RawItems` is a set of top-level items in a file (except for impls). +/// +/// It is the input to name resolution algorithm. `RawItems` are not invalidated +/// on most edits. #[derive(Debug, Default, PartialEq, Eq)] pub struct RawItems { modules: Arena, @@ -31,11 +35,11 @@ pub struct ImportSourceMap { } impl ImportSourceMap { - pub(crate) fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { + fn insert(&mut self, import: ImportId, segment: &ast::PathSegment) { self.map.insert(import, AstPtr::new(segment)) } - pub fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc { + pub(crate) fn get(&self, source: &ModuleSource, import: ImportId) -> TreeArc { let file = match source { ModuleSource::SourceFile(file) => &*file, ModuleSource::Module(m) => m.syntax().ancestors().find_map(SourceFile::cast).unwrap(), @@ -64,7 +68,7 @@ impl RawItems { (Arc::new(collector.raw_items), Arc::new(collector.source_map)) } - pub(crate) fn items(&self) -> &[RawItem] { + pub(super) fn items(&self) -> &[RawItem] { &self.items } } @@ -98,7 +102,7 @@ impl Index for RawItems { } #[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub(crate) enum RawItem { +pub(super) enum RawItem { Module(Module), Import(ImportId), Def(Def), @@ -106,11 +110,11 @@ pub(crate) enum RawItem { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct Module(RawId); +pub(super) struct Module(RawId); impl_arena_id!(Module); #[derive(Debug, PartialEq, Eq)] -pub(crate) enum ModuleData { +pub(super) enum ModuleData { Declaration { name: Name, source_item_id: SourceFileItemId }, Definition { name: Name, source_item_id: SourceFileItemId, items: Vec }, } @@ -121,26 +125,26 @@ impl_arena_id!(ImportId); #[derive(Debug, Clone, PartialEq, Eq)] pub struct ImportData { - pub(crate) path: Path, - pub(crate) alias: Option, - pub(crate) is_glob: bool, - pub(crate) is_prelude: bool, - pub(crate) is_extern_crate: bool, + pub(super) path: Path, + pub(super) alias: Option, + pub(super) is_glob: bool, + pub(super) is_prelude: bool, + pub(super) is_extern_crate: bool, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct Def(RawId); +pub(super) struct Def(RawId); impl_arena_id!(Def); #[derive(Debug, PartialEq, Eq)] -pub(crate) struct DefData { - pub(crate) source_item_id: SourceFileItemId, - pub(crate) name: Name, - pub(crate) kind: DefKind, +pub(super) struct DefData { + pub(super) source_item_id: SourceFileItemId, + pub(super) name: Name, + pub(super) kind: DefKind, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub(crate) enum DefKind { +pub(super) enum DefKind { Function, Struct, Enum, @@ -151,15 +155,15 @@ pub(crate) enum DefKind { } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub(crate) struct Macro(RawId); +pub(super) struct Macro(RawId); impl_arena_id!(Macro); #[derive(Debug, PartialEq, Eq)] -pub(crate) struct MacroData { - pub(crate) source_item_id: SourceFileItemId, - pub(crate) path: Path, - pub(crate) name: Option, - pub(crate) export: bool, +pub(super) struct MacroData { + pub(super) source_item_id: SourceFileItemId, + pub(super) path: Path, + pub(super) name: Option, + pub(super) export: bool, } struct RawItemsCollector { -- cgit v1.2.3 From 0b820cacab020993b6e1667f491289122f03de04 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Mar 2019 14:40:34 +0300 Subject: move source_id to a separate file --- crates/ra_hir/src/nameres/collector.rs | 4 ++-- crates/ra_hir/src/nameres/raw.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 89300d2ec..4fb298155 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -6,7 +6,7 @@ use ra_db::FileId; use crate::{ Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, - DefDatabase, HirFileId, Name, Path, + DefDatabase, HirFileId, Name, Path, SourceItemId, KnownName, nameres::{ Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, @@ -14,7 +14,7 @@ use crate::{ diagnostics::DefDiagnostic, raw, }, - ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId, MacroDefId}, + ids::{AstItemDef, LocationCtx, MacroCallLoc, MacroCallId, MacroDefId}, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index ee0719ee0..f32004601 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -12,7 +12,7 @@ use ra_syntax::{ use crate::{ DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, - ids::{SourceFileItemId, SourceFileItems}, + SourceFileItemId, SourceFileItems, }; /// `RawItems` is a set of top-level items in a file (except for impls). -- cgit v1.2.3 From fb8b354dcc837d5eb9b81fc205e4282a203df177 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Mar 2019 17:25:14 +0300 Subject: add typed ids --- crates/ra_hir/src/nameres/collector.rs | 22 ++++++++++------------ crates/ra_hir/src/nameres/raw.rs | 13 ++++++------- 2 files changed, 16 insertions(+), 19 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 4fb298155..e6fd8632a 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -3,6 +3,7 @@ use rustc_hash::FxHashMap; use relative_path::RelativePathBuf; use test_utils::tested_by; use ra_db::FileId; +use ra_syntax::ast; use crate::{ Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, @@ -15,6 +16,7 @@ use crate::{ raw, }, ids::{AstItemDef, LocationCtx, MacroCallLoc, MacroCallId, MacroDefId}, + AstId, }; pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { @@ -364,12 +366,9 @@ where fn collect_module(&mut self, module: &raw::ModuleData) { match module { // inline module, just recurse - raw::ModuleData::Definition { name, items, source_item_id } => { - let module_id = self.push_child_module( - name.clone(), - source_item_id.with_file_id(self.file_id), - None, - ); + raw::ModuleData::Definition { name, items, ast_id } => { + let module_id = + self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); ModCollector { def_collector: &mut *self.def_collector, module_id, @@ -379,13 +378,12 @@ where .collect(&*items); } // out of line module, resovle, parse and recurse - raw::ModuleData::Declaration { name, source_item_id } => { - let source_item_id = source_item_id.with_file_id(self.file_id); + raw::ModuleData::Declaration { name, ast_id } => { + let ast_id = ast_id.with_file_id(self.file_id); let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { Ok(file_id) => { - let module_id = - self.push_child_module(name.clone(), source_item_id, Some(file_id)); + let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); let raw_items = self.def_collector.db.raw_items(file_id.into()); ModCollector { def_collector: &mut *self.def_collector, @@ -398,7 +396,7 @@ where Err(candidate) => self.def_collector.def_map.diagnostics.push( DefDiagnostic::UnresolvedModule { module: self.module_id, - declaration: source_item_id, + declaration: ast_id, candidate, }, ), @@ -410,7 +408,7 @@ where fn push_child_module( &mut self, name: Name, - declaration: SourceItemId, + declaration: AstId, definition: Option, ) -> CrateModuleId { let modules = &mut self.def_collector.def_map.modules; diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index f32004601..09acd5a98 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -12,7 +12,7 @@ use ra_syntax::{ use crate::{ DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, - SourceFileItemId, SourceFileItems, + SourceFileItemId, SourceFileItems, FileAstId, }; /// `RawItems` is a set of top-level items in a file (except for impls). @@ -115,8 +115,8 @@ impl_arena_id!(Module); #[derive(Debug, PartialEq, Eq)] pub(super) enum ModuleData { - Declaration { name: Name, source_item_id: SourceFileItemId }, - Definition { name: Name, source_item_id: SourceFileItemId, items: Vec }, + Declaration { name: Name, ast_id: FileAstId }, + Definition { name: Name, ast_id: FileAstId, items: Vec }, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -221,10 +221,9 @@ impl RawItemsCollector { Some(it) => it.as_name(), None => return, }; - let source_item_id = self.source_file_items.id_of_unchecked(module.syntax()); + let ast_id = self.source_file_items.ast_id(module); if module.has_semi() { - let item = - self.raw_items.modules.alloc(ModuleData::Declaration { name, source_item_id }); + let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id }); self.push_item(current_module, RawItem::Module(item)); return; } @@ -232,7 +231,7 @@ impl RawItemsCollector { if let Some(item_list) = module.item_list() { let item = self.raw_items.modules.alloc(ModuleData::Definition { name, - source_item_id, + ast_id, items: Vec::new(), }); self.process_module(Some(item), item_list); -- cgit v1.2.3 From 071a19537d4399fd04d1e9594ab7878502a12d21 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Mar 2019 18:03:17 +0300 Subject: strongy-typed ids for macros --- crates/ra_hir/src/nameres/collector.rs | 24 ++++++++---------------- crates/ra_hir/src/nameres/raw.rs | 6 +++--- 2 files changed, 11 insertions(+), 19 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index e6fd8632a..b5f02ab80 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -7,7 +7,7 @@ use ra_syntax::ast; use crate::{ Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, - DefDatabase, HirFileId, Name, Path, SourceItemId, + DefDatabase, HirFileId, Name, Path, KnownName, nameres::{ Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, @@ -53,7 +53,7 @@ struct DefCollector { def_map: CrateDefMap, glob_imports: FxHashMap>, unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, - unexpanded_macros: Vec<(CrateModuleId, SourceItemId, Path)>, + unexpanded_macros: Vec<(CrateModuleId, AstId, Path)>, global_macro_scope: FxHashMap, } @@ -295,7 +295,7 @@ where let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); let mut resolved = Vec::new(); let mut res = ReachedFixedPoint::Yes; - macros.retain(|(module_id, source_item_id, path)| { + macros.retain(|(module_id, ast_id, path)| { if path.segments.len() != 2 { return true; } @@ -311,8 +311,7 @@ where res = ReachedFixedPoint::No; let def_map = self.db.crate_def_map(krate); if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() { - let call_id = - MacroCallLoc { def: macro_id, source_item_id: *source_item_id }.id(self.db); + let call_id = MacroCallLoc { def: macro_id, ast_id: *ast_id }.id(self.db); resolved.push((*module_id, call_id)); } false @@ -456,34 +455,27 @@ where // Case 1: macro rules, define a macro in crate-global mutable scope if is_macro_rules(&mac.path) { if let Some(name) = &mac.name { - let macro_id = MacroDefId::MacroByExample { - source_item_id: mac.source_item_id.with_file_id(self.file_id), - }; + let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id)); self.def_collector.define_macro(name.clone(), macro_id, mac.export) } return; } - let source_item_id = SourceItemId { file_id: self.file_id, item_id: mac.source_item_id }; + let ast_id = mac.ast_id.with_file_id(self.file_id); // Case 2: try to expand macro_rules from this crate, triggering // recursive item collection. if let Some(¯o_id) = mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) { - let macro_call_id = - MacroCallLoc { def: macro_id, source_item_id }.id(self.def_collector.db); + let macro_call_id = MacroCallLoc { def: macro_id, ast_id }.id(self.def_collector.db); self.def_collector.collect_macro_expansion(self.module_id, macro_call_id); return; } // Case 3: path to a macro from another crate, expand during name resolution - self.def_collector.unexpanded_macros.push(( - self.module_id, - source_item_id, - mac.path.clone(), - )) + self.def_collector.unexpanded_macros.push((self.module_id, ast_id, mac.path.clone())) } } diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 09acd5a98..684bd1d50 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -160,7 +160,7 @@ impl_arena_id!(Macro); #[derive(Debug, PartialEq, Eq)] pub(super) struct MacroData { - pub(super) source_item_id: SourceFileItemId, + pub(super) ast_id: FileAstId, pub(super) path: Path, pub(super) name: Option, pub(super) export: bool, @@ -285,9 +285,9 @@ impl RawItemsCollector { }; let name = m.name().map(|it| it.as_name()); - let source_item_id = self.source_file_items.id_of_unchecked(m.syntax()); + let ast_id = self.source_file_items.ast_id(m); let export = m.has_atom_attr("macro_export"); - let m = self.raw_items.macros.alloc(MacroData { source_item_id, path, name, export }); + let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export }); self.push_item(current_module, RawItem::Macro(m)); } -- cgit v1.2.3 From 8f324773127c733b12d1c5ee98a3d9c6a5360db0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Mar 2019 18:27:22 +0300 Subject: more type safety --- crates/ra_hir/src/nameres/collector.rs | 23 ++++++++-------- crates/ra_hir/src/nameres/raw.rs | 48 +++++++++++++++++++++------------- 2 files changed, 42 insertions(+), 29 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index b5f02ab80..39cadc94a 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -429,23 +429,24 @@ where fn define_def(&mut self, def: &raw::DefData) { let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into()); - macro_rules! id { - () => { - AstItemDef::from_source_item_id_unchecked(ctx, def.source_item_id) + + macro_rules! def { + ($kind:ident, $ast_id:ident) => { + $kind { id: AstItemDef::from_ast_id(ctx, $ast_id) }.into() }; } let name = def.name.clone(); let def: PerNs = match def.kind { - raw::DefKind::Function => PerNs::values(Function { id: id!() }.into()), - raw::DefKind::Struct => { - let s = Struct { id: id!() }.into(); + raw::DefKind::Function(ast_id) => PerNs::values(def!(Function, ast_id)), + raw::DefKind::Struct(ast_id) => { + let s = def!(Struct, ast_id); PerNs::both(s, s) } - raw::DefKind::Enum => PerNs::types(Enum { id: id!() }.into()), - raw::DefKind::Const => PerNs::values(Const { id: id!() }.into()), - raw::DefKind::Static => PerNs::values(Static { id: id!() }.into()), - raw::DefKind::Trait => PerNs::types(Trait { id: id!() }.into()), - raw::DefKind::TypeAlias => PerNs::types(TypeAlias { id: id!() }.into()), + raw::DefKind::Enum(ast_id) => PerNs::types(def!(Enum, ast_id)), + raw::DefKind::Const(ast_id) => PerNs::values(def!(Const, ast_id)), + raw::DefKind::Static(ast_id) => PerNs::values(def!(Static, ast_id)), + raw::DefKind::Trait(ast_id) => PerNs::types(def!(Trait, ast_id)), + raw::DefKind::TypeAlias(ast_id) => PerNs::types(def!(TypeAlias, ast_id)), }; let resolution = Resolution { def, import: None }; self.def_collector.update(self.module_id, None, &[(name, resolution)]) diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 684bd1d50..984478adc 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -12,7 +12,7 @@ use ra_syntax::{ use crate::{ DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, - SourceFileItemId, SourceFileItems, FileAstId, + SourceFileItems, FileAstId, }; /// `RawItems` is a set of top-level items in a file (except for impls). @@ -138,20 +138,19 @@ impl_arena_id!(Def); #[derive(Debug, PartialEq, Eq)] pub(super) struct DefData { - pub(super) source_item_id: SourceFileItemId, pub(super) name: Name, pub(super) kind: DefKind, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] pub(super) enum DefKind { - Function, - Struct, - Enum, - Const, - Static, - Trait, - TypeAlias, + Function(FileAstId), + Struct(FileAstId), + Enum(FileAstId), + Const(FileAstId), + Static(FileAstId), + Trait(FileAstId), + TypeAlias(FileAstId), } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -200,18 +199,31 @@ impl RawItemsCollector { // impls don't participate in name resolution return; } - ast::ModuleItemKind::StructDef(it) => (DefKind::Struct, it.name()), - ast::ModuleItemKind::EnumDef(it) => (DefKind::Enum, it.name()), - ast::ModuleItemKind::FnDef(it) => (DefKind::Function, it.name()), - ast::ModuleItemKind::TraitDef(it) => (DefKind::Trait, it.name()), - ast::ModuleItemKind::TypeAliasDef(it) => (DefKind::TypeAlias, it.name()), - ast::ModuleItemKind::ConstDef(it) => (DefKind::Const, it.name()), - ast::ModuleItemKind::StaticDef(it) => (DefKind::Static, it.name()), + ast::ModuleItemKind::StructDef(it) => { + (DefKind::Struct(self.source_file_items.ast_id(it)), it.name()) + } + ast::ModuleItemKind::EnumDef(it) => { + (DefKind::Enum(self.source_file_items.ast_id(it)), it.name()) + } + ast::ModuleItemKind::FnDef(it) => { + (DefKind::Function(self.source_file_items.ast_id(it)), it.name()) + } + ast::ModuleItemKind::TraitDef(it) => { + (DefKind::Trait(self.source_file_items.ast_id(it)), it.name()) + } + ast::ModuleItemKind::TypeAliasDef(it) => { + (DefKind::TypeAlias(self.source_file_items.ast_id(it)), it.name()) + } + ast::ModuleItemKind::ConstDef(it) => { + (DefKind::Const(self.source_file_items.ast_id(it)), it.name()) + } + ast::ModuleItemKind::StaticDef(it) => { + (DefKind::Static(self.source_file_items.ast_id(it)), it.name()) + } }; if let Some(name) = name { let name = name.as_name(); - let source_item_id = self.source_file_items.id_of_unchecked(item.syntax()); - let def = self.raw_items.defs.alloc(DefData { name, kind, source_item_id }); + let def = self.raw_items.defs.alloc(DefData { name, kind }); self.push_item(current_module, RawItem::Def(def)) } } -- cgit v1.2.3 From e28db444dfdc797002bd3561940cde2659b831de Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Mar 2019 19:00:11 +0300 Subject: rename --- crates/ra_hir/src/nameres/raw.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 984478adc..0936229ac 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs @@ -12,7 +12,7 @@ use ra_syntax::{ use crate::{ DefDatabase, Name, AsName, Path, HirFileId, ModuleSource, - SourceFileItems, FileAstId, + AstIdMap, FileAstId, }; /// `RawItems` is a set of top-level items in a file (except for impls). @@ -60,7 +60,7 @@ impl RawItems { ) -> (Arc, Arc) { let mut collector = RawItemsCollector { raw_items: RawItems::default(), - source_file_items: db.file_items(file_id.into()), + source_ast_id_map: db.ast_id_map(file_id.into()), source_map: ImportSourceMap::default(), }; let source_file = db.hir_parse(file_id); @@ -167,7 +167,7 @@ pub(super) struct MacroData { struct RawItemsCollector { raw_items: RawItems, - source_file_items: Arc, + source_ast_id_map: Arc, source_map: ImportSourceMap, } @@ -200,25 +200,25 @@ impl RawItemsCollector { return; } ast::ModuleItemKind::StructDef(it) => { - (DefKind::Struct(self.source_file_items.ast_id(it)), it.name()) + (DefKind::Struct(self.source_ast_id_map.ast_id(it)), it.name()) } ast::ModuleItemKind::EnumDef(it) => { - (DefKind::Enum(self.source_file_items.ast_id(it)), it.name()) + (DefKind::Enum(self.source_ast_id_map.ast_id(it)), it.name()) } ast::ModuleItemKind::FnDef(it) => { - (DefKind::Function(self.source_file_items.ast_id(it)), it.name()) + (DefKind::Function(self.source_ast_id_map.ast_id(it)), it.name()) } ast::ModuleItemKind::TraitDef(it) => { - (DefKind::Trait(self.source_file_items.ast_id(it)), it.name()) + (DefKind::Trait(self.source_ast_id_map.ast_id(it)), it.name()) } ast::ModuleItemKind::TypeAliasDef(it) => { - (DefKind::TypeAlias(self.source_file_items.ast_id(it)), it.name()) + (DefKind::TypeAlias(self.source_ast_id_map.ast_id(it)), it.name()) } ast::ModuleItemKind::ConstDef(it) => { - (DefKind::Const(self.source_file_items.ast_id(it)), it.name()) + (DefKind::Const(self.source_ast_id_map.ast_id(it)), it.name()) } ast::ModuleItemKind::StaticDef(it) => { - (DefKind::Static(self.source_file_items.ast_id(it)), it.name()) + (DefKind::Static(self.source_ast_id_map.ast_id(it)), it.name()) } }; if let Some(name) = name { @@ -233,7 +233,7 @@ impl RawItemsCollector { Some(it) => it.as_name(), None => return, }; - let ast_id = self.source_file_items.ast_id(module); + let ast_id = self.source_ast_id_map.ast_id(module); if module.has_semi() { let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id }); self.push_item(current_module, RawItem::Module(item)); @@ -297,7 +297,7 @@ impl RawItemsCollector { }; let name = m.name().map(|it| it.as_name()); - let ast_id = self.source_file_items.ast_id(m); + let ast_id = self.source_ast_id_map.ast_id(m); let export = m.has_atom_attr("macro_export"); let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export }); self.push_item(current_module, RawItem::Macro(m)); -- cgit v1.2.3 From a3fee2bda04be27a63d9298f6e97555c904df4da Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 26 Mar 2019 19:54:52 +0300 Subject: more realistic test for incrementality --- crates/ra_hir/src/nameres/tests/incremental.rs | 27 +++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/tests/incremental.rs b/crates/ra_hir/src/nameres/tests/incremental.rs index a059634e2..001f76ac3 100644 --- a/crates/ra_hir/src/nameres/tests/incremental.rs +++ b/crates/ra_hir/src/nameres/tests/incremental.rs @@ -92,12 +92,14 @@ fn adding_inner_items_should_not_invalidate_def_map() { #[test] fn typing_inside_a_macro_should_not_invalidate_def_map() { - check_def_map_is_not_recomputed( + let (mut db, pos) = MockDatabase::with_position( " //- /lib.rs macro_rules! m { ($ident:ident) => { - struct Foo; + fn f() { + $ident + $ident; + }; } } mod foo; @@ -109,8 +111,23 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() { <|> m!(X); ", - " - m!(Y); - ", ); + { + let events = db.log_executed(|| { + let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap(); + let decls = module.declarations(&db); + assert_eq!(decls.len(), 1); + }); + assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) + } + db.set_file_text(pos.file_id, Arc::new("m!(Y);".to_string())); + + { + let events = db.log_executed(|| { + let module = crate::source_binder::module_from_file_id(&db, pos.file_id).unwrap(); + let decls = module.declarations(&db); + assert_eq!(decls.len(), 1); + }); + assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events) + } } -- cgit v1.2.3