]> git.lizzy.rs Git - rust.git/commitdiff
Intern Attr, MacroCall and Path components
authorJonas Schievink <jonasschievink@gmail.com>
Thu, 1 Apr 2021 18:35:21 +0000 (20:35 +0200)
committerJonas Schievink <jonasschievink@gmail.com>
Thu, 1 Apr 2021 18:35:21 +0000 (20:35 +0200)
crates/hir_def/src/attr.rs
crates/hir_def/src/intern.rs
crates/hir_def/src/item_tree.rs
crates/hir_def/src/item_tree/lower.rs
crates/hir_def/src/nameres/collector.rs
crates/hir_def/src/path.rs
crates/hir_def/src/path/lower.rs

index 52a2bce9b10aad3a18892e1863cbe4b20e9af1ed..2bab121d993032fb06f3e071b6315adabfdaa65c 100644 (file)
@@ -18,6 +18,7 @@
 
 use crate::{
     db::DefDatabase,
+    intern::Interned,
     item_tree::{ItemTreeId, ItemTreeNode},
     nameres::ModuleSource,
     path::{ModPath, PathKind},
@@ -98,7 +99,7 @@ pub(crate) fn new(owner: &dyn ast::AttrsOwner, hygiene: &Hygiene) -> Self {
                 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::<Arc<_>>();
@@ -510,7 +511,7 @@ pub fn source_of(&self, attr: &Attr) -> InFile<&Either<ast::Attr, ast::Comment>>
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct Attr {
     index: u32,
-    pub(crate) path: ModPath,
+    pub(crate) path: Interned<ModPath>,
     pub(crate) input: Option<AttrInput>,
 }
 
@@ -524,7 +525,7 @@ pub enum AttrInput {
 
 impl Attr {
     fn from_src(ast: ast::Attr, hygiene: &Hygiene, index: u32) -> Option<Attr> {
-        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(),
index 28ec72cffc08309513feeda1e67396cf01dc12b3..4d8fbd32494319ad21f8f80ef8c236bf698c9289 100644 (file)
@@ -15,6 +15,7 @@
 
 type InternMap<T> = DashMap<Arc<T>, (), BuildHasherDefault<FxHasher>>;
 
+#[derive(Hash)]
 pub struct Interned<T: Internable> {
     arc: Arc<T>,
 }
@@ -152,6 +153,6 @@ fn storage() -> &'static InternStorage<Self> {
     )+ };
 }
 
-impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef);
+impl_internable!(crate::type_ref::TypeRef, crate::type_ref::TraitRef, crate::path::ModPath);
 
 // endregion
index 9f6bb3a7cf8156e7d0859f839fcc9e218550582b..69a313c7e2d44cb8146aacb70959e13800857a55 100644 (file)
@@ -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<ModPath>,
     pub ast_id: FileAstId<ast::MacroCall>,
 }
 
index 23d3dea7b68e4fa20c0abd8d88db5dbab293dece..5247379c58c4a66be55a28ca2b03c65a6888f2c4 100644 (file)
@@ -606,7 +606,7 @@ fn lower_extern_crate(
     }
 
     fn lower_macro_call(&mut self, m: &ast::MacroCall) -> Option<FileItemTreeId<MacroCall>> {
-        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)))
index d58135ec98ced336c294c660776506f38d721946..5badefabf5786bbfc492096bdff9365ef5df783e 100644 (file)
@@ -1464,7 +1464,7 @@ fn collect_macro_def(&mut self, id: FileItemTreeId<MacroDef>) {
     }
 
     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;
index 8c923bb7b28d651d0349532e577902155a0188b5..a3e83e2cf1e8953231a0b8829e1ca163b236890a 100644 (file)
@@ -7,7 +7,7 @@
     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<ModPath> {
-        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<Item = Name>) -> ModPath {
@@ -123,7 +123,7 @@ pub struct Path {
     /// Type based path like `<T>::foo`.
     /// Note that paths like `<Type as Trait>::foo` are desugard to `Trait::<Self=Type>::foo`.
     type_anchor: Option<Box<TypeRef>>,
-    mod_path: ModPath,
+    mod_path: Interned<ModPath>,
     /// Invariant: the same len as `self.mod_path.segments`
     generic_args: Vec<Option<Arc<GenericArgs>>>,
 }
@@ -176,7 +176,7 @@ pub(crate) fn from_known_path(
         path: ModPath,
         generic_args: Vec<Option<Arc<GenericArgs>>>,
     ) -> 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 @@ pub fn qualifier(&self) -> Option<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<Name> 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],
         }
     }
index 4de951fd3e85fcf1442e27239ef532f11de2cf14..28f6244da199634dcfc60ccf01cc6649c9bfe260 100644 (file)
@@ -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<Path>
                     // <T as Trait<A>>::Foo desugars to Trait<Self=T, A>::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<Path>
         }
     }
 
-    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<ast::Path> {