Skip to content

Commit 9ce066e

Browse files
committed
Use symbol in cfg
1 parent 7f8a54b commit 9ce066e

File tree

22 files changed

+147
-92
lines changed

22 files changed

+147
-92
lines changed

src/tools/rust-analyzer/Cargo.lock

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,10 @@ dependencies = [
146146
"arbitrary",
147147
"derive_arbitrary",
148148
"expect-test",
149+
"intern",
149150
"mbe",
150151
"oorandom",
151152
"rustc-hash",
152-
"smol_str",
153153
"syntax",
154154
"tt",
155155
]
@@ -1416,6 +1416,7 @@ dependencies = [
14161416
"cargo_metadata",
14171417
"cfg",
14181418
"expect-test",
1419+
"intern",
14191420
"itertools",
14201421
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
14211422
"paths",
@@ -1656,6 +1657,7 @@ dependencies = [
16561657
"ide",
16571658
"ide-db",
16581659
"ide-ssr",
1660+
"intern",
16591661
"itertools",
16601662
"load-cargo",
16611663
"lsp-server 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",

src/tools/rust-analyzer/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ debug = 2
5050
[workspace.dependencies]
5151
# local crates
5252
base-db = { path = "./crates/base-db", version = "0.0.0" }
53-
cfg = { path = "./crates/cfg", version = "0.0.0" }
53+
cfg = { path = "./crates/cfg", version = "0.0.0", features = ["tt"] }
5454
flycheck = { path = "./crates/flycheck", version = "0.0.0" }
5555
hir = { path = "./crates/hir", version = "0.0.0" }
5656
hir-def = { path = "./crates/hir-def", version = "0.0.0" }

src/tools/rust-analyzer/crates/cfg/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ doctest = false
1515
rustc-hash.workspace = true
1616

1717
# locals deps
18-
tt.workspace = true
19-
smol_str.workspace = true
18+
tt = { workspace = true, optional = true }
19+
intern.workspace = true
2020

2121
[dev-dependencies]
2222
expect-test = "1.4.1"

src/tools/rust-analyzer/crates/cfg/src/cfg_expr.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22
//!
33
//! See: <https://doc.rust-lang.org/reference/conditional-compilation.html#conditional-compilation>
44
5-
use std::{fmt, slice::Iter as SliceIter};
5+
use std::fmt;
66

7-
use smol_str::SmolStr;
7+
use intern::Symbol;
88

99
/// A simple configuration value passed in from the outside.
10-
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
10+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1111
pub enum CfgAtom {
1212
/// eg. `#[cfg(test)]`
13-
Flag(SmolStr),
13+
Flag(Symbol),
1414
/// eg. `#[cfg(target_os = "linux")]`
1515
///
1616
/// Note that a key can have multiple values that are all considered "active" at the same time.
1717
/// For example, `#[cfg(target_feature = "sse")]` and `#[cfg(target_feature = "sse2")]`.
18-
KeyValue { key: SmolStr, value: SmolStr },
18+
KeyValue { key: Symbol, value: Symbol },
1919
}
2020

2121
impl fmt::Display for CfgAtom {
@@ -44,6 +44,7 @@ impl From<CfgAtom> for CfgExpr {
4444
}
4545

4646
impl CfgExpr {
47+
#[cfg(feature = "tt")]
4748
pub fn parse<S>(tt: &tt::Subtree<S>) -> CfgExpr {
4849
next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid)
4950
}
@@ -63,7 +64,11 @@ impl CfgExpr {
6364
}
6465
}
6566
}
66-
fn next_cfg_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<CfgExpr> {
67+
68+
#[cfg(feature = "tt")]
69+
fn next_cfg_expr<S>(it: &mut std::slice::Iter<'_, tt::TokenTree<S>>) -> Option<CfgExpr> {
70+
use intern::sym;
71+
6772
let name = match it.next() {
6873
None => return None,
6974
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.sym.clone(),
@@ -77,9 +82,7 @@ fn next_cfg_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<CfgExpr>
7782
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
7883
it.next();
7984
it.next();
80-
// FIXME: escape?
81-
let value = literal.symbol.as_str().into();
82-
CfgAtom::KeyValue { key: name.as_str().into(), value }.into()
85+
CfgAtom::KeyValue { key: name, value: literal.symbol.clone() }.into()
8386
}
8487
_ => return Some(CfgExpr::Invalid),
8588
}
@@ -88,14 +91,16 @@ fn next_cfg_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<CfgExpr>
8891
it.next();
8992
let mut sub_it = subtree.token_trees.iter();
9093
let mut subs = std::iter::from_fn(|| next_cfg_expr(&mut sub_it)).collect();
91-
match name.as_str() {
92-
"all" => CfgExpr::All(subs),
93-
"any" => CfgExpr::Any(subs),
94-
"not" => CfgExpr::Not(Box::new(subs.pop().unwrap_or(CfgExpr::Invalid))),
94+
match &name {
95+
s if *s == sym::all => CfgExpr::All(subs),
96+
s if *s == sym::any => CfgExpr::Any(subs),
97+
s if *s == sym::not => {
98+
CfgExpr::Not(Box::new(subs.pop().unwrap_or(CfgExpr::Invalid)))
99+
}
95100
_ => CfgExpr::Invalid,
96101
}
97102
}
98-
_ => CfgAtom::Flag(name.as_str().into()).into(),
103+
_ => CfgAtom::Flag(name).into(),
99104
};
100105

101106
// Eat comma separator
@@ -111,11 +116,11 @@ fn next_cfg_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<CfgExpr>
111116
impl arbitrary::Arbitrary<'_> for CfgAtom {
112117
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
113118
if u.arbitrary()? {
114-
Ok(CfgAtom::Flag(String::arbitrary(u)?.into()))
119+
Ok(CfgAtom::Flag(Symbol::intern(<_>::arbitrary(u)?)))
115120
} else {
116121
Ok(CfgAtom::KeyValue {
117-
key: String::arbitrary(u)?.into(),
118-
value: String::arbitrary(u)?.into(),
122+
key: Symbol::intern(<_>::arbitrary(u)?),
123+
value: Symbol::intern(<_>::arbitrary(u)?),
119124
})
120125
}
121126
}

src/tools/rust-analyzer/crates/cfg/src/dnf.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ impl DnfExpr {
6666
}
6767
}
6868

69-
res.enabled.sort_unstable();
69+
res.enabled.sort_unstable_by(compare);
7070
res.enabled.dedup();
71-
res.disabled.sort_unstable();
71+
res.disabled.sort_unstable_by(compare);
7272
res.disabled.dedup();
7373
Some(res)
7474
}
@@ -114,14 +114,25 @@ impl DnfExpr {
114114
};
115115

116116
// Undo the FxHashMap randomization for consistent output.
117-
diff.enable.sort_unstable();
118-
diff.disable.sort_unstable();
117+
diff.enable.sort_unstable_by(compare);
118+
diff.disable.sort_unstable_by(compare);
119119

120120
Some(diff)
121121
})
122122
}
123123
}
124124

125+
fn compare(a: &CfgAtom, b: &CfgAtom) -> std::cmp::Ordering {
126+
match (a, b) {
127+
(CfgAtom::Flag(a), CfgAtom::Flag(b)) => a.as_str().cmp(b.as_str()),
128+
(CfgAtom::Flag(_), CfgAtom::KeyValue { .. }) => std::cmp::Ordering::Less,
129+
(CfgAtom::KeyValue { .. }, CfgAtom::Flag(_)) => std::cmp::Ordering::Greater,
130+
(CfgAtom::KeyValue { key, value }, CfgAtom::KeyValue { key: key2, value: value2 }) => {
131+
key.as_str().cmp(key2.as_str()).then(value.as_str().cmp(value2.as_str()))
132+
}
133+
}
134+
}
135+
125136
impl fmt::Display for DnfExpr {
126137
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127138
if self.conjunctions.len() != 1 {

src/tools/rust-analyzer/crates/cfg/src/lib.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ use std::fmt;
99

1010
use rustc_hash::FxHashSet;
1111

12+
use intern::Symbol;
13+
1214
pub use cfg_expr::{CfgAtom, CfgExpr};
1315
pub use dnf::DnfExpr;
14-
use smol_str::SmolStr;
1516

1617
/// Configuration options used for conditional compilation on items with `cfg` attributes.
1718
/// We have two kind of options in different namespaces: atomic options like `unix`, and
@@ -48,11 +49,11 @@ impl CfgOptions {
4849
cfg.fold(&|atom| self.enabled.contains(atom))
4950
}
5051

51-
pub fn insert_atom(&mut self, key: SmolStr) {
52+
pub fn insert_atom(&mut self, key: Symbol) {
5253
self.enabled.insert(CfgAtom::Flag(key));
5354
}
5455

55-
pub fn insert_key_value(&mut self, key: SmolStr, value: SmolStr) {
56+
pub fn insert_key_value(&mut self, key: Symbol, value: Symbol) {
5657
self.enabled.insert(CfgAtom::KeyValue { key, value });
5758
}
5859

@@ -66,19 +67,16 @@ impl CfgOptions {
6667
}
6768
}
6869

69-
pub fn get_cfg_keys(&self) -> impl Iterator<Item = &SmolStr> {
70+
pub fn get_cfg_keys(&self) -> impl Iterator<Item = &Symbol> {
7071
self.enabled.iter().map(|it| match it {
7172
CfgAtom::Flag(key) => key,
7273
CfgAtom::KeyValue { key, .. } => key,
7374
})
7475
}
7576

76-
pub fn get_cfg_values<'a>(
77-
&'a self,
78-
cfg_key: &'a str,
79-
) -> impl Iterator<Item = &'a SmolStr> + 'a {
77+
pub fn get_cfg_values<'a>(&'a self, cfg_key: &'a str) -> impl Iterator<Item = &'a Symbol> + 'a {
8078
self.enabled.iter().filter_map(move |it| match it {
81-
CfgAtom::KeyValue { key, value } if cfg_key == key => Some(value),
79+
CfgAtom::KeyValue { key, value } if cfg_key == key.as_str() => Some(value),
8280
_ => None,
8381
})
8482
}

src/tools/rust-analyzer/crates/cfg/src/tests.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use arbitrary::{Arbitrary, Unstructured};
22
use expect_test::{expect, Expect};
3+
use intern::Symbol;
34
use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode, DummyTestSpanMap, DUMMY};
45
use syntax::{ast, AstNode, Edition};
56

@@ -65,22 +66,25 @@ fn check_enable_hints(input: &str, opts: &CfgOptions, expected_hints: &[&str]) {
6566

6667
#[test]
6768
fn test_cfg_expr_parser() {
68-
assert_parse_result("#![cfg(foo)]", CfgAtom::Flag("foo".into()).into());
69-
assert_parse_result("#![cfg(foo,)]", CfgAtom::Flag("foo".into()).into());
69+
assert_parse_result("#![cfg(foo)]", CfgAtom::Flag(Symbol::intern("foo")).into());
70+
assert_parse_result("#![cfg(foo,)]", CfgAtom::Flag(Symbol::intern("foo")).into());
7071
assert_parse_result(
7172
"#![cfg(not(foo))]",
72-
CfgExpr::Not(Box::new(CfgAtom::Flag("foo".into()).into())),
73+
CfgExpr::Not(Box::new(CfgAtom::Flag(Symbol::intern("foo")).into())),
7374
);
7475
assert_parse_result("#![cfg(foo(bar))]", CfgExpr::Invalid);
7576

7677
// Only take the first
77-
assert_parse_result(r#"#![cfg(foo, bar = "baz")]"#, CfgAtom::Flag("foo".into()).into());
78+
assert_parse_result(
79+
r#"#![cfg(foo, bar = "baz")]"#,
80+
CfgAtom::Flag(Symbol::intern("foo")).into(),
81+
);
7882

7983
assert_parse_result(
8084
r#"#![cfg(all(foo, bar = "baz"))]"#,
8185
CfgExpr::All(vec![
82-
CfgAtom::Flag("foo".into()).into(),
83-
CfgAtom::KeyValue { key: "bar".into(), value: "baz".into() }.into(),
86+
CfgAtom::Flag(Symbol::intern("foo")).into(),
87+
CfgAtom::KeyValue { key: Symbol::intern("bar"), value: Symbol::intern("baz") }.into(),
8488
]),
8589
);
8690

@@ -90,7 +94,7 @@ fn test_cfg_expr_parser() {
9094
CfgExpr::Not(Box::new(CfgExpr::Invalid)),
9195
CfgExpr::All(vec![]),
9296
CfgExpr::Invalid,
93-
CfgAtom::KeyValue { key: "bar".into(), value: "baz".into() }.into(),
97+
CfgAtom::KeyValue { key: Symbol::intern("bar"), value: Symbol::intern("baz") }.into(),
9498
]),
9599
);
96100
}
@@ -167,7 +171,7 @@ fn hints() {
167171

168172
check_enable_hints("#![cfg(all(a, b))]", &opts, &["enable a and b"]);
169173

170-
opts.insert_atom("test".into());
174+
opts.insert_atom(Symbol::intern("test"));
171175

172176
check_enable_hints("#![cfg(test)]", &opts, &[]);
173177
check_enable_hints("#![cfg(not(test))]", &opts, &["disable test"]);
@@ -180,16 +184,16 @@ fn hints_impossible() {
180184

181185
check_enable_hints("#![cfg(all(test, not(test)))]", &opts, &[]);
182186

183-
opts.insert_atom("test".into());
187+
opts.insert_atom(Symbol::intern("test"));
184188

185189
check_enable_hints("#![cfg(all(test, not(test)))]", &opts, &[]);
186190
}
187191

188192
#[test]
189193
fn why_inactive() {
190194
let mut opts = CfgOptions::default();
191-
opts.insert_atom("test".into());
192-
opts.insert_atom("test2".into());
195+
opts.insert_atom(Symbol::intern("test"));
196+
opts.insert_atom(Symbol::intern("test2"));
193197

194198
check_why_inactive("#![cfg(a)]", &opts, expect![["a is disabled"]]);
195199
check_why_inactive("#![cfg(not(test))]", &opts, expect![["test is enabled"]]);

src/tools/rust-analyzer/crates/hir-expand/src/builtin_fn_macro.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,12 @@ fn concat_bytes_expand(
563563
};
564564
for (i, t) in tt.token_trees.iter().enumerate() {
565565
match t {
566-
tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { symbol: text, span, kind, suffix: _ })) => {
566+
tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal {
567+
symbol: text,
568+
span,
569+
kind,
570+
suffix: _,
571+
})) => {
567572
record_span(*span);
568573
match kind {
569574
tt::LitKind::Byte => {

src/tools/rust-analyzer/crates/hir-expand/src/cfg_process.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::iter::Peekable;
33

44
use base_db::CrateId;
55
use cfg::{CfgAtom, CfgExpr};
6+
use intern::{sym, Symbol};
67
use rustc_hash::FxHashSet;
78
use syntax::{
89
ast::{self, Attr, HasAttrs, Meta, VariantList},
@@ -262,13 +263,13 @@ where
262263
let name = match iter.next() {
263264
None => return None,
264265
Some(NodeOrToken::Token(element)) => match element.kind() {
265-
syntax::T![ident] => element.text().to_owned(),
266+
syntax::T![ident] => Symbol::intern(element.text()),
266267
_ => return Some(CfgExpr::Invalid),
267268
},
268269
Some(_) => return Some(CfgExpr::Invalid),
269270
};
270-
let result = match name.as_str() {
271-
"all" | "any" | "not" => {
271+
let result = match &name {
272+
s if [&sym::all, &sym::any, &sym::not].contains(&s) => {
272273
let mut preds = Vec::new();
273274
let Some(NodeOrToken::Node(tree)) = iter.next() else {
274275
return Some(CfgExpr::Invalid);
@@ -285,10 +286,12 @@ where
285286
preds.push(pred);
286287
}
287288
}
288-
let group = match name.as_str() {
289-
"all" => CfgExpr::All(preds),
290-
"any" => CfgExpr::Any(preds),
291-
"not" => CfgExpr::Not(Box::new(preds.pop().unwrap_or(CfgExpr::Invalid))),
289+
let group = match &name {
290+
s if *s == sym::all => CfgExpr::All(preds),
291+
s if *s == sym::any => CfgExpr::Any(preds),
292+
s if *s == sym::not => {
293+
CfgExpr::Not(Box::new(preds.pop().unwrap_or(CfgExpr::Invalid)))
294+
}
292295
_ => unreachable!(),
293296
};
294297
Some(group)
@@ -301,13 +304,15 @@ where
301304
if (value_token.kind() == syntax::SyntaxKind::STRING) =>
302305
{
303306
let value = value_token.text();
304-
let value = value.trim_matches('"').into();
305-
Some(CfgExpr::Atom(CfgAtom::KeyValue { key: name.into(), value }))
307+
Some(CfgExpr::Atom(CfgAtom::KeyValue {
308+
key: name,
309+
value: Symbol::intern(value.trim_matches('"')),
310+
}))
306311
}
307312
_ => None,
308313
}
309314
}
310-
_ => Some(CfgExpr::Atom(CfgAtom::Flag(name.into()))),
315+
_ => Some(CfgExpr::Atom(CfgAtom::Flag(name))),
311316
},
312317
};
313318
if let Some(NodeOrToken::Token(element)) = iter.peek() {

src/tools/rust-analyzer/crates/ide-completion/src/completions/attribute/cfg.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
3939
"target_vendor" => KNOWN_VENDOR.iter().copied().for_each(add_completion),
4040
"target_endian" => ["little", "big"].into_iter().for_each(add_completion),
4141
name => ctx.krate.potential_cfg(ctx.db).get_cfg_values(name).cloned().for_each(|s| {
42+
let s = s.as_str();
4243
let insert_text = format!(r#""{s}""#);
4344
let mut item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
4445
item.insert_text(insert_text);
@@ -47,6 +48,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
4748
}),
4849
},
4950
None => ctx.krate.potential_cfg(ctx.db).get_cfg_keys().cloned().unique().for_each(|s| {
51+
let s = s.as_str();
5052
let item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
5153
acc.add(item.build(ctx.db));
5254
}),

0 commit comments

Comments
 (0)