From c6748782afce501b8f3a8ba1c83165ebf1320f91 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 13 Jul 2026 16:10:59 +1000 Subject: [PATCH 1/2] Add a case to the `multiple-tail-expr-behind-cfg.rs` test This demonstrates the `if cfg!(..)` suggestion being applied wrongly, when a `cfg` attribute is followed by a non-`cfg` attribute. --- .../multiple-tail-expr-behind-cfg.rs | 7 +++++ .../multiple-tail-expr-behind-cfg.stderr | 29 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.rs b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.rs index 371f19d487268..fcf0dcf478444 100644 --- a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.rs +++ b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.rs @@ -14,6 +14,13 @@ fn bar() -> String { String::new() } +fn baz() -> String { + #[cfg(false)] + [1, 2, 3].iter().map(|c| c.to_string()).collect::() //~ ERROR expected `;`, found `#` + #[allow(unused)] + String::new() +} + fn main() { println!("{}", foo()); } diff --git a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr index 3a97a14b3c301..f5bbb78882687 100644 --- a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr +++ b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr @@ -44,11 +44,38 @@ help: alternatively, consider surrounding the expression with a block LL | { [1, 2, 3].iter().map(|c| c.to_string()).collect::() } | + + +error: expected `;`, found `#` + --> $DIR/multiple-tail-expr-behind-cfg.rs:19:64 + | +LL | #[cfg(false)] + | ------------- only `;` terminated statements or tail expressions are allowed after this attribute +LL | [1, 2, 3].iter().map(|c| c.to_string()).collect::() + | ^ expected `;` here +LL | #[allow(unused)] + | - unexpected token + | +help: add `;` here + | +LL | [1, 2, 3].iter().map(|c| c.to_string()).collect::(); + | + +help: alternatively, consider surrounding the expression with a block + | +LL | { [1, 2, 3].iter().map(|c| c.to_string()).collect::() } + | + + +help: it seems like you are trying to provide different expressions depending on `cfg`, consider using `if cfg!(..)` + | +LL ~ if cfg!(false) { +LL ~ [1, 2, 3].iter().map(|c| c.to_string()).collect::() +LL ~ } else if cfg!(unused) { +LL ~ String::new() +LL + } + | + error: cannot find attribute `attr` in this scope --> $DIR/multiple-tail-expr-behind-cfg.rs:13:7 | LL | #[attr] | ^^^^ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors From 895538515599db58b843620d251d5b977d09dcc9 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Mon, 13 Jul 2026 15:55:44 +1000 Subject: [PATCH 2/2] Fix typo in `attr_on_non_tail_expr` The line `&& segment.ident.name == sym::cfg` duplicates a line from just a few lines above in the same if-let chain. It's clear from context that the `segment` is a copy/paste error and should be `next_segment`. This fixes the erroneous suggestion given for `multiple-tail-expr-behind-cfg.rs`. --- compiler/rustc_parse/src/parser/diagnostics.rs | 2 +- .../parser/attribute/multiple-tail-expr-behind-cfg.stderr | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 254e7e410f579..a4f0f5610081d 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -873,7 +873,7 @@ impl<'a> Parser<'a> { && let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind && let Some(next_attr_args_span) = next_attr_kind.item.args.span() && let [next_segment] = &next_attr_kind.item.path.segments[..] - && segment.ident.name == sym::cfg + && next_segment.ident.name == sym::cfg { let next_expr = match snapshot.parse_expr() { Ok(next_expr) => next_expr, diff --git a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr index f5bbb78882687..c8f3d50edd103 100644 --- a/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr +++ b/tests/ui/parser/attribute/multiple-tail-expr-behind-cfg.stderr @@ -62,14 +62,6 @@ help: alternatively, consider surrounding the expression with a block | LL | { [1, 2, 3].iter().map(|c| c.to_string()).collect::() } | + + -help: it seems like you are trying to provide different expressions depending on `cfg`, consider using `if cfg!(..)` - | -LL ~ if cfg!(false) { -LL ~ [1, 2, 3].iter().map(|c| c.to_string()).collect::() -LL ~ } else if cfg!(unused) { -LL ~ String::new() -LL + } - | error: cannot find attribute `attr` in this scope --> $DIR/multiple-tail-expr-behind-cfg.rs:13:7