Skip to content

Compiler unexpectedly panicked in std::sys::backtrace::BacktraceLock::print::DisplayBacktrace (on Mac and Linux) #140421

Closed as duplicate of#138979
@ShakenCodes

Description

@ShakenCodes

Code

#![cfg_attr(not(test), no_std)]
#![cfg_attr(not(test), no_main)]

// Only dependency in Cargo.toml is: heapless = "0.9.0"

use core::{
    cmp::PartialOrd,
    fmt::Debug,
    mem::size_of,
    ops::{Add, Div, Mul, Sub},
};
use heapless::HistoryBuf;

pub struct MovingAverage<T, TCALC, const N: usize>
where
    T: Sized + PartialEq + TryFrom<TCALC, Error: Debug> + Clone + Copy,
    TCALC: Sized
        + Add<TCALC, Output = TCALC>
        + Sub<TCALC, Output = TCALC>
        + Div<Output = TCALC>
        + Mul<Output = TCALC>
        + PartialEq
        + PartialOrd
        + From<T>
        + TryFrom<usize, Error: Debug>
        + Clone
        + Copy,
{
    num: TCALC,
    sum: Option<TCALC>,
    buffer: HistoryBuf<T, N>,
}

/// # Panics
/// Panics if TCALC not larger than T, allocation-time assert.
/// Panics if unable to convert from usize to TCALC.
/// This panic should never occur due to allocation-time assert checks.
#[expect(clippy::unwrap_used, reason = "Made safe by compile-time asserts")]
impl<T, TCALC, const N: usize> Default for MovingAverage<T, TCALC, N>
where
    T: Sized + PartialEq + TryFrom<TCALC, Error: Debug> + Clone + Copy,
    TCALC: Sized
        + Add<TCALC, Output = TCALC>
        + Sub<TCALC, Output = TCALC>
        + Div<Output = TCALC>
        + Mul<Output = TCALC>
        + PartialEq
        + PartialOrd
        + From<T>
        + TryFrom<usize, Error: Debug>
        + Clone
        + Copy,
{
    fn default() -> Self {
        const {
            assert!(
                size_of::<TCALC>() > size_of::<T>(),
                "TCALC must be larger than T"
            );
            assert!(N > 0, "N must be non-zero");
        }
        Self {
            num: TCALC::try_from(N).unwrap(),
            sum: None,
            buffer: HistoryBuf::new(),
        }
    }
}

impl<T, TCALC, const N: usize> MovingAverage<T, TCALC, N>
where
    T: Sized + PartialEq + TryFrom<TCALC, Error: Debug> + Clone + Copy,
    TCALC: Sized
        + Add<TCALC, Output = TCALC>
        + Sub<TCALC, Output = TCALC>
        + Div<Output = TCALC>
        + Mul<Output = TCALC>
        + PartialEq
        + PartialOrd
        + From<T>
        + TryFrom<usize, Error: Debug>
        + Clone
        + Copy,
{
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    /// # Panics
    /// Panics if unable to convert from TCALC to T.
    /// This panic should never occur due to compile-time assert checks.
    #[must_use]
    pub fn average(&mut self, input: T) -> T {
        let new_value = TCALC::from(input);
        let prev_sum = self.get_or_init_and_get_sum(input);
        let remove = self.insert_new_value_pop_oldest_value(input);
        self.create_average(new_value, prev_sum, remove)
    }

    fn get_or_init_and_get_sum(&mut self, input: T) -> TCALC {
        let new_value = TCALC::from(input);
        if let Some(sum) = self.sum {
            sum
        } else {
            for _ in 0..N {
                self.buffer.write(input);
            }
            self.num * new_value
        }
    }

    fn insert_new_value_pop_oldest_value(&mut self, input: T) -> TCALC {
        let remove = self.get_remove_value();
        self.buffer.write(input);
        remove
    }

    #[expect(clippy::expect_used, reason = "Made safe by compile-time asserts")]
    fn create_average(&mut self, new_value: TCALC, prev_sum: TCALC, remove: TCALC) -> T {
        #[cfg(test)]
        assert!(prev_sum >= remove, "Remove must not be bigger than sum.");

        let new_sum = prev_sum + new_value - remove;
        self.sum = Some(new_sum);
        let average_as_tcalc = new_sum / self.num;
        T::try_from(average_as_tcalc).expect("Converting from TCALC to T should be safe")
    }

    #[expect(clippy::expect_used, reason = "Made safe by compile-time asserts")]
    fn get_remove_value(&self) -> TCALC {
        #[cfg(test)]
        assert!(
            self.buffer.len() == N,
            "Buffer len {} different than capacity {N}.",
            self.buffer.len()
        );

        TCALC::from(*self.buffer.oldest().expect("Buffer should be full"))
    }
}

Meta

rustc --version --verbose:

rustc 1.86.0 (05f9846f8 2025-03-31)
binary: rustc
commit-hash: 05f9846f893b09a1be1fc8560e33fc3c815cfecb
commit-date: 2025-03-31
host: aarch64-apple-darwin
release: 1.86.0
LLVM version: 19.1.7

Error output

% cargo build --release
   Compiling heapless v0.9.0
   Compiling byteorder v1.5.0
   Compiling stable_deref_trait v1.2.0
   Compiling hash32 v0.3.1
   Compiling no-std-moving-average v0.1.0 (/Users/shakencodes/Development/Kelvin/no-std-moving-average-rs)

thread 'rustc' panicked at compiler/rustc_errors/src/lib.rs:675:17:
`trimmed_def_paths` called, diagnostics were expected but none were emitted. Use `with_no_trimmed_paths` for debugging. Backtraces are currently disabled: set `RUST_BACKTRACE=1` and re-run to see where it happened.
stack backtrace:
   0:        0x10d8e9c78 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h217270392019d164
   1:        0x10b0ec3f0 - core::fmt::write::he22fcab56bd3ec61
   2:        0x10d8de3e8 - std::io::Write::write_fmt::hb32eaafcfd249a19
   3:        0x10d8e9b38 - std::sys::backtrace::BacktraceLock::print::h115149c0b879e5c3
   4:        0x10d8ebf9c - std::panicking::default_hook::{{closure}}::h5c3a234feebd11a5
   5:        0x10d8ebdec - std::panicking::default_hook::ha0b223ccc4379930
   6:        0x10bb5a5e8 - std[9558dde1fef45f95]::panicking::update_hook::<alloc[a353884198cecfbc]::boxed::Box<rustc_driver_impl[d422414f666c26d7]::install_ice_hook::{closure#1}>>::{closure#0}
   7:        0x10d8ecc18 - std::panicking::rust_panic_with_hook::h203f96c93e7ac62d
   8:        0x10d8ec7ac - std::panicking::begin_panic_handler::{{closure}}::hcc8f653f753c0254
   9:        0x10d8ea108 - std::sys::backtrace::__rust_end_short_backtrace::h911de07218b69a6c
  10:        0x10d8ec470 - _rust_begin_unwind
  11:        0x1103a77a4 - core::panicking::panic_fmt::h6a4014bec58fba4f
  12:        0x10bc09634 - <rustc_errors[ec173a575dd51043]::DiagCtxtInner as core[b495b0e88a16f434]::ops::drop::Drop>::drop
  13:        0x10bb2b730 - core[b495b0e88a16f434]::ptr::drop_in_place::<rustc_errors[ec173a575dd51043]::DiagCtxt>
  14:        0x10bb413d4 - core[b495b0e88a16f434]::ptr::drop_in_place::<rustc_session[ba2d81a866856cf8]::parse::ParseSess>
  15:        0x10bb3b5d8 - core[b495b0e88a16f434]::ptr::drop_in_place::<rustc_interface[3ca3d7ac74064029]::interface::Compiler>
  16:        0x10bb572b4 - rustc_interface[3ca3d7ac74064029]::interface::run_compiler::<(), rustc_driver_impl[d422414f666c26d7]::run_compiler::{closure#0}>::{closure#1}
  17:        0x10bb49aa4 - std[9558dde1fef45f95]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[3ca3d7ac74064029]::util::run_in_thread_with_globals<rustc_interface[3ca3d7ac74064029]::util::run_in_thread_pool_with_globals<rustc_interface[3ca3d7ac74064029]::interface::run_compiler<(), rustc_driver_impl[d422414f666c26d7]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  18:        0x10bb5e0fc - <<std[9558dde1fef45f95]::thread::Builder>::spawn_unchecked_<rustc_interface[3ca3d7ac74064029]::util::run_in_thread_with_globals<rustc_interface[3ca3d7ac74064029]::util::run_in_thread_pool_with_globals<rustc_interface[3ca3d7ac74064029]::interface::run_compiler<(), rustc_driver_impl[d422414f666c26d7]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[b495b0e88a16f434]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  19:        0x10d8f76b4 - std::sys::pal::unix::thread::Thread::new::thread_start::h6d53b1b0c047a3b9
  20:        0x185b85c0c - __pthread_cond_wait

error: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.86.0 (05f9846f8 2025-03-31) running on aarch64-apple-darwin

note: compiler flags: --crate-type lib -C opt-level=3 -C embed-bitcode=no -C strip=debuginfo

note: some of the compiler flags provided by cargo are hidden

query stack during panic:
end of query stack
error: could not compile `heapless` (lib)

Caused by:
  process didn't exit successfully: `/Users/shakencodes/.rustup/toolchains/stable-aarch64-apple-darwin/bin/rustc --crate-name heapless --edition=2021 /Users/shakencodes/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/heapless-0.9.0/src/lib.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=113 --crate-type lib --emit=dep-info,metadata,link -C opt-level=3 -C embed-bitcode=no --check-cfg 'cfg(docsrs,test)' --check-cfg 'cfg(feature, values("alloc", "bytes", "defmt", "mpmc_large", "nightly", "portable-atomic", "portable-atomic-critical-section", "portable-atomic-unsafe-assume-single-core", "serde", "ufmt"))' -C metadata=e55147cee1a46efb -C extra-filename=-9d546ea6984ac991 --out-dir /Users/shakencodes/Development/Kelvin/no-std-moving-average-rs/target/release/deps -C strip=debuginfo -L dependency=/Users/shakencodes/Development/Kelvin/no-std-moving-average-rs/target/release/deps --extern hash32=/Users/shakencodes/Development/Kelvin/no-std-moving-average-rs/target/release/deps/libhash32-9bb5e7c30052cb43.rmeta --extern stable_deref_trait=/Users/shakencodes/Development/Kelvin/no-std-moving-average-rs/target/release/deps/libstable_deref_trait-ce896a0d5f65d597.rmeta --cap-lints allow --check-cfg 'cfg(arm_llsc)' --check-cfg 'cfg(has_atomic_load_store)'` (exit status: 101)
warning: build failed, waiting for other jobs to finish...
%
Backtrace

% RUST_BACKTRACE=1 cargo build
   Compiling no-std-moving-average v0.1.0 (/Users/shakencodes/Development/Kelvin/no-std-moving-average-rs)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.11s
%

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions