fix: cfg_select supports non token-tree tokens

- Fix single non-curly groups is ignored `true => ((),)`, old: `(),`, new: `((),)`

Example
---
```rust
const _: i32 = cfg_select! { true => 2 + 3, _ => 3 + 4 };
```

**Before this PR**

```rust
const _: i32 = cfg_select! { true => 2 /* expected a token tree after `=>` */+ 3, _ => 3 + 4 };
```

**After this PR**

```rust
const _: i32 = 2 + 3;
```
This commit is contained in:
A4-Tacks
2026-02-24 18:29:05 +08:00
parent 0dc6097727
commit c47f4e036a
2 changed files with 39 additions and 3 deletions

View File

@@ -568,6 +568,12 @@ cfg_select! {
_ => { fn true_2() {} }
}
const _: ((),) = cfg_select! { _ => ((), ) };
const _: i32 = cfg_select! { true => 2 + 3, _ => 3 + 4 };
const _: i32 = cfg_select! { false => 2 + 3, _ => 3 + 4 };
const _: bool = cfg_select! { _ => 2 < 3 };
const _: bool = cfg_select! { true => foo::<(), fn() -> Foo<i32, i64>>(1,), _ => false };
cfg_select! {
false => { fn false_3() {} }
}
@@ -589,6 +595,12 @@ fn true_1() {}
fn true_2() {}
const _: ((),) = ((), );
const _: i32 = 2+3;
const _: i32 = 3+4;
const _: bool = 2<3;
const _: bool = foo::<(), fn() -> Foo<i32, i64>>(1, );
/* error: none of the predicates in this `cfg_select` evaluated to true */
/* error: expected `=>` after cfg expression */

View File

@@ -381,16 +381,40 @@ fn cfg_select_expand(
);
}
}
let expand_to_if_active = match iter.next() {
Some(tt::TtElement::Subtree(_, tt)) => tt.remaining(),
_ => {
let expand_to_if_active = match iter.peek() {
Some(tt::TtElement::Subtree(sub, tt)) if sub.delimiter.kind == DelimiterKind::Brace => {
iter.next();
tt.remaining()
}
None | Some(TtElement::Leaf(tt::Leaf::Punct(tt::Punct { char: ',', .. }))) => {
let err_span = iter.peek().map(|it| it.first_span()).unwrap_or(span);
iter.next();
return ExpandResult::new(
tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
ExpandError::other(err_span, "expected a token tree after `=>`"),
);
}
Some(_) => {
let expr = expect_fragment(
db,
&mut iter,
parser::PrefixEntryPoint::Expr,
tt.top_subtree().delimiter.delim_span(),
);
if let Some(err) = expr.err {
return ExpandResult::new(
tt::TopSubtree::empty(tt::DelimSpan::from_single(span)),
err.into(),
);
}
expr.value
}
};
if let Some(TtElement::Leaf(tt::Leaf::Punct(p))) = iter.peek()
&& p.char == ','
{
iter.next();
}
if expand_to.is_none() && active {
expand_to = Some(expand_to_if_active);