From 39d992ef559c9cd67551819a9d63ef52ef7b725f Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 1 Apr 2021 20:35:21 +0200 Subject: Intern Attr, MacroCall and Path components --- crates/hir_def/src/attr.rs | 7 ++++--- crates/hir_def/src/intern.rs | 3 ++- crates/hir_def/src/item_tree.rs | 2 +- crates/hir_def/src/item_tree/lower.rs | 2 +- crates/hir_def/src/nameres/collector.rs | 2 +- crates/hir_def/src/path.rs | 14 +++++++------- crates/hir_def/src/path/lower.rs | 8 +++++--- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 52a2bce9b..2bab121d9 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs @@ -18,6 +18,7 @@ use tt::Subtree; use crate::{ db::DefDatabase, + intern::Interned, item_tree::{ItemTreeId, ItemTreeNode}, nameres::ModuleSource, path::{ModPath, PathKind}, @@ -98,7 +99,7 @@ impl RawAttrs { Either::Right(comment) => comment.doc_comment().map(|doc| Attr { index: i as u32, input: Some(AttrInput::Literal(SmolStr::new(doc))), - path: ModPath::from(hir_expand::name!(doc)), + path: Interned::new(ModPath::from(hir_expand::name!(doc))), }), }) .collect::>(); @@ -510,7 +511,7 @@ impl AttrSourceMap { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Attr { index: u32, - pub(crate) path: ModPath, + pub(crate) path: Interned, pub(crate) input: Option, } @@ -524,7 +525,7 @@ pub enum AttrInput { impl Attr { fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option { - let path = ModPath::from_src(ast.path()?, hygiene)?; + let path = Interned::new(ModPath::from_src(ast.path()?, hygiene)?); let input = if let Some(ast::Expr::Literal(lit)) = ast.expr() { let value = match lit.kind() { ast::LiteralKind::String(string) => string.value()?.into(), diff --git a/crates/hir_def/src/intern.rs b/crates/hir_def/src/intern.rs index 28ec72cff..4d8fbd324 100644 --- a/crates/hir_def/src/intern.rs +++ b/crates/hir_def/src/intern.rs @@ -15,6 +15,7 @@ use rustc_hash::FxHasher; type InternMap = DashMap, (), BuildHasherDefault>; +#[derive(Hash)] pub struct Interned { arc: Arc, } @@ -152,6 +153,6 @@ macro_rules! impl_internable { )+ }; } -impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef); +impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef, crate::path::ModPath); // endregion diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 9f6bb3a7c..69a313c7e 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -694,7 +694,7 @@ pub enum ModKind { #[derive(Debug, Clone, Eq, PartialEq)] pub struct MacroCall { /// Path to the called macro. - pub path: ModPath, + pub path: Interned, pub ast_id: FileAstId, } diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 23d3dea7b..5247379c5 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs @@ -606,7 +606,7 @@ impl Ctx { } fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option> { - let path = ModPath::from_src(m.path()?, &self.hygiene)?; + let path = Interned::new(ModPath::from_src(m.path()?, &self.hygiene)?); let ast_id = self.source_ast_id_map.ast_id(m); let res = MacroCall { path, ast_id }; Some(id(self.data().macro_calls.alloc(res))) diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index d58135ec9..5badefabf 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -1464,7 +1464,7 @@ impl ModCollector<'_, '_> { } fn collect_macro_call(&mut self, mac: &MacroCall) { - let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); + let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, (*mac.path).clone()); // Case 1: try to resolve in legacy scope and expand macro_rules let mut error = None; diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 8c923bb7b..a3e83e2cf 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs @@ -7,7 +7,7 @@ use std::{ sync::Arc, }; -use crate::{body::LowerCtx, type_ref::LifetimeRef}; +use crate::{body::LowerCtx, intern::Interned, type_ref::LifetimeRef}; use base_db::CrateId; use hir_expand::{ hygiene::Hygiene, @@ -48,7 +48,7 @@ pub enum ImportAlias { impl ModPath { pub fn from_src(path: ast::Path, hygiene: &Hygiene) -> Option { - lower::lower_path(path, hygiene).map(|it| it.mod_path) + lower::lower_path(path, hygiene).map(|it| (*it.mod_path).clone()) } pub fn from_segments(kind: PathKind, segments: impl IntoIterator) -> ModPath { @@ -123,7 +123,7 @@ pub struct Path { /// Type based path like `::foo`. /// Note that paths like `::foo` are desugard to `Trait::::foo`. type_anchor: Option>, - mod_path: ModPath, + mod_path: Interned, /// Invariant: the same len as `self.mod_path.segments` generic_args: Vec>>, } @@ -176,7 +176,7 @@ impl Path { path: ModPath, generic_args: Vec>>, ) -> Path { - Path { type_anchor: None, mod_path: path, generic_args } + Path { type_anchor: None, mod_path: Interned::new(path), generic_args } } pub fn kind(&self) -> &PathKind { @@ -204,10 +204,10 @@ impl Path { } let res = Path { type_anchor: self.type_anchor.clone(), - mod_path: ModPath::from_segments( + mod_path: Interned::new(ModPath::from_segments( self.mod_path.kind.clone(), self.mod_path.segments[..self.mod_path.segments.len() - 1].iter().cloned(), - ), + )), generic_args: self.generic_args[..self.generic_args.len() - 1].to_vec(), }; Some(res) @@ -283,7 +283,7 @@ impl From for Path { fn from(name: Name) -> Path { Path { type_anchor: None, - mod_path: ModPath::from_segments(PathKind::Plain, iter::once(name)), + mod_path: Interned::new(ModPath::from_segments(PathKind::Plain, iter::once(name))), generic_args: vec![None], } } diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 4de951fd3..28f6244da 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs @@ -2,6 +2,7 @@ mod lower_use; +use crate::intern::Interned; use std::sync::Arc; use either::Either; @@ -74,10 +75,11 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option // >::Foo desugars to Trait::Foo Some(trait_ref) => { let path = Path::from_src(trait_ref.path()?, hygiene)?; + let mod_path = (*path.mod_path).clone(); let num_segments = path.mod_path.segments.len(); - kind = path.mod_path.kind; + kind = mod_path.kind; - let mut prefix_segments = path.mod_path.segments; + let mut prefix_segments = mod_path.segments; prefix_segments.reverse(); segments.extend(prefix_segments); @@ -140,7 +142,7 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option } } - let mod_path = ModPath::from_segments(kind, segments); + let mod_path = Interned::new(ModPath::from_segments(kind, segments)); return Some(Path { type_anchor, mod_path, generic_args }); fn qualifier(path: &ast::Path) -> Option { -- cgit v1.2.3