Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21705 from A4-Tacks/cfg-select-fallback
fix: cfg_select supports non token-tree tokens
Chayim Refael Friedman 7 weeks ago
parent 0dc6097 · parent c47f4e0 · commit 23cc64a
-rw-r--r--crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs12
-rw-r--r--crates/hir-expand/src/builtin/fn_macro.rs30
2 files changed, 39 insertions, 3 deletions
diff --git a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
index eeaf865338..46cdb39c5b 100644
--- a/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
+++ b/crates/hir-def/src/macro_expansion_tests/builtin_fn_macro.rs
@@ -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 */
diff --git a/crates/hir-expand/src/builtin/fn_macro.rs b/crates/hir-expand/src/builtin/fn_macro.rs
index 949b22b0ad..2de7290a21 100644
--- a/crates/hir-expand/src/builtin/fn_macro.rs
+++ b/crates/hir-expand/src/builtin/fn_macro.rs
@@ -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);