Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 0036762

Browse files
committed
Make use of ThinArc in RawAttrs
1 parent 928d847 commit 0036762

File tree

2 files changed

+82
-62
lines changed

2 files changed

+82
-62
lines changed

crates/hir-expand/src/attrs.rs

Lines changed: 78 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
99
use smallvec::{smallvec, SmallVec};
1010
use span::{Span, SyntaxContextId};
1111
use syntax::{ast, format_smolstr, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
12-
use triomphe::Arc;
12+
use triomphe::ThinArc;
1313

1414
use crate::{
1515
db::ExpandDatabase,
@@ -22,16 +22,15 @@ use crate::{
2222
/// Syntactical attributes, without filtering of `cfg_attr`s.
2323
#[derive(Default, Debug, Clone, PartialEq, Eq)]
2424
pub struct RawAttrs {
25-
// FIXME: Make this a ThinArc
26-
entries: Option<Arc<[Attr]>>,
25+
entries: Option<ThinArc<(), Attr>>,
2726
}
2827

2928
impl ops::Deref for RawAttrs {
3029
type Target = [Attr];
3130

3231
fn deref(&self) -> &[Attr] {
3332
match &self.entries {
34-
Some(it) => it,
33+
Some(it) => &it.slice,
3534
None => &[],
3635
}
3736
}
@@ -45,27 +44,34 @@ impl RawAttrs {
4544
owner: &dyn ast::HasAttrs,
4645
span_map: SpanMapRef<'_>,
4746
) -> Self {
48-
let entries = collect_attrs(owner).filter_map(|(id, attr)| match attr {
49-
Either::Left(attr) => {
50-
attr.meta().and_then(|meta| Attr::from_src(db, meta, span_map, id))
51-
}
52-
Either::Right(comment) => comment.doc_comment().map(|doc| {
53-
let span = span_map.span_for_range(comment.syntax().text_range());
54-
Attr {
55-
id,
56-
input: Some(Interned::new(AttrInput::Literal(tt::Literal {
57-
// FIXME: Escape quotes from comment content
58-
text: SmolStr::new(format_smolstr!("\"{doc}\"",)),
59-
span,
60-
}))),
61-
path: Interned::new(ModPath::from(crate::name!(doc))),
62-
ctxt: span.ctx,
47+
let entries: Vec<_> = collect_attrs(owner)
48+
.filter_map(|(id, attr)| match attr {
49+
Either::Left(attr) => {
50+
attr.meta().and_then(|meta| Attr::from_src(db, meta, span_map, id))
6351
}
64-
}),
65-
});
66-
let entries: Arc<[Attr]> = Arc::from_iter(entries);
52+
Either::Right(comment) => comment.doc_comment().map(|doc| {
53+
let span = span_map.span_for_range(comment.syntax().text_range());
54+
Attr {
55+
id,
56+
input: Some(Interned::new(AttrInput::Literal(tt::Literal {
57+
// FIXME: Escape quotes from comment content
58+
text: SmolStr::new(format_smolstr!("\"{doc}\"",)),
59+
span,
60+
}))),
61+
path: Interned::new(ModPath::from(crate::name!(doc))),
62+
ctxt: span.ctx,
63+
}
64+
}),
65+
})
66+
.collect();
6767

68-
Self { entries: if entries.is_empty() { None } else { Some(entries) } }
68+
let entries = if entries.is_empty() {
69+
None
70+
} else {
71+
Some(ThinArc::from_header_and_iter((), entries.into_iter()))
72+
};
73+
74+
RawAttrs { entries }
6975
}
7076

7177
pub fn from_attrs_owner(
@@ -82,16 +88,20 @@ impl RawAttrs {
8288
(None, entries @ Some(_)) => Self { entries },
8389
(Some(entries), None) => Self { entries: Some(entries.clone()) },
8490
(Some(a), Some(b)) => {
85-
let last_ast_index = a.last().map_or(0, |it| it.id.ast_index() + 1) as u32;
86-
Self {
87-
entries: Some(Arc::from_iter(a.iter().cloned().chain(b.iter().map(|it| {
91+
let last_ast_index = a.slice.last().map_or(0, |it| it.id.ast_index() + 1) as u32;
92+
let items = a
93+
.slice
94+
.iter()
95+
.cloned()
96+
.chain(b.slice.iter().map(|it| {
8897
let mut it = it.clone();
8998
it.id.id = (it.id.ast_index() as u32 + last_ast_index)
9099
| (it.id.cfg_attr_index().unwrap_or(0) as u32)
91100
<< AttrId::AST_INDEX_BITS;
92101
it
93-
})))),
94-
}
102+
}))
103+
.collect::<Vec<_>>();
104+
Self { entries: Some(ThinArc::from_header_and_iter((), items.into_iter())) }
95105
}
96106
}
97107
}
@@ -107,41 +117,47 @@ impl RawAttrs {
107117
}
108118

109119
let crate_graph = db.crate_graph();
110-
let new_attrs = Arc::from_iter(self.iter().flat_map(|attr| -> SmallVec<[_; 1]> {
111-
let is_cfg_attr =
112-
attr.path.as_ident().map_or(false, |name| *name == crate::name![cfg_attr]);
113-
if !is_cfg_attr {
114-
return smallvec![attr.clone()];
115-
}
116-
117-
let subtree = match attr.token_tree_value() {
118-
Some(it) => it,
119-
_ => return smallvec![attr.clone()],
120-
};
121-
122-
let (cfg, parts) = match parse_cfg_attr_input(subtree) {
123-
Some(it) => it,
124-
None => return smallvec![attr.clone()],
125-
};
126-
let index = attr.id;
127-
let attrs = parts
128-
.enumerate()
129-
.take(1 << AttrId::CFG_ATTR_BITS)
130-
.filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)));
131-
132-
let cfg_options = &crate_graph[krate].cfg_options;
133-
let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) };
134-
let cfg = CfgExpr::parse(&cfg);
135-
if cfg_options.check(&cfg) == Some(false) {
136-
smallvec![]
137-
} else {
138-
cov_mark::hit!(cfg_attr_active);
139-
140-
attrs.collect()
141-
}
142-
}));
120+
let new_attrs =
121+
self.iter()
122+
.flat_map(|attr| -> SmallVec<[_; 1]> {
123+
let is_cfg_attr =
124+
attr.path.as_ident().map_or(false, |name| *name == crate::name![cfg_attr]);
125+
if !is_cfg_attr {
126+
return smallvec![attr.clone()];
127+
}
143128

144-
RawAttrs { entries: Some(new_attrs) }
129+
let subtree = match attr.token_tree_value() {
130+
Some(it) => it,
131+
_ => return smallvec![attr.clone()],
132+
};
133+
134+
let (cfg, parts) = match parse_cfg_attr_input(subtree) {
135+
Some(it) => it,
136+
None => return smallvec![attr.clone()],
137+
};
138+
let index = attr.id;
139+
let attrs = parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map(
140+
|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)),
141+
);
142+
143+
let cfg_options = &crate_graph[krate].cfg_options;
144+
let cfg = Subtree { delimiter: subtree.delimiter, token_trees: Box::from(cfg) };
145+
let cfg = CfgExpr::parse(&cfg);
146+
if cfg_options.check(&cfg) == Some(false) {
147+
smallvec![]
148+
} else {
149+
cov_mark::hit!(cfg_attr_active);
150+
151+
attrs.collect()
152+
}
153+
})
154+
.collect::<Vec<_>>();
155+
let entries = if new_attrs.is_empty() {
156+
None
157+
} else {
158+
Some(ThinArc::from_header_and_iter((), new_attrs.into_iter()))
159+
};
160+
RawAttrs { entries }
145161
}
146162
}
147163

crates/ide-diagnostics/src/tests.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,10 @@ fn test_disabled_diagnostics() {
283283

284284
#[test]
285285
fn minicore_smoke_test() {
286+
if test_utils::skip_slow_tests() {
287+
return;
288+
}
289+
286290
fn check(minicore: MiniCore) {
287291
let source = minicore.source_code();
288292
let mut config = DiagnosticsConfig::test_sample();

0 commit comments

Comments
 (0)