about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-03-21 11:49:09 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-03-21 11:49:09 +0100
commit0036762b9d3823dacd3181fa03780b5ae9166613 (patch)
tree986e68d20b3b813900eb30ec6472edad353cb61c
parent928d847cc2c19bf5157293baa1327593ab5034b6 (diff)
downloadrust-0036762b9d3823dacd3181fa03780b5ae9166613.tar.gz
rust-0036762b9d3823dacd3181fa03780b5ae9166613.zip
Make use of `ThinArc` in `RawAttrs`
-rw-r--r--crates/hir-expand/src/attrs.rs140
-rw-r--r--crates/ide-diagnostics/src/tests.rs4
2 files changed, 82 insertions, 62 deletions
diff --git a/crates/hir-expand/src/attrs.rs b/crates/hir-expand/src/attrs.rs
index f7987988194..f1540498f26 100644
--- a/crates/hir-expand/src/attrs.rs
+++ b/crates/hir-expand/src/attrs.rs
@@ -9,7 +9,7 @@ use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
 use smallvec::{smallvec, SmallVec};
 use span::{Span, SyntaxContextId};
 use syntax::{ast, format_smolstr, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
-use triomphe::Arc;
+use triomphe::ThinArc;
 
 use crate::{
     db::ExpandDatabase,
@@ -22,8 +22,7 @@ use crate::{
 /// Syntactical attributes, without filtering of `cfg_attr`s.
 #[derive(Default, Debug, Clone, PartialEq, Eq)]
 pub struct RawAttrs {
-    // FIXME: Make this a ThinArc
-    entries: Option<Arc<[Attr]>>,
+    entries: Option<ThinArc<(), Attr>>,
 }
 
 impl ops::Deref for RawAttrs {
@@ -31,7 +30,7 @@ impl ops::Deref for RawAttrs {
 
     fn deref(&self) -> &[Attr] {
         match &self.entries {
-            Some(it) => it,
+            Some(it) => &it.slice,
             None => &[],
         }
     }
@@ -45,27 +44,34 @@ impl RawAttrs {
         owner: &dyn ast::HasAttrs,
         span_map: SpanMapRef<'_>,
     ) -> Self {
-        let entries = collect_attrs(owner).filter_map(|(id, attr)| match attr {
-            Either::Left(attr) => {
-                attr.meta().and_then(|meta| Attr::from_src(db, meta, span_map, id))
-            }
-            Either::Right(comment) => comment.doc_comment().map(|doc| {
-                let span = span_map.span_for_range(comment.syntax().text_range());
-                Attr {
-                    id,
-                    input: Some(Interned::new(AttrInput::Literal(tt::Literal {
-                        // FIXME: Escape quotes from comment content
-                        text: SmolStr::new(format_smolstr!("\"{doc}\"",)),
-                        span,
-                    }))),
-                    path: Interned::new(ModPath::from(crate::name!(doc))),
-                    ctxt: span.ctx,
+        let entries: Vec<_> = collect_attrs(owner)
+            .filter_map(|(id, attr)| match attr {
+                Either::Left(attr) => {
+                    attr.meta().and_then(|meta| Attr::from_src(db, meta, span_map, id))
                 }
-            }),
-        });
-        let entries: Arc<[Attr]> = Arc::from_iter(entries);
+                Either::Right(comment) => comment.doc_comment().map(|doc| {
+                    let span = span_map.span_for_range(comment.syntax().text_range());
+                    Attr {
+                        id,
+                        input: Some(Interned::new(AttrInput::Literal(tt::Literal {
+                            // FIXME: Escape quotes from comment content
+                            text: SmolStr::new(format_smolstr!("\"{doc}\"",)),
+                            span,
+                        }))),
+                        path: Interned::new(ModPath::from(crate::name!(doc))),
+                        ctxt: span.ctx,
+                    }
+                }),
+            })
+            .collect();
 
-        Self { entries: if entries.is_empty() { None } else { Some(entries) } }
+        let entries = if entries.is_empty() {
+            None
+        } else {
+            Some(ThinArc::from_header_and_iter((), entries.into_iter()))
+        };
+
+        RawAttrs { entries }
     }
 
     pub fn from_attrs_owner(
@@ -82,16 +88,20 @@ impl RawAttrs {
             (None, entries @ Some(_)) => Self { entries },
             (Some(entries), None) => Self { entries: Some(entries.clone()) },
             (Some(a), Some(b)) => {
-                let last_ast_index = a.last().map_or(0, |it| it.id.ast_index() + 1) as u32;
-                Self {
-                    entries: Some(Arc::from_iter(a.iter().cloned().chain(b.iter().map(|it| {
+                let last_ast_index = a.slice.last().map_or(0, |it| it.id.ast_index() + 1) as u32;
+                let items = a
+                    .slice
+                    .iter()
+                    .cloned()
+                    .chain(b.slice.iter().map(|it| {
                         let mut it = it.clone();
                         it.id.id = (it.id.ast_index() as u32 + last_ast_index)
                             | (it.id.cfg_attr_index().unwrap_or(0) as u32)
                                 << AttrId::AST_INDEX_BITS;
                         it
-                    })))),
-                }
+                    }))
+                    .collect::<Vec<_>>();
+                Self { entries: Some(ThinArc::from_header_and_iter((), items.into_iter())) }
             }
         }
     }
@@ -107,41 +117,47 @@ impl RawAttrs {
         }
 
         let crate_graph = db.crate_graph();
-        let new_attrs = Arc::from_iter(self.iter().flat_map(|attr| -> SmallVec<[_; 1]> {
-            let is_cfg_attr =
-                attr.path.as_ident().map_or(false, |name| *name == crate::name![cfg_attr]);
-            if !is_cfg_attr {
-                return smallvec![attr.clone()];
-            }
-
-            let subtree = match attr.token_tree_value() {
-                Some(it) => it,
-                _ => return smallvec![attr.clone()],
-            };
-
-            let (cfg, parts) = match parse_cfg_attr_input(subtree) {
-                Some(it) => it,
-                None => return smallvec![attr.clone()],
-            };
-            let index = attr.id;
-            let attrs = parts
-                .enumerate()
-                .take(1 << AttrId::CFG_ATTR_BITS)
-                .filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)));
-
-            let cfg_options = &crate_graph[krate].cfg_options;
-            let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) };
-            let cfg = CfgExpr::parse(&cfg);
-            if cfg_options.check(&cfg) == Some(false) {
-                smallvec![]
-            } else {
-                cov_mark::hit!(cfg_attr_active);
-
-                attrs.collect()
-            }
-        }));
+        let new_attrs =
+            self.iter()
+                .flat_map(|attr| -> SmallVec<[_; 1]> {
+                    let is_cfg_attr =
+                        attr.path.as_ident().map_or(false, |name| *name == crate::name![cfg_attr]);
+                    if !is_cfg_attr {
+                        return smallvec![attr.clone()];
+                    }
 
-        RawAttrs { entries: Some(new_attrs) }
+                    let subtree = match attr.token_tree_value() {
+                        Some(it) => it,
+                        _ => return smallvec![attr.clone()],
+                    };
+
+                    let (cfg, parts) = match parse_cfg_attr_input(subtree) {
+                        Some(it) => it,
+                        None => return smallvec![attr.clone()],
+                    };
+                    let index = attr.id;
+                    let attrs = parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map(
+                        |(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)),
+                    );
+
+                    let cfg_options = &crate_graph[krate].cfg_options;
+                    let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) };
+                    let cfg = CfgExpr::parse(&cfg);
+                    if cfg_options.check(&cfg) == Some(false) {
+                        smallvec![]
+                    } else {
+                        cov_mark::hit!(cfg_attr_active);
+
+                        attrs.collect()
+                    }
+                })
+                .collect::<Vec<_>>();
+        let entries = if new_attrs.is_empty() {
+            None
+        } else {
+            Some(ThinArc::from_header_and_iter((), new_attrs.into_iter()))
+        };
+        RawAttrs { entries }
     }
 }
 
diff --git a/crates/ide-diagnostics/src/tests.rs b/crates/ide-diagnostics/src/tests.rs
index dcaa2120892..bb5c2b79139 100644
--- a/crates/ide-diagnostics/src/tests.rs
+++ b/crates/ide-diagnostics/src/tests.rs
@@ -283,6 +283,10 @@ fn test_disabled_diagnostics() {
 
 #[test]
 fn minicore_smoke_test() {
+    if test_utils::skip_slow_tests() {
+        return;
+    }
+
     fn check(minicore: MiniCore) {
         let source = minicore.source_code();
         let mut config = DiagnosticsConfig::test_sample();