Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-expand/src/attrs.rs')
| -rw-r--r-- | crates/hir-expand/src/attrs.rs | 101 |
1 files changed, 54 insertions, 47 deletions
diff --git a/crates/hir-expand/src/attrs.rs b/crates/hir-expand/src/attrs.rs index 17360090db..3ff18e982e 100644 --- a/crates/hir-expand/src/attrs.rs +++ b/crates/hir-expand/src/attrs.rs @@ -1,5 +1,5 @@ //! A higher level attributes based on TokenTree, with also some shortcuts. -use std::{fmt, ops, sync::Arc}; +use std::{fmt, ops}; use base_db::CrateId; use cfg::CfgExpr; @@ -8,6 +8,7 @@ use intern::Interned; use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct}; use smallvec::{smallvec, SmallVec}; use syntax::{ast, match_ast, AstNode, SmolStr, SyntaxNode}; +use triomphe::Arc; use crate::{ db::ExpandDatabase, @@ -50,7 +51,9 @@ impl RawAttrs { path: Interned::new(ModPath::from(crate::name!(doc))), }), }) - .collect::<Arc<_>>(); + .collect::<Vec<_>>(); + // FIXME: use `Arc::from_iter` when it becomes available + let entries: Arc<[Attr]> = Arc::from(entries); Self { entries: if entries.is_empty() { None } else { Some(entries) } } } @@ -68,7 +71,7 @@ impl RawAttrs { (Some(a), Some(b)) => { let last_ast_index = a.last().map_or(0, |it| it.id.ast_index() + 1) as u32; Self { - entries: Some( + entries: Some(Arc::from( a.iter() .cloned() .chain(b.iter().map(|it| { @@ -78,8 +81,9 @@ impl RawAttrs { << AttrId::AST_INDEX_BITS; it })) - .collect(), - ), + // FIXME: use `Arc::from_iter` when it becomes available + .collect::<Vec<_>>(), + )), } } } @@ -96,48 +100,51 @@ impl RawAttrs { } let crate_graph = db.crate_graph(); - 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()]; - } - - 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)| { - let tree = Subtree { - delimiter: tt::Delimiter::unspecified(), - token_trees: attr.to_vec(), - }; - // FIXME hygiene - let hygiene = Hygiene::new_unhygienic(); - Attr::from_tt(db, &tree, &hygiene, index.with_cfg_attr(idx)) - }); - - let cfg_options = &crate_graph[krate].cfg_options; - let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() }; - let cfg = CfgExpr::parse(&cfg); - if cfg_options.check(&cfg) == Some(false) { - smallvec![] - } else { - cov_mark::hit!(cfg_attr_active); - - attrs.collect() - } - }) - .collect(); + let new_attrs = Arc::from( + 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)| { + let tree = Subtree { + delimiter: tt::Delimiter::unspecified(), + token_trees: attr.to_vec(), + }; + // FIXME hygiene + let hygiene = Hygiene::new_unhygienic(); + Attr::from_tt(db, &tree, &hygiene, index.with_cfg_attr(idx)) + }, + ); + + let cfg_options = &crate_graph[krate].cfg_options; + let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg.to_vec() }; + let cfg = CfgExpr::parse(&cfg); + if cfg_options.check(&cfg) == Some(false) { + smallvec![] + } else { + cov_mark::hit!(cfg_attr_active); + + attrs.collect() + } + }) + // FIXME: use `Arc::from_iter` when it becomes available + .collect::<Vec<_>>(), + ); RawAttrs { entries: Some(new_attrs) } } |