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>(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>(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);