Skip to content

[ICE]: bad span: ): ; cfg_select! invalid arm expr "successfully" formats but produces an ICE report #7087

Description

@matthiaskrgr

Code

#![crate_type = "lib"]

    cfg_select! {
        true => {
            fn foo{
    a() => {}
} {}
        }


}

Meta

rustfmt --version:

rustfmt 1.10.0-nightly (fd7ed57dfd 2026-08-29)

Error output

Diff in /tmp/im/a.rs:1:
 #![crate_type = "lib"]

-    cfg_select! {
+cfg_select! {
         true => {
             fn foo{
     a() => {}
Backtrace

thread 'main' (652005) panicked at src/tools/rustfmt/src/source_map.rs:31:13:
bad span: `)`: ``
stack backtrace:
   0:     0x7fe4044a1f16 - <<std[c12b020f820b1a60]::sys::backtrace::BacktraceLock>::print::DisplayBacktrace as core[27a82328e35982ef]::fmt::Display>::fmt
   1:     0x7fe404c0b98f - core[27a82328e35982ef]::fmt::write
   2:     0x7fe4044b702c - <std[c12b020f820b1a60]::sys::stdio::unix::Stderr as core[27a82328e35982ef]::io::write::Write>::write_fmt
   3:     0x7fe404474a1a - std[c12b020f820b1a60]::panicking::default_hook::{closure#0}
   4:     0x7fe4044961d3 - std[c12b020f820b1a60]::panicking::default_hook
   5:     0x7fe4033f8bbf - std[c12b020f820b1a60]::panicking::update_hook::<alloc[da1d5361f54fe3ea]::boxed::Box<rustc_driver_impl[c8665e0298a778c0]::install_ice_hook::{closure#1}>>::{closure#0}
   6:     0x7fe404496672 - std[c12b020f820b1a60]::panicking::panic_with_hook
   7:     0x7fe404474ad2 - std[c12b020f820b1a60]::panicking::panic_handler::{closure#0}
   8:     0x7fe40446cba9 - std[c12b020f820b1a60]::sys::backtrace::__rust_end_short_backtrace::<std[c12b020f820b1a60]::panicking::panic_handler::{closure#0}, !>
   9:     0x7fe4044763fd - __rustc[2017c61168e86746]::rust_begin_unwind
  10:     0x7fe40111d73c - core[27a82328e35982ef]::panicking::panic_fmt
  11:     0x556e917e03fe - <rustfmt_nightly[8fca045b5810b375]::visitor::SnippetProvider as rustfmt_nightly[8fca045b5810b375]::source_map::SpanUtils>::span_after::{closure#0}
  12:     0x556e91852bbb - rustfmt_nightly[8fca045b5810b375]::items::rewrite_fn_base
  13:     0x556e917ef3f0 - <rustfmt_nightly[8fca045b5810b375]::visitor::FmtVisitor>::visit_fn
  14:     0x556e917e9807 - <rustfmt_nightly[8fca045b5810b375]::visitor::FmtVisitor>::visit_item
  15:     0x556e917ea970 - <rustfmt_nightly[8fca045b5810b375]::visitor::FmtVisitor>::walk_stmts
  16:     0x556e917ed965 - <rustfmt_nightly[8fca045b5810b375]::visitor::FmtVisitor>::visit_block
  17:     0x556e9184a545 - rustfmt_nightly[8fca045b5810b375]::expr::rewrite_block_with_visitor
  18:     0x556e918417b4 - rustfmt_nightly[8fca045b5810b375]::expr::format_expr
  19:     0x556e9187ab68 - rustfmt_nightly[8fca045b5810b375]::matches::rewrite_match_body
  20:     0x556e917e23c3 - <rustfmt_nightly[8fca045b5810b375]::lists::ListItems<core[27a82328e35982ef]::slice::iter::Iter<rustfmt_nightly[8fca045b5810b375]::parse::macros::cfg_select::CfgSelectArm>, rustfmt_nightly[8fca045b5810b375]::macros::format_cfg_select::{closure#0}, rustfmt_nightly[8fca045b5810b375]::macros::format_cfg_select::{closure#1}, rustfmt_nightly[8fca045b5810b375]::macros::format_cfg_select::{closure#2}> as core[27a82328e35982ef]::iter::traits::iterator::Iterator>::next::{closure#0}
  21:     0x556e91889a0a - <alloc[da1d5361f54fe3ea]::vec::Vec<rustfmt_nightly[8fca045b5810b375]::lists::ListItem> as alloc[da1d5361f54fe3ea]::vec::spec_from_iter_nested::SpecFromIterNested<rustfmt_nightly[8fca045b5810b375]::lists::ListItem, rustfmt_nightly[8fca045b5810b375]::lists::ListItems<core[27a82328e35982ef]::slice::iter::Iter<rustfmt_nightly[8fca045b5810b375]::parse::macros::cfg_select::CfgSelectArm>, rustfmt_nightly[8fca045b5810b375]::macros::format_cfg_select::{closure#0}, rustfmt_nightly[8fca045b5810b375]::macros::format_cfg_select::{closure#1}, rustfmt_nightly[8fca045b5810b375]::macros::format_cfg_select::{closure#2}>>>::from_iter
  22:     0x556e9186892d - rustfmt_nightly[8fca045b5810b375]::macros::rewrite_macro
  23:     0x556e917efe44 - <rustfmt_nightly[8fca045b5810b375]::visitor::FmtVisitor>::visit_mac
  24:     0x556e917e9374 - <rustfmt_nightly[8fca045b5810b375]::visitor::FmtVisitor>::visit_item
  25:     0x556e91832e56 - <rustfmt_nightly[8fca045b5810b375]::visitor::FmtVisitor>::visit_items_with_reordering
  26:     0x556e917ee320 - <rustfmt_nightly[8fca045b5810b375]::visitor::FmtVisitor>::walk_mod_items
  27:     0x556e9176321a - <scoped_tls[175d74dc713e2aa3]::ScopedKey<rustc_span[3b717a46cdec11cc]::SessionGlobals>>::with::<<rustfmt_nightly[8fca045b5810b375]::Session<std[c12b020f820b1a60]::io::stdio::Stdout>>::format_input_inner::{closure#0}, core[27a82328e35982ef]::result::Result<rustfmt_nightly[8fca045b5810b375]::FormatReport, rustfmt_nightly[8fca045b5810b375]::ErrorKind>>
  28:     0x556e9175d61f - rustfmt[53f92ba75be596c0]::format_and_emit_report::<std[c12b020f820b1a60]::io::stdio::Stdout>
  29:     0x556e91772afc - rustfmt[53f92ba75be596c0]::execute
  30:     0x556e9176dd76 - rustfmt[53f92ba75be596c0]::main
  31:     0x556e9176becb - std[c12b020f820b1a60]::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
  32:     0x556e9176c859 - std[c12b020f820b1a60]::rt::lang_start::<()>::{closure#0}
  33:     0x7fe405fcd352 - std[c12b020f820b1a60]::rt::lang_start_internal
  34:     0x556e9177d1d8 - main
  35:     0x7fe3ff027781 - <unknown>
  36:     0x7fe3ff0278b9 - __libc_start_main
  37:     0x556e91642cf9 - <unknown>
  38:                0x0 - <unknown>

error: the compiler unexpectedly panicked. This is a bug

note: we would appreciate a bug report: https://github.com/rust-lang/rustfmt/issues/new?labels=bug

note: please make sure that you have updated to the latest nightly

note: please attach the file at `/tmp/im/rustc-ice-2026-08-29T22_10_47-652005.txt` to your bug report

note: rustc 1.100.0-nightly (fd7ed57df 2026-08-29) running on x86_64-unknown-linux-gnu

query stack during panic:
end of query stack
Diff in /tmp/im/a.rs:1:
 #![crate_type = "lib"]

-    cfg_select! {
+cfg_select! {
         true => {
             fn foo{
     a() => {}

Activity

  1. added
    C-bugCategory: this is a bug; use also I-* labels for specific bug kinds, e.g. I-non-idempotency or I-ICE
    I-ICEIssue: Internal Compiler Error (ICE) reported by rustfmt
    on Aug 29, 2026
  2. added
    needs-triageThis issue or PR needs triaging to determine its status. Remove label once sufficiently triaged.
    on Aug 29, 2026
  3. matthiaskrgr commented on Aug 29, 2026

    @matthiaskrgr
    MemberAuthor

    smaller:

    cfg_select! { true => { fn foo {} } }
  4. added
    unstable-language-featureFormatting related to an unstable language feature
    and removed
    needs-triageThis issue or PR needs triaging to determine its status. Remove label once sufficiently triaged.
    unstable-language-featureFormatting related to an unstable language feature
    C-bugCategory: this is a bug; use also I-* labels for specific bug kinds, e.g. I-non-idempotency or I-ICE
    I-ICEIssue: Internal Compiler Error (ICE) reported by rustfmt
    on Sep 3, 2026
  5. jieyouxu commented on Sep 3, 2026

    @jieyouxu
    Member

    Huh, this one is a bit interesting. I think what's happening is that:

    • The cfg_select! formatting can only format well-formed cfg_select! arm exprs.
    • The fn foo {} isn't valid syntax (missing ()), so we are trying to panic somewhere in trying to format item (specifically a function item). We try to recover from such panics in rewrite_macro and fallback to emit the macro unmodified (i.e. "give up").
    • The binary installs the rustc ICE hook which runs before unwinding.
    • So we get this ICE report, except rustfmt actually reports 0 (success), with the cfg_select! unmodified here, since we "successfully" gave up.
    • I was trying to add a test for this locally and noticed that the test harness cannot catch this ICE condition:
      • For idempotency the macro is re-emitted unmodified
      • For the has format failures on, it checks only non-macro formating failures
      • The test harness does not install the ICE hook, so it won't have the ICE report
  6. added
    C-bugCategory: this is a bug; use also I-* labels for specific bug kinds, e.g. I-non-idempotency or I-ICE
    I-ICEIssue: Internal Compiler Error (ICE) reported by rustfmt
    on Sep 3, 2026
  7. 1 remaining item

  8. added
    C-bugCategory: this is a bug; use also I-* labels for specific bug kinds, e.g. I-non-idempotency or I-ICE
    I-ICEIssue: Internal Compiler Error (ICE) reported by rustfmt
    and removed
    C-bugCategory: this is a bug; use also I-* labels for specific bug kinds, e.g. I-non-idempotency or I-ICE
    A-macrosArea: macros (procedural macros, macro_rules! macros, etc.)
    I-ICEIssue: Internal Compiler Error (ICE) reported by rustfmt
    on Sep 3, 2026
  9. changed the title [-][ICE]: bad span: `)`: ``[/-] [+][ICE]: `cfg_select!` invalid arm expr "successfully" formats but produces an ICE report[/+] on Sep 3, 2026
  10. changed the title [-][ICE]: `cfg_select!` invalid arm expr "successfully" formats but produces an ICE report[/-] [+][ICE]: bad span: `)`: ``; `cfg_select!` invalid arm expr "successfully" formats but produces an ICE report[/+] on Sep 3, 2026
  11. changed the title [-][ICE]: bad span: `)`: ``; `cfg_select!` invalid arm expr "successfully" formats but produces an ICE report[/-] [+][ICE]: bad span: `)`: ` `; `cfg_select!` invalid arm expr "successfully" formats but produces an ICE report[/+] on Sep 3, 2026
  12. ytmimi commented on Sep 4, 2026

    @ytmimi
    Contributor

    Yeah, I looked into this one too and it seems like fn foo {} is getting parsed as a function declaration even though it's missing (). It's a little odd because I'd expect parsing fn foo {} to fail, but it seems to parse just fine when we call parse_expr.

    Once we've got what we think is a valid block expr we go through our regular formatting flow and when we reach fn foo {} things fail because rustfmt (IMO rightfully) assumes that it will always be able to find an opening ( and closing ). I'm pretty sure we need to do that for comment recovery.

  13. jieyouxu commented on Oct 10, 2026

    @jieyouxu
    Member

    Yeah, I looked into this one too and it seems like fn foo {} is getting parsed as a function declaration even though it's missing (). It's a little odd because I'd expect parsing fn foo {} to fail, but it seems to parse just fine when we call parse_expr.

    D'oh I know why. It's because parser recovery. It's indeed invalid expr, but it's common enough that rustc's parser has a specific recovery for missing the arg list parentheses. In rustc we'd stash a diagnostics for the recovery that must be emitted or we ICE. Here in rustfmt, we cancel the stashed diagnostics but don't check error count.

    EDIT: fix is #7171

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-cfg_select`cfg_select!`A-test-harnessArea: rustfmt test harnessC-bugCategory: this is a bug; use also I-* labels for specific bug kinds, e.g. I-non-idempotency or I-ICEI-ICEIssue: Internal Compiler Error (ICE) reported by rustfmt

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions