Skip to content

Commit 447de3d

Browse files
committed
Review Updates and added tests.
1 parent 0fb5d0d commit 447de3d

File tree

6 files changed

+274
-126
lines changed

6 files changed

+274
-126
lines changed

crates/cfg/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ rustc-hash.workspace = true
1616

1717
# locals deps
1818
tt.workspace = true
19-
syntax.workspace = true
2019

2120
[dev-dependencies]
2221
expect-test = "1.4.1"
@@ -29,6 +28,7 @@ derive_arbitrary = "1.3.2"
2928

3029
# local deps
3130
mbe.workspace = true
31+
syntax.workspace = true
3232

3333
[lints]
3434
workspace = true

crates/cfg/src/cfg_expr.rs

+2-75
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,8 @@
22
//!
33
//! See: <https://doc.rust-lang.org/reference/conditional-compilation.html#conditional-compilation>
44
5-
use std::{fmt, iter::Peekable, slice::Iter as SliceIter};
5+
use std::{fmt, slice::Iter as SliceIter};
66

7-
use syntax::{
8-
ast::{self, Meta},
9-
NodeOrToken,
10-
};
117
use tt::SmolStr;
128

139
/// A simple configuration value passed in from the outside.
@@ -51,12 +47,7 @@ impl CfgExpr {
5147
pub fn parse<S>(tt: &tt::Subtree<S>) -> CfgExpr {
5248
next_cfg_expr(&mut tt.token_trees.iter()).unwrap_or(CfgExpr::Invalid)
5349
}
54-
/// Parses a `cfg` attribute from the meta
55-
pub fn parse_from_attr_meta(meta: Meta) -> Option<CfgExpr> {
56-
let tt = meta.token_tree()?;
57-
let mut iter = tt.token_trees_and_tokens().skip(1).peekable();
58-
next_cfg_expr_from_syntax(&mut iter)
59-
}
50+
6051
/// Fold the cfg by querying all basic `Atom` and `KeyValue` predicates.
6152
pub fn fold(&self, query: &dyn Fn(&CfgAtom) -> bool) -> Option<bool> {
6253
match self {
@@ -72,70 +63,6 @@ impl CfgExpr {
7263
}
7364
}
7465
}
75-
fn next_cfg_expr_from_syntax<I>(iter: &mut Peekable<I>) -> Option<CfgExpr>
76-
where
77-
I: Iterator<Item = NodeOrToken<ast::TokenTree, syntax::SyntaxToken>>,
78-
{
79-
let name = match iter.next() {
80-
None => return None,
81-
Some(NodeOrToken::Token(element)) => match element.kind() {
82-
syntax::T![ident] => SmolStr::new(element.text()),
83-
_ => return Some(CfgExpr::Invalid),
84-
},
85-
Some(_) => return Some(CfgExpr::Invalid),
86-
};
87-
let result = match name.as_str() {
88-
"all" | "any" | "not" => {
89-
let mut preds = Vec::new();
90-
let Some(NodeOrToken::Node(tree)) = iter.next() else {
91-
return Some(CfgExpr::Invalid);
92-
};
93-
let mut tree_iter = tree.token_trees_and_tokens().skip(1).peekable();
94-
while tree_iter
95-
.peek()
96-
.filter(
97-
|element| matches!(element, NodeOrToken::Token(token) if (token.kind() != syntax::T![')'])),
98-
)
99-
.is_some()
100-
{
101-
let pred = next_cfg_expr_from_syntax(&mut tree_iter);
102-
if let Some(pred) = pred {
103-
preds.push(pred);
104-
}
105-
}
106-
let group = match name.as_str() {
107-
"all" => CfgExpr::All(preds),
108-
"any" => CfgExpr::Any(preds),
109-
"not" => CfgExpr::Not(Box::new(preds.pop().unwrap_or(CfgExpr::Invalid))),
110-
_ => unreachable!(),
111-
};
112-
Some(group)
113-
}
114-
_ => match iter.peek() {
115-
Some(NodeOrToken::Token(element)) if (element.kind() == syntax::T![=]) => {
116-
iter.next();
117-
match iter.next() {
118-
Some(NodeOrToken::Token(value_token))
119-
if (value_token.kind() == syntax::SyntaxKind::STRING) =>
120-
{
121-
let value = value_token.text();
122-
let value = SmolStr::new(value.trim_matches('"'));
123-
Some(CfgExpr::Atom(CfgAtom::KeyValue { key: name, value }))
124-
}
125-
_ => None,
126-
}
127-
}
128-
_ => Some(CfgExpr::Atom(CfgAtom::Flag(name))),
129-
},
130-
};
131-
if let Some(NodeOrToken::Token(element)) = iter.peek() {
132-
if element.kind() == syntax::T![,] {
133-
iter.next();
134-
}
135-
}
136-
result
137-
}
138-
13966
fn next_cfg_expr<S>(it: &mut SliceIter<'_, tt::TokenTree<S>>) -> Option<CfgExpr> {
14067
let name = match it.next() {
14168
None => return None,

crates/cfg/src/tests.rs

+1-25
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
use arbitrary::{Arbitrary, Unstructured};
22
use expect_test::{expect, Expect};
33
use mbe::{syntax_node_to_token_tree, DummyTestSpanMap, DUMMY};
4-
use syntax::{
5-
ast::{self, Attr},
6-
AstNode, SourceFile,
7-
};
4+
use syntax::{ast, AstNode};
85

96
use crate::{CfgAtom, CfgExpr, CfgOptions, DnfExpr};
107

@@ -15,22 +12,6 @@ fn assert_parse_result(input: &str, expected: CfgExpr) {
1512
let cfg = CfgExpr::parse(&tt);
1613
assert_eq!(cfg, expected);
1714
}
18-
fn check_dnf_from_syntax(input: &str, expect: Expect) {
19-
let parse = SourceFile::parse(input);
20-
let node = match parse.tree().syntax().descendants().find_map(Attr::cast) {
21-
Some(it) => it,
22-
None => {
23-
let node = std::any::type_name::<Attr>();
24-
panic!("Failed to make ast node `{node}` from text {input}")
25-
}
26-
};
27-
let node = node.clone_subtree();
28-
assert_eq!(node.syntax().text_range().start(), 0.into());
29-
30-
let cfg = CfgExpr::parse_from_attr_meta(node.meta().unwrap()).unwrap();
31-
let actual = format!("#![cfg({})]", DnfExpr::new(cfg));
32-
expect.assert_eq(&actual);
33-
}
3415

3516
fn check_dnf(input: &str, expect: Expect) {
3617
let source_file = ast::SourceFile::parse(input).ok().unwrap();
@@ -105,11 +86,6 @@ fn smoke() {
10586

10687
check_dnf("#![cfg(not(a))]", expect![[r#"#![cfg(not(a))]"#]]);
10788
}
108-
#[test]
109-
fn cfg_from_attr() {
110-
check_dnf_from_syntax(r#"#[cfg(test)]"#, expect![[r#"#![cfg(test)]"#]]);
111-
check_dnf_from_syntax(r#"#[cfg(not(never))]"#, expect![[r#"#![cfg(not(never))]"#]]);
112-
}
11389

11490
#[test]
11591
fn distribute() {

crates/hir-def/src/macro_expansion_tests/builtin_derive_macro.rs

+118
Original file line numberDiff line numberDiff line change
@@ -528,3 +528,121 @@ impl < > $crate::fmt::Debug for Command< > where {
528528
}"#]],
529529
);
530530
}
531+
#[test]
532+
fn test_debug_expand_with_cfg() {
533+
check(
534+
r#"
535+
//- minicore: derive, fmt
536+
use core::fmt::Debug;
537+
538+
#[derive(Debug)]
539+
struct HideAndShow {
540+
#[cfg(never)]
541+
always_hide: u32,
542+
#[cfg(not(never))]
543+
always_show: u32,
544+
}
545+
#[derive(Debug)]
546+
enum HideAndShowEnum {
547+
#[cfg(never)]
548+
AlwaysHide,
549+
#[cfg(not(never))]
550+
AlwaysShow{
551+
#[cfg(never)]
552+
always_hide: u32,
553+
#[cfg(not(never))]
554+
always_show: u32,
555+
}
556+
}
557+
"#,
558+
expect![[r#"
559+
use core::fmt::Debug;
560+
561+
#[derive(Debug)]
562+
struct HideAndShow {
563+
#[cfg(never)]
564+
always_hide: u32,
565+
#[cfg(not(never))]
566+
always_show: u32,
567+
}
568+
#[derive(Debug)]
569+
enum HideAndShowEnum {
570+
#[cfg(never)]
571+
AlwaysHide,
572+
#[cfg(not(never))]
573+
AlwaysShow{
574+
#[cfg(never)]
575+
always_hide: u32,
576+
#[cfg(not(never))]
577+
always_show: u32,
578+
}
579+
}
580+
581+
impl < > $crate::fmt::Debug for HideAndShow< > where {
582+
fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
583+
match self {
584+
HideAndShow {
585+
always_show: always_show,
586+
}
587+
=>f.debug_struct("HideAndShow").field("always_show", &always_show).finish()
588+
}
589+
}
590+
}
591+
impl < > $crate::fmt::Debug for HideAndShowEnum< > where {
592+
fn fmt(&self , f: &mut $crate::fmt::Formatter) -> $crate::fmt::Result {
593+
match self {
594+
HideAndShowEnum::AlwaysShow {
595+
always_show: always_show,
596+
}
597+
=>f.debug_struct("AlwaysShow").field("always_show", &always_show).finish(),
598+
}
599+
}
600+
}"#]],
601+
);
602+
}
603+
#[test]
604+
fn test_default_expand_with_cfg() {
605+
check(
606+
r#"
607+
//- minicore: derive, default
608+
#[derive(Default)]
609+
struct Foo {
610+
field1: i32,
611+
#[cfg(never)]
612+
field2: (),
613+
}
614+
#[derive(Default)]
615+
enum Bar {
616+
Foo,
617+
#[cfg_attr(not(never), default)]
618+
Bar,
619+
}
620+
"#,
621+
expect![[r#"
622+
#[derive(Default)]
623+
struct Foo {
624+
field1: i32,
625+
#[cfg(never)]
626+
field2: (),
627+
}
628+
#[derive(Default)]
629+
enum Bar {
630+
Foo,
631+
#[cfg_attr(not(never), default)]
632+
Bar,
633+
}
634+
635+
impl < > $crate::default::Default for Foo< > where {
636+
fn default() -> Self {
637+
Foo {
638+
field1: $crate::default::Default::default(),
639+
}
640+
}
641+
}
642+
impl < > $crate::default::Default for Bar< > where {
643+
fn default() -> Self {
644+
Bar::Bar
645+
}
646+
}"#]],
647+
);
648+
}

0 commit comments

Comments
 (0)