From 8e084132f8008ef2b1fba13ae0d6b402d140d225 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Tue, 21 Dec 2021 13:38:58 +0100 Subject: [PATCH] internal: Do less work in `hir::Semantics` --- crates/hir/src/semantics.rs | 78 ++++++++++++----------- crates/hir/src/semantics/source_to_def.rs | 25 +++----- crates/hir_expand/src/lib.rs | 10 ++- 3 files changed, 54 insertions(+), 59 deletions(-) diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index a299aa44988..02cfeb361cf 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -210,7 +210,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { } pub fn hir_file_for(&self, syntax_node: &SyntaxNode) -> HirFileId { - self.imp.find_file(syntax_node.clone()).file_id + self.imp.find_file(syntax_node).file_id } pub fn original_range(&self, node: &SyntaxNode) -> FileRange { @@ -362,7 +362,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { } pub fn to_def(&self, src: &T) -> Option { - let src = self.imp.find_file(src.syntax().clone()).with_value(src).cloned(); + let src = self.imp.find_file(src.syntax()).with_value(src).cloned(); T::to_def(&self.imp, src) } @@ -427,7 +427,7 @@ impl<'db> SemanticsImpl<'db> { } fn expand(&self, macro_call: &ast::MacroCall) -> Option { - let sa = self.analyze(macro_call.syntax()); + let sa = self.analyze_no_infer(macro_call.syntax()); let file_id = sa.expand(self.db, InFile::new(sa.file_id, macro_call))?; let node = self.db.parse_or_expand(file_id)?; self.cache(node.clone(), file_id); @@ -435,8 +435,7 @@ impl<'db> SemanticsImpl<'db> { } fn expand_attr_macro(&self, item: &ast::Item) -> Option { - let sa = self.analyze(item.syntax()); - let src = InFile::new(sa.file_id, item.clone()); + let src = self.find_file(item.syntax()).with_value(item.clone()); let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(src))?; let file_id = macro_call_id.as_file(); let node = self.db.parse_or_expand(file_id)?; @@ -446,9 +445,9 @@ impl<'db> SemanticsImpl<'db> { fn expand_derive_macro(&self, attr: &ast::Attr) -> Option> { let item = attr.syntax().parent().and_then(ast::Item::cast)?; - let sa = self.analyze(item.syntax()); - let item = InFile::new(sa.file_id, &item); - let src = InFile::new(sa.file_id, attr.clone()); + let file_id = self.find_file(item.syntax()).file_id; + let item = InFile::new(file_id, &item); + let src = InFile::new(file_id, attr.clone()); self.with_ctx(|ctx| { let macro_call_ids = ctx.attr_to_derive_macro_call(item, src)?; @@ -470,8 +469,8 @@ impl<'db> SemanticsImpl<'db> { } fn is_attr_macro_call(&self, item: &ast::Item) -> bool { - let sa = self.analyze(item.syntax()); - let src = InFile::new(sa.file_id, item.clone()); + let file_id = self.find_file(item.syntax()).file_id; + let src = InFile::new(file_id, item.clone()); self.with_ctx(|ctx| ctx.item_to_macro_call(src).is_some()) } @@ -481,11 +480,12 @@ impl<'db> SemanticsImpl<'db> { speculative_args: &ast::TokenTree, token_to_map: SyntaxToken, ) -> Option<(SyntaxNode, SyntaxToken)> { - let sa = self.analyze(actual_macro_call.syntax()); - let macro_call = InFile::new(sa.file_id, actual_macro_call); - let krate = sa.resolver.krate()?; + let SourceAnalyzer { file_id, resolver, .. } = + self.analyze_no_infer(actual_macro_call.syntax()); + let macro_call = InFile::new(file_id, actual_macro_call); + let krate = resolver.krate()?; let macro_call_id = macro_call.as_call_id(self.db.upcast(), krate, |path| { - sa.resolver.resolve_path_as_macro(self.db.upcast(), &path) + resolver.resolve_path_as_macro(self.db.upcast(), &path) })?; hir_expand::db::expand_speculative( self.db.upcast(), @@ -501,8 +501,8 @@ impl<'db> SemanticsImpl<'db> { speculative_args: &ast::Item, token_to_map: SyntaxToken, ) -> Option<(SyntaxNode, SyntaxToken)> { - let sa = self.analyze(actual_macro_call.syntax()); - let macro_call = InFile::new(sa.file_id, actual_macro_call.clone()); + let file_id = self.find_file(actual_macro_call.syntax()).file_id; + let macro_call = InFile::new(file_id, actual_macro_call.clone()); let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(macro_call))?; hir_expand::db::expand_speculative( self.db.upcast(), @@ -712,18 +712,18 @@ impl<'db> SemanticsImpl<'db> { } fn original_range(&self, node: &SyntaxNode) -> FileRange { - let node = self.find_file(node.clone()); - node.as_ref().original_file_range(self.db.upcast()) + let node = self.find_file(node); + node.original_file_range(self.db.upcast()) } fn original_range_opt(&self, node: &SyntaxNode) -> Option { - let node = self.find_file(node.clone()); - node.as_ref().original_file_range_opt(self.db.upcast()) + let node = self.find_file(node); + node.original_file_range_opt(self.db.upcast()) } fn original_ast_node(&self, node: N) -> Option { - let file = self.find_file(node.syntax().clone()); - file.with_value(node).original_ast_node(self.db.upcast()).map(|it| it.value) + let InFile { file_id, .. } = self.find_file(node.syntax()); + InFile::new(file_id, node).original_ast_node(self.db.upcast()).map(|it| it.value) } fn diagnostics_display_range(&self, src: InFile) -> FileRange { @@ -744,7 +744,7 @@ impl<'db> SemanticsImpl<'db> { &self, node: SyntaxNode, ) -> impl Iterator + Clone + '_ { - let node = self.find_file(node); + let node = self.find_file(&node); node.ancestors_with_macros(self.db.upcast()).map(|it| it.value) } @@ -765,7 +765,8 @@ impl<'db> SemanticsImpl<'db> { gpl.lifetime_params() .find(|tp| tp.lifetime().as_ref().map(|lt| lt.text()).as_ref() == Some(&text)) })?; - let src = self.find_file(lifetime_param.syntax().clone()).with_value(lifetime_param); + let file_id = self.find_file(lifetime_param.syntax()).file_id; + let src = InFile::new(file_id, lifetime_param); ToDef::to_def(self, src) } @@ -787,7 +788,8 @@ impl<'db> SemanticsImpl<'db> { .map_or(false, |lt| lt.text() == text) }) })?; - let src = self.find_file(label.syntax().clone()).with_value(label); + let file_id = self.find_file(label.syntax()).file_id; + let src = InFile::new(file_id, label); ToDef::to_def(self, src) } @@ -846,12 +848,12 @@ impl<'db> SemanticsImpl<'db> { fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option { let sa = self.analyze(macro_call.syntax()); - let macro_call = self.find_file(macro_call.syntax().clone()).with_value(macro_call); + let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call); sa.resolve_macro_call(self.db, macro_call) } fn resolve_attr_macro_call(&self, item: &ast::Item) -> Option { - let item_in_file = self.find_file(item.syntax().clone()).with_value(item.clone()); + let item_in_file = self.find_file(item.syntax()).with_value(item.clone()); let macro_call_id = self.with_ctx(|ctx| ctx.item_to_macro_call(item_in_file))?; Some(MacroDef { id: self.db.lookup_intern_macro_call(macro_call_id).def }) } @@ -902,12 +904,13 @@ impl<'db> SemanticsImpl<'db> { } fn scope(&self, node: &SyntaxNode) -> SemanticsScope<'db> { - let SourceAnalyzer { file_id, resolver, .. } = self.analyze(node); + let SourceAnalyzer { file_id, resolver, .. } = self.analyze_no_infer(node); SemanticsScope { db: self.db, file_id, resolver } } fn scope_at_offset(&self, node: &SyntaxNode, offset: TextSize) -> SemanticsScope<'db> { - let SourceAnalyzer { file_id, resolver, .. } = self.analyze_with_offset(node, offset); + let SourceAnalyzer { file_id, resolver, .. } = + self.analyze_with_offset_no_infer(node, offset); SemanticsScope { db: self.db, file_id, resolver } } @@ -930,14 +933,14 @@ impl<'db> SemanticsImpl<'db> { self.analyze_impl(node, None, true) } - fn analyze_with_offset(&self, node: &SyntaxNode, offset: TextSize) -> SourceAnalyzer { - self.analyze_impl(node, Some(offset), true) - } - fn analyze_no_infer(&self, node: &SyntaxNode) -> SourceAnalyzer { self.analyze_impl(node, None, false) } + fn analyze_with_offset_no_infer(&self, node: &SyntaxNode, offset: TextSize) -> SourceAnalyzer { + self.analyze_impl(node, Some(offset), false) + } + fn analyze_impl( &self, node: &SyntaxNode, @@ -945,8 +948,7 @@ impl<'db> SemanticsImpl<'db> { infer_body: bool, ) -> SourceAnalyzer { let _p = profile::span("Semantics::analyze_impl"); - let node = self.find_file(node.clone()); - let node = node.as_ref(); + let node = self.find_file(node); let container = match self.with_ctx(|ctx| ctx.find_container(node)) { Some(it) => it, @@ -980,7 +982,7 @@ impl<'db> SemanticsImpl<'db> { } fn assert_contains_node(&self, node: &SyntaxNode) { - self.find_file(node.clone()); + self.find_file(node); } fn lookup(&self, root_node: &SyntaxNode) -> Option { @@ -988,8 +990,8 @@ impl<'db> SemanticsImpl<'db> { cache.get(root_node).copied() } - fn find_file(&self, node: SyntaxNode) -> InFile { - let root_node = find_root(&node); + fn find_file<'node>(&self, node: &'node SyntaxNode) -> InFile<&'node SyntaxNode> { + let root_node = find_root(node); let file_id = self.lookup(&root_node).unwrap_or_else(|| { panic!( "\n\nFailed to lookup {:?} in this Semantics.\n\ diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 9b8e5635923..dd83f1c86e0 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -131,15 +131,13 @@ impl SourceToDefCtx<'_, '_> { pub(super) fn module_to_def(&mut self, src: InFile) -> Option { let _p = profile::span("module_to_def"); - let parent_declaration = src - .syntax() - .cloned() - .ancestors_with_macros_skip_attr_item(self.db.upcast()) - .skip(1) - .find_map(|it| { - let m = ast::Module::cast(it.value.clone())?; - Some(it.with_value(m)) - }); + let parent_declaration = + src.syntax().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1).find_map( + |it| { + let m = ast::Module::cast(it.value.clone())?; + Some(it.with_value(m)) + }, + ); let parent_module = match parent_declaration { Some(parent_declaration) => self.module_to_def(parent_declaration), @@ -333,8 +331,7 @@ impl SourceToDefCtx<'_, '_> { } pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option { - for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) - { + for container in src.ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) { if let Some(res) = self.container_to_def(container) { return Some(res); } @@ -398,8 +395,7 @@ impl SourceToDefCtx<'_, '_> { } fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option { - for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) - { + for container in src.ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) { let res: GenericDefId = match_ast! { match (container.value) { ast::Fn(it) => self.fn_to_def(container.with_value(it))?.into(), @@ -417,8 +413,7 @@ impl SourceToDefCtx<'_, '_> { } fn find_pat_or_label_container(&mut self, src: InFile<&SyntaxNode>) -> Option { - for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) - { + for container in src.ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) { let res: DefWithBodyId = match_ast! { match (container.value) { ast::Const(it) => self.const_to_def(container.with_value(it))?.into(), diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index bca380a4d6f..fe9f7ef2749 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs @@ -578,12 +578,12 @@ impl InFile> { } } -impl InFile { +impl<'a> InFile<&'a SyntaxNode> { pub fn ancestors_with_macros( self, db: &dyn db::AstDatabase, ) -> impl Iterator> + Clone + '_ { - iter::successors(Some(self), move |node| match node.value.parent() { + iter::successors(Some(self.cloned()), move |node| match node.value.parent() { Some(parent) => Some(node.with_value(parent)), None => { let parent_node = node.file_id.call_node(db)?; @@ -597,7 +597,7 @@ impl InFile { self, db: &dyn db::AstDatabase, ) -> impl Iterator> + '_ { - iter::successors(Some(self), move |node| match node.value.parent() { + iter::successors(Some(self.cloned()), move |node| match node.value.parent() { Some(parent) => Some(node.with_value(parent)), None => { let parent_node = node.file_id.call_node(db)?; @@ -611,9 +611,7 @@ impl InFile { } }) } -} -impl<'a> InFile<&'a SyntaxNode> { /// Falls back to the macro call range if the node cannot be mapped up fully. pub fn original_file_range(self, db: &dyn db::AstDatabase) -> FileRange { if let Some(res) = self.original_file_range_opt(db) { @@ -701,7 +699,7 @@ impl InFile { ) -> impl Iterator> + '_ { self.value.parent().into_iter().flat_map({ let file_id = self.file_id; - move |parent| InFile::new(file_id, parent).ancestors_with_macros(db) + move |parent| InFile::new(file_id, &parent).ancestors_with_macros(db) }) } }