rust-lang / rust-lang/rust

The `if cfg!(debug_assertions)` make the `unconditional_recursion` lint not work (e.x. when using `debug_assert_eq!`)

Open
#149,048 8 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

C-discussion
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

I tried this code:

struct Buf<'a> {
    len: u16,
    buf: &'a [u8],
}

impl Buf<'_> {
    fn len(&self) -> usize {
        if core::cfg!(debug_assertions) {
            let _ = self.len();
        }

        self.len.into()
    }
}

fn main() {
    let buf = Buf {
        len: 3,
        buf: &[1, 2, 3],
    };

    println!("{}", buf.len());
}

I expected to see this happen: a lint on the infinite recursion for calling self.len().

Instead, this happened: the debug assertion doesn't make the lint visible.

This is the simplification of the following code:

struct Buf<'a> {
    len: u16,
    buf: &'a [u8],
}

impl Buf<'_> {
    fn len(&self) -> usize {
        debug_assert_eq!(self.len(), self.buf.len());

        self.len.into()
    }
}

fn main() {
    let buf = Buf {
        len: 3,
        buf: &[1, 2, 3],
    };

    println!("{}", buf.len());
}
Meta

I think there are other issues regarding this kind of infinite recursion, but I wanted to focus on the issue about the debug_assert... case, since it's a common pattern and the error is not easy to debug and is misleading:

thread 'main' (68424) has overflowed its stack
fatal runtime error: stack overflow, aborting
fish: Job 1, 'cargo +nightly r' terminated by signal SIGABRT (Abort)

I understand it's not actually unconditional_recursion, but it's really hard to understand when this error is encountered.

Tried with nightly

rustc --version --verbose:

rec ❯ rustc +nightly --version --verbose
rustc 1.93.0-nightly (518b42830 2025-11-16)
binary: rustc
commit-hash: 518b428304e0008859cb1fd81d1ac20efb2a064a
commit-date: 2025-11-16
host: x86_64-unknown-linux-gnu
release: 1.93.0-nightly
LLVM version: 21.1.5

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided Buf reproducer and run it using the mentioned nightly rustc version, then investigate the compiler's unconditional_recursion lint handling for code guarded by cfg!(debug_assertions). Done means the lint is emitted for the recursive call in both the simplified example and the debug_assert_eq! pattern, without changing unrelated behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.