mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 21:13:37 +00:00
Use symbol in cfg
This commit is contained in:
parent
93024ad411
commit
c30bdfcc84
22 changed files with 147 additions and 92 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -146,10 +146,10 @@ dependencies = [
|
||||||
"arbitrary",
|
"arbitrary",
|
||||||
"derive_arbitrary",
|
"derive_arbitrary",
|
||||||
"expect-test",
|
"expect-test",
|
||||||
|
"intern",
|
||||||
"mbe",
|
"mbe",
|
||||||
"oorandom",
|
"oorandom",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
"smol_str",
|
|
||||||
"syntax",
|
"syntax",
|
||||||
"tt",
|
"tt",
|
||||||
]
|
]
|
||||||
|
@ -1416,6 +1416,7 @@ dependencies = [
|
||||||
"cargo_metadata",
|
"cargo_metadata",
|
||||||
"cfg",
|
"cfg",
|
||||||
"expect-test",
|
"expect-test",
|
||||||
|
"intern",
|
||||||
"itertools",
|
"itertools",
|
||||||
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"paths",
|
"paths",
|
||||||
|
@ -1656,6 +1657,7 @@ dependencies = [
|
||||||
"ide",
|
"ide",
|
||||||
"ide-db",
|
"ide-db",
|
||||||
"ide-ssr",
|
"ide-ssr",
|
||||||
|
"intern",
|
||||||
"itertools",
|
"itertools",
|
||||||
"load-cargo",
|
"load-cargo",
|
||||||
"lsp-server 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lsp-server 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
|
|
@ -50,7 +50,7 @@ debug = 2
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
# local crates
|
# local crates
|
||||||
base-db = { path = "./crates/base-db", version = "0.0.0" }
|
base-db = { path = "./crates/base-db", version = "0.0.0" }
|
||||||
cfg = { path = "./crates/cfg", version = "0.0.0" }
|
cfg = { path = "./crates/cfg", version = "0.0.0", features = ["tt"] }
|
||||||
flycheck = { path = "./crates/flycheck", version = "0.0.0" }
|
flycheck = { path = "./crates/flycheck", version = "0.0.0" }
|
||||||
hir = { path = "./crates/hir", version = "0.0.0" }
|
hir = { path = "./crates/hir", version = "0.0.0" }
|
||||||
hir-def = { path = "./crates/hir-def", version = "0.0.0" }
|
hir-def = { path = "./crates/hir-def", version = "0.0.0" }
|
||||||
|
|
|
@ -15,8 +15,8 @@ doctest = false
|
||||||
rustc-hash.workspace = true
|
rustc-hash.workspace = true
|
||||||
|
|
||||||
# locals deps
|
# locals deps
|
||||||
tt.workspace = true
|
tt = { workspace = true, optional = true }
|
||||||
smol_str.workspace = true
|
intern.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
expect-test = "1.4.1"
|
expect-test = "1.4.1"
|
||||||
|
|
|
@ -2,20 +2,20 @@
|
||||||
//!
|
//!
|
||||||
//! See: <https://doc.rust-lang.org/reference/conditional-compilation.html#conditional-compilation>
|
//! See: <https://doc.rust-lang.org/reference/conditional-compilation.html#conditional-compilation>
|
||||||
|
|
||||||
use std::{fmt, slice::Iter as SliceIter};
|
use std::fmt;
|
||||||
|
|
||||||
use smol_str::SmolStr;
|
use intern::Symbol;
|
||||||
|
|
||||||
/// A simple configuration value passed in from the outside.
|
/// A simple configuration value passed in from the outside.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum CfgAtom {
|
pub enum CfgAtom {
|
||||||
/// eg. `#[cfg(test)]`
|
/// eg. `#[cfg(test)]`
|
||||||
Flag(SmolStr),
|
Flag(Symbol),
|
||||||
/// eg. `#[cfg(target_os = "linux")]`
|
/// eg. `#[cfg(target_os = "linux")]`
|
||||||
///
|
///
|
||||||
/// Note that a key can have multiple values that are all considered "active" at the same time.
|
/// Note that a key can have multiple values that are all considered "active" at the same time.
|
||||||
/// For example, `#[cfg(target_feature = "sse")]` and `#[cfg(target_feature = "sse2")]`.
|
/// For example, `#[cfg(target_feature = "sse")]` and `#[cfg(target_feature = "sse2")]`.
|
||||||
KeyValue { key: SmolStr, value: SmolStr },
|
KeyValue { key: Symbol, value: Symbol },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CfgAtom {
|
impl fmt::Display for CfgAtom {
|
||||||
|
@ -44,6 +44,7 @@ impl From<CfgAtom> for CfgExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CfgExpr {
|
impl CfgExpr {
|
||||||
|
#[cfg(feature = "tt")]
|
||||||
pub fn parse<S>(tt: &tt::Subtree<S>) -> CfgExpr {
|
pub fn parse<S>(tt: &tt::Subtree<S>) -> CfgExpr {
|
||||||
next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid)
|
next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid)
|
||||||
}
|
}
|
||||||
|
@ -63,7 +64,11 @@ impl CfgExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn next_cfg_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<CfgExpr> {
|
|
||||||
|
#[cfg(feature = "tt")]
|
||||||
|
fn next_cfg_expr<S>(it: &mut std::slice::Iter<'_, tt::TokenTree<S>>) -> Option<CfgExpr> {
|
||||||
|
use intern::sym;
|
||||||
|
|
||||||
let name = match it.next() {
|
let name = match it.next() {
|
||||||
None => return None,
|
None => return None,
|
||||||
Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) => ident.sym.clone(),
|
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>
|
||||||
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
|
Some(tt::TokenTree::Leaf(tt::Leaf::Literal(literal))) => {
|
||||||
it.next();
|
it.next();
|
||||||
it.next();
|
it.next();
|
||||||
// FIXME: escape?
|
CfgAtom::KeyValue { key: name, value: literal.symbol.clone() }.into()
|
||||||
let value = literal.symbol.as_str().into();
|
|
||||||
CfgAtom::KeyValue { key: name.as_str().into(), value }.into()
|
|
||||||
}
|
}
|
||||||
_ => return Some(CfgExpr::Invalid),
|
_ => return Some(CfgExpr::Invalid),
|
||||||
}
|
}
|
||||||
|
@ -88,14 +91,16 @@ fn next_cfg_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<CfgExpr>
|
||||||
it.next();
|
it.next();
|
||||||
let mut sub_it = subtree.token_trees.iter();
|
let mut sub_it = subtree.token_trees.iter();
|
||||||
let mut subs = std::iter::from_fn(|| next_cfg_expr(&mut sub_it)).collect();
|
let mut subs = std::iter::from_fn(|| next_cfg_expr(&mut sub_it)).collect();
|
||||||
match name.as_str() {
|
match &name {
|
||||||
"all" => CfgExpr::All(subs),
|
s if *s == sym::all => CfgExpr::All(subs),
|
||||||
"any" => CfgExpr::Any(subs),
|
s if *s == sym::any => CfgExpr::Any(subs),
|
||||||
"not" => CfgExpr::Not(Box::new(subs.pop().unwrap_or(CfgExpr::Invalid))),
|
s if *s == sym::not => {
|
||||||
|
CfgExpr::Not(Box::new(subs.pop().unwrap_or(CfgExpr::Invalid)))
|
||||||
|
}
|
||||||
_ => CfgExpr::Invalid,
|
_ => CfgExpr::Invalid,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => CfgAtom::Flag(name.as_str().into()).into(),
|
_ => CfgAtom::Flag(name).into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Eat comma separator
|
// Eat comma separator
|
||||||
|
@ -111,11 +116,11 @@ fn next_cfg_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<CfgExpr>
|
||||||
impl arbitrary::Arbitrary<'_> for CfgAtom {
|
impl arbitrary::Arbitrary<'_> for CfgAtom {
|
||||||
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
|
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
|
||||||
if u.arbitrary()? {
|
if u.arbitrary()? {
|
||||||
Ok(CfgAtom::Flag(String::arbitrary(u)?.into()))
|
Ok(CfgAtom::Flag(Symbol::intern(<_>::arbitrary(u)?)))
|
||||||
} else {
|
} else {
|
||||||
Ok(CfgAtom::KeyValue {
|
Ok(CfgAtom::KeyValue {
|
||||||
key: String::arbitrary(u)?.into(),
|
key: Symbol::intern(<_>::arbitrary(u)?),
|
||||||
value: String::arbitrary(u)?.into(),
|
value: Symbol::intern(<_>::arbitrary(u)?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,9 +66,9 @@ impl DnfExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res.enabled.sort_unstable();
|
res.enabled.sort_unstable_by(compare);
|
||||||
res.enabled.dedup();
|
res.enabled.dedup();
|
||||||
res.disabled.sort_unstable();
|
res.disabled.sort_unstable_by(compare);
|
||||||
res.disabled.dedup();
|
res.disabled.dedup();
|
||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
|
@ -114,14 +114,25 @@ impl DnfExpr {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Undo the FxHashMap randomization for consistent output.
|
// Undo the FxHashMap randomization for consistent output.
|
||||||
diff.enable.sort_unstable();
|
diff.enable.sort_unstable_by(compare);
|
||||||
diff.disable.sort_unstable();
|
diff.disable.sort_unstable_by(compare);
|
||||||
|
|
||||||
Some(diff)
|
Some(diff)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compare(a: &CfgAtom, b: &CfgAtom) -> std::cmp::Ordering {
|
||||||
|
match (a, b) {
|
||||||
|
(CfgAtom::Flag(a), CfgAtom::Flag(b)) => a.as_str().cmp(b.as_str()),
|
||||||
|
(CfgAtom::Flag(_), CfgAtom::KeyValue { .. }) => std::cmp::Ordering::Less,
|
||||||
|
(CfgAtom::KeyValue { .. }, CfgAtom::Flag(_)) => std::cmp::Ordering::Greater,
|
||||||
|
(CfgAtom::KeyValue { key, value }, CfgAtom::KeyValue { key: key2, value: value2 }) => {
|
||||||
|
key.as_str().cmp(key2.as_str()).then(value.as_str().cmp(value2.as_str()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for DnfExpr {
|
impl fmt::Display for DnfExpr {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
if self.conjunctions.len() != 1 {
|
if self.conjunctions.len() != 1 {
|
||||||
|
|
|
@ -9,9 +9,10 @@ use std::fmt;
|
||||||
|
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
|
|
||||||
|
use intern::Symbol;
|
||||||
|
|
||||||
pub use cfg_expr::{CfgAtom, CfgExpr};
|
pub use cfg_expr::{CfgAtom, CfgExpr};
|
||||||
pub use dnf::DnfExpr;
|
pub use dnf::DnfExpr;
|
||||||
use smol_str::SmolStr;
|
|
||||||
|
|
||||||
/// Configuration options used for conditional compilation on items with `cfg` attributes.
|
/// Configuration options used for conditional compilation on items with `cfg` attributes.
|
||||||
/// We have two kind of options in different namespaces: atomic options like `unix`, and
|
/// We have two kind of options in different namespaces: atomic options like `unix`, and
|
||||||
|
@ -48,11 +49,11 @@ impl CfgOptions {
|
||||||
cfg.fold(&|atom| self.enabled.contains(atom))
|
cfg.fold(&|atom| self.enabled.contains(atom))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_atom(&mut self, key: SmolStr) {
|
pub fn insert_atom(&mut self, key: Symbol) {
|
||||||
self.enabled.insert(CfgAtom::Flag(key));
|
self.enabled.insert(CfgAtom::Flag(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_key_value(&mut self, key: SmolStr, value: SmolStr) {
|
pub fn insert_key_value(&mut self, key: Symbol, value: Symbol) {
|
||||||
self.enabled.insert(CfgAtom::KeyValue { key, value });
|
self.enabled.insert(CfgAtom::KeyValue { key, value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,19 +67,16 @@ impl CfgOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cfg_keys(&self) -> impl Iterator<Item = &SmolStr> {
|
pub fn get_cfg_keys(&self) -> impl Iterator<Item = &Symbol> {
|
||||||
self.enabled.iter().map(|it| match it {
|
self.enabled.iter().map(|it| match it {
|
||||||
CfgAtom::Flag(key) => key,
|
CfgAtom::Flag(key) => key,
|
||||||
CfgAtom::KeyValue { key, .. } => key,
|
CfgAtom::KeyValue { key, .. } => key,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_cfg_values<'a>(
|
pub fn get_cfg_values<'a>(&'a self, cfg_key: &'a str) -> impl Iterator<Item = &'a Symbol> + 'a {
|
||||||
&'a self,
|
|
||||||
cfg_key: &'a str,
|
|
||||||
) -> impl Iterator<Item = &'a SmolStr> + 'a {
|
|
||||||
self.enabled.iter().filter_map(move |it| match it {
|
self.enabled.iter().filter_map(move |it| match it {
|
||||||
CfgAtom::KeyValue { key, value } if cfg_key == key => Some(value),
|
CfgAtom::KeyValue { key, value } if cfg_key == key.as_str() => Some(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use arbitrary::{Arbitrary, Unstructured};
|
use arbitrary::{Arbitrary, Unstructured};
|
||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
|
use intern::Symbol;
|
||||||
use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode, DummyTestSpanMap, DUMMY};
|
use mbe::{syntax_node_to_token_tree, DocCommentDesugarMode, DummyTestSpanMap, DUMMY};
|
||||||
use syntax::{ast, AstNode, Edition};
|
use syntax::{ast, AstNode, Edition};
|
||||||
|
|
||||||
|
@ -65,22 +66,25 @@ fn check_enable_hints(input: &str, opts: &CfgOptions, expected_hints: &[&str]) {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_cfg_expr_parser() {
|
fn test_cfg_expr_parser() {
|
||||||
assert_parse_result("#![cfg(foo)]", CfgAtom::Flag("foo".into()).into());
|
assert_parse_result("#![cfg(foo)]", CfgAtom::Flag(Symbol::intern("foo")).into());
|
||||||
assert_parse_result("#![cfg(foo,)]", CfgAtom::Flag("foo".into()).into());
|
assert_parse_result("#![cfg(foo,)]", CfgAtom::Flag(Symbol::intern("foo")).into());
|
||||||
assert_parse_result(
|
assert_parse_result(
|
||||||
"#![cfg(not(foo))]",
|
"#![cfg(not(foo))]",
|
||||||
CfgExpr::Not(Box::new(CfgAtom::Flag("foo".into()).into())),
|
CfgExpr::Not(Box::new(CfgAtom::Flag(Symbol::intern("foo")).into())),
|
||||||
);
|
);
|
||||||
assert_parse_result("#![cfg(foo(bar))]", CfgExpr::Invalid);
|
assert_parse_result("#![cfg(foo(bar))]", CfgExpr::Invalid);
|
||||||
|
|
||||||
// Only take the first
|
// Only take the first
|
||||||
assert_parse_result(r#"#![cfg(foo, bar = "baz")]"#, CfgAtom::Flag("foo".into()).into());
|
assert_parse_result(
|
||||||
|
r#"#![cfg(foo, bar = "baz")]"#,
|
||||||
|
CfgAtom::Flag(Symbol::intern("foo")).into(),
|
||||||
|
);
|
||||||
|
|
||||||
assert_parse_result(
|
assert_parse_result(
|
||||||
r#"#![cfg(all(foo, bar = "baz"))]"#,
|
r#"#![cfg(all(foo, bar = "baz"))]"#,
|
||||||
CfgExpr::All(vec![
|
CfgExpr::All(vec![
|
||||||
CfgAtom::Flag("foo".into()).into(),
|
CfgAtom::Flag(Symbol::intern("foo")).into(),
|
||||||
CfgAtom::KeyValue { key: "bar".into(), value: "baz".into() }.into(),
|
CfgAtom::KeyValue { key: Symbol::intern("bar"), value: Symbol::intern("baz") }.into(),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -90,7 +94,7 @@ fn test_cfg_expr_parser() {
|
||||||
CfgExpr::Not(Box::new(CfgExpr::Invalid)),
|
CfgExpr::Not(Box::new(CfgExpr::Invalid)),
|
||||||
CfgExpr::All(vec![]),
|
CfgExpr::All(vec![]),
|
||||||
CfgExpr::Invalid,
|
CfgExpr::Invalid,
|
||||||
CfgAtom::KeyValue { key: "bar".into(), value: "baz".into() }.into(),
|
CfgAtom::KeyValue { key: Symbol::intern("bar"), value: Symbol::intern("baz") }.into(),
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -167,7 +171,7 @@ fn hints() {
|
||||||
|
|
||||||
check_enable_hints("#![cfg(all(a, b))]", &opts, &["enable a and b"]);
|
check_enable_hints("#![cfg(all(a, b))]", &opts, &["enable a and b"]);
|
||||||
|
|
||||||
opts.insert_atom("test".into());
|
opts.insert_atom(Symbol::intern("test"));
|
||||||
|
|
||||||
check_enable_hints("#![cfg(test)]", &opts, &[]);
|
check_enable_hints("#![cfg(test)]", &opts, &[]);
|
||||||
check_enable_hints("#![cfg(not(test))]", &opts, &["disable test"]);
|
check_enable_hints("#![cfg(not(test))]", &opts, &["disable test"]);
|
||||||
|
@ -180,7 +184,7 @@ fn hints_impossible() {
|
||||||
|
|
||||||
check_enable_hints("#![cfg(all(test, not(test)))]", &opts, &[]);
|
check_enable_hints("#![cfg(all(test, not(test)))]", &opts, &[]);
|
||||||
|
|
||||||
opts.insert_atom("test".into());
|
opts.insert_atom(Symbol::intern("test"));
|
||||||
|
|
||||||
check_enable_hints("#![cfg(all(test, not(test)))]", &opts, &[]);
|
check_enable_hints("#![cfg(all(test, not(test)))]", &opts, &[]);
|
||||||
}
|
}
|
||||||
|
@ -188,8 +192,8 @@ fn hints_impossible() {
|
||||||
#[test]
|
#[test]
|
||||||
fn why_inactive() {
|
fn why_inactive() {
|
||||||
let mut opts = CfgOptions::default();
|
let mut opts = CfgOptions::default();
|
||||||
opts.insert_atom("test".into());
|
opts.insert_atom(Symbol::intern("test"));
|
||||||
opts.insert_atom("test2".into());
|
opts.insert_atom(Symbol::intern("test2"));
|
||||||
|
|
||||||
check_why_inactive("#![cfg(a)]", &opts, expect![["a is disabled"]]);
|
check_why_inactive("#![cfg(a)]", &opts, expect![["a is disabled"]]);
|
||||||
check_why_inactive("#![cfg(not(test))]", &opts, expect![["test is enabled"]]);
|
check_why_inactive("#![cfg(not(test))]", &opts, expect![["test is enabled"]]);
|
||||||
|
|
|
@ -563,7 +563,12 @@ fn concat_bytes_expand(
|
||||||
};
|
};
|
||||||
for (i, t) in tt.token_trees.iter().enumerate() {
|
for (i, t) in tt.token_trees.iter().enumerate() {
|
||||||
match t {
|
match t {
|
||||||
tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { symbol: text, span, kind, suffix: _ })) => {
|
tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal {
|
||||||
|
symbol: text,
|
||||||
|
span,
|
||||||
|
kind,
|
||||||
|
suffix: _,
|
||||||
|
})) => {
|
||||||
record_span(*span);
|
record_span(*span);
|
||||||
match kind {
|
match kind {
|
||||||
tt::LitKind::Byte => {
|
tt::LitKind::Byte => {
|
||||||
|
|
|
@ -3,6 +3,7 @@ use std::iter::Peekable;
|
||||||
|
|
||||||
use base_db::CrateId;
|
use base_db::CrateId;
|
||||||
use cfg::{CfgAtom, CfgExpr};
|
use cfg::{CfgAtom, CfgExpr};
|
||||||
|
use intern::{sym, Symbol};
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use syntax::{
|
use syntax::{
|
||||||
ast::{self, Attr, HasAttrs, Meta, VariantList},
|
ast::{self, Attr, HasAttrs, Meta, VariantList},
|
||||||
|
@ -262,13 +263,13 @@ where
|
||||||
let name = match iter.next() {
|
let name = match iter.next() {
|
||||||
None => return None,
|
None => return None,
|
||||||
Some(NodeOrToken::Token(element)) => match element.kind() {
|
Some(NodeOrToken::Token(element)) => match element.kind() {
|
||||||
syntax::T![ident] => element.text().to_owned(),
|
syntax::T![ident] => Symbol::intern(element.text()),
|
||||||
_ => return Some(CfgExpr::Invalid),
|
_ => return Some(CfgExpr::Invalid),
|
||||||
},
|
},
|
||||||
Some(_) => return Some(CfgExpr::Invalid),
|
Some(_) => return Some(CfgExpr::Invalid),
|
||||||
};
|
};
|
||||||
let result = match name.as_str() {
|
let result = match &name {
|
||||||
"all" | "any" | "not" => {
|
s if [&sym::all, &sym::any, &sym::not].contains(&s) => {
|
||||||
let mut preds = Vec::new();
|
let mut preds = Vec::new();
|
||||||
let Some(NodeOrToken::Node(tree)) = iter.next() else {
|
let Some(NodeOrToken::Node(tree)) = iter.next() else {
|
||||||
return Some(CfgExpr::Invalid);
|
return Some(CfgExpr::Invalid);
|
||||||
|
@ -285,10 +286,12 @@ where
|
||||||
preds.push(pred);
|
preds.push(pred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let group = match name.as_str() {
|
let group = match &name {
|
||||||
"all" => CfgExpr::All(preds),
|
s if *s == sym::all => CfgExpr::All(preds),
|
||||||
"any" => CfgExpr::Any(preds),
|
s if *s == sym::any => CfgExpr::Any(preds),
|
||||||
"not" => CfgExpr::Not(Box::new(preds.pop().unwrap_or(CfgExpr::Invalid))),
|
s if *s == sym::not => {
|
||||||
|
CfgExpr::Not(Box::new(preds.pop().unwrap_or(CfgExpr::Invalid)))
|
||||||
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
Some(group)
|
Some(group)
|
||||||
|
@ -301,13 +304,15 @@ where
|
||||||
if (value_token.kind() == syntax::SyntaxKind::STRING) =>
|
if (value_token.kind() == syntax::SyntaxKind::STRING) =>
|
||||||
{
|
{
|
||||||
let value = value_token.text();
|
let value = value_token.text();
|
||||||
let value = value.trim_matches('"').into();
|
Some(CfgExpr::Atom(CfgAtom::KeyValue {
|
||||||
Some(CfgExpr::Atom(CfgAtom::KeyValue { key: name.into(), value }))
|
key: name,
|
||||||
|
value: Symbol::intern(value.trim_matches('"')),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Some(CfgExpr::Atom(CfgAtom::Flag(name.into()))),
|
_ => Some(CfgExpr::Atom(CfgAtom::Flag(name))),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
if let Some(NodeOrToken::Token(element)) = iter.peek() {
|
if let Some(NodeOrToken::Token(element)) = iter.peek() {
|
||||||
|
|
|
@ -39,6 +39,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
|
||||||
"target_vendor" => KNOWN_VENDOR.iter().copied().for_each(add_completion),
|
"target_vendor" => KNOWN_VENDOR.iter().copied().for_each(add_completion),
|
||||||
"target_endian" => ["little", "big"].into_iter().for_each(add_completion),
|
"target_endian" => ["little", "big"].into_iter().for_each(add_completion),
|
||||||
name => ctx.krate.potential_cfg(ctx.db).get_cfg_values(name).cloned().for_each(|s| {
|
name => ctx.krate.potential_cfg(ctx.db).get_cfg_values(name).cloned().for_each(|s| {
|
||||||
|
let s = s.as_str();
|
||||||
let insert_text = format!(r#""{s}""#);
|
let insert_text = format!(r#""{s}""#);
|
||||||
let mut item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
|
let mut item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
|
||||||
item.insert_text(insert_text);
|
item.insert_text(insert_text);
|
||||||
|
@ -47,6 +48,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) {
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
None => ctx.krate.potential_cfg(ctx.db).get_cfg_keys().cloned().unique().for_each(|s| {
|
None => ctx.krate.potential_cfg(ctx.db).get_cfg_keys().cloned().unique().for_each(|s| {
|
||||||
|
let s = s.as_str();
|
||||||
let item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
|
let item = CompletionItem::new(SymbolKind::BuiltinAttr, ctx.source_range(), s);
|
||||||
acc.add(item.build(ctx.db));
|
acc.add(item.build(ctx.db));
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -62,7 +62,7 @@ use std::panic::UnwindSafe;
|
||||||
|
|
||||||
use cfg::CfgOptions;
|
use cfg::CfgOptions;
|
||||||
use fetch_crates::CrateInfo;
|
use fetch_crates::CrateInfo;
|
||||||
use hir::ChangeWithProcMacros;
|
use hir::{sym, ChangeWithProcMacros};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{
|
base_db::{
|
||||||
salsa::{self, ParallelDatabase},
|
salsa::{self, ParallelDatabase},
|
||||||
|
@ -248,7 +248,7 @@ impl Analysis {
|
||||||
// FIXME: cfg options
|
// FIXME: cfg options
|
||||||
// Default to enable test for single file.
|
// Default to enable test for single file.
|
||||||
let mut cfg_options = CfgOptions::default();
|
let mut cfg_options = CfgOptions::default();
|
||||||
cfg_options.insert_atom("test".into());
|
cfg_options.insert_atom(sym::test.clone());
|
||||||
crate_graph.add_crate_root(
|
crate_graph.add_crate_root(
|
||||||
file_id,
|
file_id,
|
||||||
Edition::CURRENT,
|
Edition::CURRENT,
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::fmt;
|
||||||
use ast::HasName;
|
use ast::HasName;
|
||||||
use cfg::{CfgAtom, CfgExpr};
|
use cfg::{CfgAtom, CfgExpr};
|
||||||
use hir::{
|
use hir::{
|
||||||
db::HirDatabase, AsAssocItem, AttrsWithOwner, HasAttrs, HasSource, HirFileIdExt, Semantics,
|
db::HirDatabase, sym, AsAssocItem, AttrsWithOwner, HasAttrs, HasSource, HirFileIdExt, Semantics,
|
||||||
};
|
};
|
||||||
use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn};
|
use ide_assists::utils::{has_test_related_attribute, test_related_attribute_syn};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
|
@ -403,7 +403,7 @@ pub(crate) fn runnable_impl(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_cfg_test(attrs: AttrsWithOwner) -> bool {
|
fn has_cfg_test(attrs: AttrsWithOwner) -> bool {
|
||||||
attrs.cfgs().any(|cfg| matches!(cfg, CfgExpr::Atom(CfgAtom::Flag(s)) if s == "test"))
|
attrs.cfgs().any(|cfg| matches!(&cfg, CfgExpr::Atom(CfgAtom::Flag(s)) if *s == sym::test))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a test mod runnable for outline modules at the top of their definition.
|
/// Creates a test mod runnable for outline modules at the top of their definition.
|
||||||
|
|
|
@ -139,11 +139,17 @@ impl TaggedArcPtr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Debug)]
|
#[derive(PartialEq, Eq, Hash)]
|
||||||
pub struct Symbol {
|
pub struct Symbol {
|
||||||
repr: TaggedArcPtr,
|
repr: TaggedArcPtr,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Symbol {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
self.as_str().fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const _: () = assert!(std::mem::size_of::<Symbol>() == std::mem::size_of::<NonNull<()>>());
|
const _: () = assert!(std::mem::size_of::<Symbol>() == std::mem::size_of::<NonNull<()>>());
|
||||||
const _: () = assert!(std::mem::align_of::<Symbol>() == std::mem::align_of::<NonNull<()>>());
|
const _: () = assert!(std::mem::align_of::<Symbol>() == std::mem::align_of::<NonNull<()>>());
|
||||||
|
|
||||||
|
|
|
@ -93,20 +93,20 @@ define_symbols! {
|
||||||
__ra_fixup,
|
__ra_fixup,
|
||||||
add_assign,
|
add_assign,
|
||||||
add,
|
add,
|
||||||
attributes,
|
|
||||||
align_offset,
|
align_offset,
|
||||||
|
align,
|
||||||
|
all,
|
||||||
alloc_layout,
|
alloc_layout,
|
||||||
alloc,
|
alloc,
|
||||||
|
any,
|
||||||
as_str,
|
as_str,
|
||||||
asm,
|
asm,
|
||||||
assert,
|
assert,
|
||||||
|
attributes,
|
||||||
begin_panic,
|
begin_panic,
|
||||||
bench,
|
bench,
|
||||||
bitand_assign,
|
bitand_assign,
|
||||||
bitand,
|
bitand,
|
||||||
notable_trait,
|
|
||||||
hidden,
|
|
||||||
local_inner_macros,
|
|
||||||
bitor_assign,
|
bitor_assign,
|
||||||
bitor,
|
bitor,
|
||||||
bitxor_assign,
|
bitxor_assign,
|
||||||
|
@ -118,6 +118,7 @@ define_symbols! {
|
||||||
branch,
|
branch,
|
||||||
Break,
|
Break,
|
||||||
c_void,
|
c_void,
|
||||||
|
C,
|
||||||
call_mut,
|
call_mut,
|
||||||
call_once,
|
call_once,
|
||||||
call,
|
call,
|
||||||
|
@ -146,8 +147,10 @@ define_symbols! {
|
||||||
core,
|
core,
|
||||||
coroutine_state,
|
coroutine_state,
|
||||||
coroutine,
|
coroutine,
|
||||||
|
count,
|
||||||
crate_type,
|
crate_type,
|
||||||
CStr,
|
CStr,
|
||||||
|
debug_assertions,
|
||||||
Debug,
|
Debug,
|
||||||
default,
|
default,
|
||||||
Default,
|
Default,
|
||||||
|
@ -172,6 +175,7 @@ define_symbols! {
|
||||||
Eq,
|
Eq,
|
||||||
Err,
|
Err,
|
||||||
exchange_malloc,
|
exchange_malloc,
|
||||||
|
exhaustive_patterns,
|
||||||
f128,
|
f128,
|
||||||
f16,
|
f16,
|
||||||
f32,
|
f32,
|
||||||
|
@ -208,11 +212,13 @@ define_symbols! {
|
||||||
global_asm,
|
global_asm,
|
||||||
gt,
|
gt,
|
||||||
Hash,
|
Hash,
|
||||||
|
hidden,
|
||||||
i128,
|
i128,
|
||||||
i16,
|
i16,
|
||||||
i32,
|
i32,
|
||||||
i64,
|
i64,
|
||||||
i8,
|
i8,
|
||||||
|
ignore,
|
||||||
Implied,
|
Implied,
|
||||||
include_bytes,
|
include_bytes,
|
||||||
include_str,
|
include_str,
|
||||||
|
@ -237,14 +243,15 @@ define_symbols! {
|
||||||
len,
|
len,
|
||||||
line,
|
line,
|
||||||
llvm_asm,
|
llvm_asm,
|
||||||
|
local_inner_macros,
|
||||||
log_syntax,
|
log_syntax,
|
||||||
lt,
|
lt,
|
||||||
macro_rules,
|
macro_rules,
|
||||||
ignore,
|
|
||||||
count,
|
|
||||||
manually_drop,
|
manually_drop,
|
||||||
maybe_uninit,
|
maybe_uninit,
|
||||||
metadata_type,
|
metadata_type,
|
||||||
|
min_exhaustive_patterns,
|
||||||
|
miri,
|
||||||
missing,
|
missing,
|
||||||
module_path,
|
module_path,
|
||||||
mul_assign,
|
mul_assign,
|
||||||
|
@ -271,6 +278,7 @@ define_symbols! {
|
||||||
None,
|
None,
|
||||||
not,
|
not,
|
||||||
Not,
|
Not,
|
||||||
|
notable_trait,
|
||||||
Ok,
|
Ok,
|
||||||
opaque,
|
opaque,
|
||||||
ops,
|
ops,
|
||||||
|
@ -280,6 +288,7 @@ define_symbols! {
|
||||||
Ord,
|
Ord,
|
||||||
Output,
|
Output,
|
||||||
owned_box,
|
owned_box,
|
||||||
|
packed,
|
||||||
panic_2015,
|
panic_2015,
|
||||||
panic_2021,
|
panic_2021,
|
||||||
panic_bounds_check,
|
panic_bounds_check,
|
||||||
|
@ -328,6 +337,7 @@ define_symbols! {
|
||||||
rust_2018,
|
rust_2018,
|
||||||
rust_2021,
|
rust_2021,
|
||||||
rust_2024,
|
rust_2024,
|
||||||
|
rust_analyzer,
|
||||||
rustc_coherence_is_core,
|
rustc_coherence_is_core,
|
||||||
rustc_macro_transparency,
|
rustc_macro_transparency,
|
||||||
semitransparent,
|
semitransparent,
|
||||||
|
@ -335,6 +345,7 @@ define_symbols! {
|
||||||
shl,
|
shl,
|
||||||
shr_assign,
|
shr_assign,
|
||||||
shr,
|
shr,
|
||||||
|
simd,
|
||||||
sized,
|
sized,
|
||||||
slice_len_fn,
|
slice_len_fn,
|
||||||
Some,
|
Some,
|
||||||
|
@ -367,10 +378,6 @@ define_symbols! {
|
||||||
u8,
|
u8,
|
||||||
Unknown,
|
Unknown,
|
||||||
unpin,
|
unpin,
|
||||||
simd,
|
|
||||||
C,
|
|
||||||
align,
|
|
||||||
packed,
|
|
||||||
unreachable_2015,
|
unreachable_2015,
|
||||||
unreachable_2021,
|
unreachable_2021,
|
||||||
unreachable,
|
unreachable,
|
||||||
|
@ -378,7 +385,5 @@ define_symbols! {
|
||||||
unsize,
|
unsize,
|
||||||
usize,
|
usize,
|
||||||
v1,
|
v1,
|
||||||
exhaustive_patterns,
|
|
||||||
min_exhaustive_patterns,
|
|
||||||
va_list
|
va_list
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ itertools.workspace = true
|
||||||
|
|
||||||
# local deps
|
# local deps
|
||||||
base-db.workspace = true
|
base-db.workspace = true
|
||||||
|
intern.workspace = true
|
||||||
span.workspace = true
|
span.workspace = true
|
||||||
cfg.workspace = true
|
cfg.workspace = true
|
||||||
paths = { workspace = true, features = ["serde1"] }
|
paths = { workspace = true, features = ["serde1"] }
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
use std::{fmt, str::FromStr};
|
use std::{fmt, str::FromStr};
|
||||||
|
|
||||||
use cfg::{CfgDiff, CfgOptions};
|
use cfg::{CfgDiff, CfgOptions};
|
||||||
|
use intern::Symbol;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -44,8 +45,10 @@ impl Extend<CfgFlag> for CfgOptions {
|
||||||
fn extend<T: IntoIterator<Item = CfgFlag>>(&mut self, iter: T) {
|
fn extend<T: IntoIterator<Item = CfgFlag>>(&mut self, iter: T) {
|
||||||
for cfg_flag in iter {
|
for cfg_flag in iter {
|
||||||
match cfg_flag {
|
match cfg_flag {
|
||||||
CfgFlag::Atom(it) => self.insert_atom(it.into()),
|
CfgFlag::Atom(it) => self.insert_atom(Symbol::intern(&it)),
|
||||||
CfgFlag::KeyValue { key, value } => self.insert_key_value(key.into(), value.into()),
|
CfgFlag::KeyValue { key, value } => {
|
||||||
|
self.insert_key_value(Symbol::intern(&key), Symbol::intern(&value))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ use base_db::{CrateGraph, FileId, ProcMacroPaths};
|
||||||
use cargo_metadata::Metadata;
|
use cargo_metadata::Metadata;
|
||||||
use cfg::{CfgAtom, CfgDiff};
|
use cfg::{CfgAtom, CfgDiff};
|
||||||
use expect_test::{expect_file, ExpectFile};
|
use expect_test::{expect_file, ExpectFile};
|
||||||
|
use intern::sym;
|
||||||
use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf};
|
use paths::{AbsPath, AbsPathBuf, Utf8Path, Utf8PathBuf};
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
use serde::de::DeserializeOwned;
|
use serde::de::DeserializeOwned;
|
||||||
|
@ -180,7 +181,7 @@ fn check_crate_graph(crate_graph: CrateGraph, expect: ExpectFile) {
|
||||||
#[test]
|
#[test]
|
||||||
fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
fn cargo_hello_world_project_model_with_wildcard_overrides() {
|
||||||
let cfg_overrides = CfgOverrides {
|
let cfg_overrides = CfgOverrides {
|
||||||
global: CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(),
|
global: CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]).unwrap(),
|
||||||
selective: Default::default(),
|
selective: Default::default(),
|
||||||
};
|
};
|
||||||
let (crate_graph, _proc_macros) =
|
let (crate_graph, _proc_macros) =
|
||||||
|
@ -199,7 +200,7 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
|
||||||
global: Default::default(),
|
global: Default::default(),
|
||||||
selective: std::iter::once((
|
selective: std::iter::once((
|
||||||
"libc".to_owned(),
|
"libc".to_owned(),
|
||||||
CfgDiff::new(Vec::new(), vec![CfgAtom::Flag("test".into())]).unwrap(),
|
CfgDiff::new(Vec::new(), vec![CfgAtom::Flag(sym::test.clone())]).unwrap(),
|
||||||
))
|
))
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@ use base_db::{
|
||||||
LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult,
|
LangCrateOrigin, ProcMacroPaths, TargetLayoutLoadResult,
|
||||||
};
|
};
|
||||||
use cfg::{CfgAtom, CfgDiff, CfgOptions};
|
use cfg::{CfgAtom, CfgDiff, CfgOptions};
|
||||||
|
use intern::{sym, Symbol};
|
||||||
use paths::{AbsPath, AbsPathBuf};
|
use paths::{AbsPath, AbsPathBuf};
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use semver::Version;
|
use semver::Version;
|
||||||
|
@ -977,8 +978,8 @@ fn cargo_to_crate_graph(
|
||||||
|
|
||||||
if cargo[pkg].is_local {
|
if cargo[pkg].is_local {
|
||||||
// Add test cfg for local crates
|
// Add test cfg for local crates
|
||||||
cfg_options.insert_atom("test".into());
|
cfg_options.insert_atom(sym::test.clone());
|
||||||
cfg_options.insert_atom("rust_analyzer".into());
|
cfg_options.insert_atom(sym::rust_analyzer.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
override_cfg.apply(&mut cfg_options, &cargo[pkg].name);
|
override_cfg.apply(&mut cfg_options, &cargo[pkg].name);
|
||||||
|
@ -1144,8 +1145,8 @@ fn detached_file_to_crate_graph(
|
||||||
sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load);
|
sysroot_to_crate_graph(&mut crate_graph, sysroot, rustc_cfg.clone(), load);
|
||||||
|
|
||||||
let mut cfg_options = CfgOptions::from_iter(rustc_cfg);
|
let mut cfg_options = CfgOptions::from_iter(rustc_cfg);
|
||||||
cfg_options.insert_atom("test".into());
|
cfg_options.insert_atom(sym::test.clone());
|
||||||
cfg_options.insert_atom("rust_analyzer".into());
|
cfg_options.insert_atom(sym::rust_analyzer.clone());
|
||||||
override_cfg.apply(&mut cfg_options, "");
|
override_cfg.apply(&mut cfg_options, "");
|
||||||
let cfg_options = Arc::new(cfg_options);
|
let cfg_options = Arc::new(cfg_options);
|
||||||
|
|
||||||
|
@ -1307,7 +1308,7 @@ fn add_target_crate_root(
|
||||||
let cfg_options = {
|
let cfg_options = {
|
||||||
let mut opts = cfg_options;
|
let mut opts = cfg_options;
|
||||||
for feature in pkg.active_features.iter() {
|
for feature in pkg.active_features.iter() {
|
||||||
opts.insert_key_value("feature".into(), feature.into());
|
opts.insert_key_value(sym::feature.clone(), Symbol::intern(feature));
|
||||||
}
|
}
|
||||||
if let Some(cfgs) = build_data.as_ref().map(|it| &it.cfgs) {
|
if let Some(cfgs) = build_data.as_ref().map(|it| &it.cfgs) {
|
||||||
opts.extend(cfgs.iter().cloned());
|
opts.extend(cfgs.iter().cloned());
|
||||||
|
@ -1381,8 +1382,8 @@ fn sysroot_to_crate_graph(
|
||||||
&CfgOverrides {
|
&CfgOverrides {
|
||||||
global: CfgDiff::new(
|
global: CfgDiff::new(
|
||||||
vec![
|
vec![
|
||||||
CfgAtom::Flag("debug_assertions".into()),
|
CfgAtom::Flag(sym::debug_assertions.clone()),
|
||||||
CfgAtom::Flag("miri".into()),
|
CfgAtom::Flag(sym::miri.clone()),
|
||||||
],
|
],
|
||||||
vec![],
|
vec![],
|
||||||
)
|
)
|
||||||
|
@ -1394,7 +1395,7 @@ fn sysroot_to_crate_graph(
|
||||||
|
|
||||||
let mut pub_deps = vec![];
|
let mut pub_deps = vec![];
|
||||||
let mut libproc_macro = None;
|
let mut libproc_macro = None;
|
||||||
let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag("test".into())]).unwrap();
|
let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap();
|
||||||
for (cid, c) in cg.iter_mut() {
|
for (cid, c) in cg.iter_mut() {
|
||||||
// uninject `test` flag so `core` keeps working.
|
// uninject `test` flag so `core` keeps working.
|
||||||
Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone());
|
Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone());
|
||||||
|
@ -1449,8 +1450,8 @@ fn sysroot_to_crate_graph(
|
||||||
let cfg_options = Arc::new({
|
let cfg_options = Arc::new({
|
||||||
let mut cfg_options = CfgOptions::default();
|
let mut cfg_options = CfgOptions::default();
|
||||||
cfg_options.extend(rustc_cfg);
|
cfg_options.extend(rustc_cfg);
|
||||||
cfg_options.insert_atom("debug_assertions".into());
|
cfg_options.insert_atom(sym::debug_assertions.clone());
|
||||||
cfg_options.insert_atom("miri".into());
|
cfg_options.insert_atom(sym::miri.clone());
|
||||||
cfg_options
|
cfg_options
|
||||||
});
|
});
|
||||||
let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = stitched
|
let sysroot_crates: FxHashMap<SysrootCrate, CrateId> = stitched
|
||||||
|
|
|
@ -54,6 +54,7 @@ hir-def.workspace = true
|
||||||
hir-ty.workspace = true
|
hir-ty.workspace = true
|
||||||
hir.workspace = true
|
hir.workspace = true
|
||||||
ide-db.workspace = true
|
ide-db.workspace = true
|
||||||
|
intern.workspace = true
|
||||||
# This should only be used in CLI
|
# This should only be used in CLI
|
||||||
ide-ssr.workspace = true
|
ide-ssr.workspace = true
|
||||||
ide.workspace = true
|
ide.workspace = true
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::{fmt, iter, ops::Not, sync::OnceLock};
|
||||||
use cfg::{CfgAtom, CfgDiff};
|
use cfg::{CfgAtom, CfgDiff};
|
||||||
use dirs::config_dir;
|
use dirs::config_dir;
|
||||||
use flycheck::{CargoOptions, FlycheckConfig};
|
use flycheck::{CargoOptions, FlycheckConfig};
|
||||||
|
use hir::Symbol;
|
||||||
use ide::{
|
use ide::{
|
||||||
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
|
AssistConfig, CallableSnippets, CompletionConfig, DiagnosticsConfig, ExprFillDefaultMode,
|
||||||
GenericParameterHints, HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat,
|
GenericParameterHints, HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat,
|
||||||
|
@ -1691,8 +1692,11 @@ impl Config {
|
||||||
self.cargo_cfgs()
|
self.cargo_cfgs()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(key, val)| match val {
|
.map(|(key, val)| match val {
|
||||||
Some(val) => CfgAtom::KeyValue { key: key.into(), value: val.into() },
|
Some(val) => CfgAtom::KeyValue {
|
||||||
None => CfgAtom::Flag(key.into()),
|
key: Symbol::intern(key),
|
||||||
|
value: Symbol::intern(val),
|
||||||
|
},
|
||||||
|
None => CfgAtom::Flag(Symbol::intern(key)),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
vec![],
|
vec![],
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use cfg::{CfgAtom, CfgExpr};
|
use cfg::{CfgAtom, CfgExpr};
|
||||||
|
use hir::sym;
|
||||||
use ide::{Cancellable, CrateId, FileId, RunnableKind, TestId};
|
use ide::{Cancellable, CrateId, FileId, RunnableKind, TestId};
|
||||||
use project_model::project_json::Runnable;
|
use project_model::project_json::Runnable;
|
||||||
use project_model::{CargoFeatures, ManifestPath, TargetKind};
|
use project_model::{CargoFeatures, ManifestPath, TargetKind};
|
||||||
|
@ -237,7 +238,7 @@ impl CargoTargetSpec {
|
||||||
/// Fill minimal features needed
|
/// Fill minimal features needed
|
||||||
fn required_features(cfg_expr: &CfgExpr, features: &mut Vec<String>) {
|
fn required_features(cfg_expr: &CfgExpr, features: &mut Vec<String>) {
|
||||||
match cfg_expr {
|
match cfg_expr {
|
||||||
CfgExpr::Atom(CfgAtom::KeyValue { key, value }) if key == "feature" => {
|
CfgExpr::Atom(CfgAtom::KeyValue { key, value }) if *key == sym::feature => {
|
||||||
features.push(value.to_string())
|
features.push(value.to_string())
|
||||||
}
|
}
|
||||||
CfgExpr::All(preds) => {
|
CfgExpr::All(preds) => {
|
||||||
|
|
|
@ -481,9 +481,9 @@ impl FileMeta {
|
||||||
let mut cfg = CfgOptions::default();
|
let mut cfg = CfgOptions::default();
|
||||||
for (k, v) in f.cfgs {
|
for (k, v) in f.cfgs {
|
||||||
if let Some(v) = v {
|
if let Some(v) = v {
|
||||||
cfg.insert_key_value(k.into(), v.into());
|
cfg.insert_key_value(Symbol::intern(&k), Symbol::intern(&v));
|
||||||
} else {
|
} else {
|
||||||
cfg.insert_atom(k.into());
|
cfg.insert_atom(Symbol::intern(&k));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue