Skip to content

format_args deduplicates consts with interior mutability or destructor #145739

@theemathas

Description

@theemathas

I'm not sure if this is a bug or not.

I tried this code:

use std::fmt::{self, Display, Formatter};
use std::cell::Cell;

struct PrintCounter(Cell<usize>);

impl Display for PrintCounter {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let counter = 1 + self.0.get();
        self.0.set(counter);
        write!(f, "{counter}")
    }
}

const ZERO: PrintCounter = PrintCounter(Cell::new(0));

fn main() {
    println!("{ZERO}, {ZERO}");
}

I expected the code to print 1, 1, since I am creating two separate PrintCounter values and printing them separately.

Instead, it printed 1, 2. The compiler seemed to have deduplicated the two mentions of ZERO into one mention.

Note that if the code is modified to be println!("{}, {}", ZERO, ZERO);, then it correctly prints 1, 1.

@rustbot labels +A-fmt

Meta

Reproducible on the playground with version 1.91.0-nightly (2025-08-20 040a98af70f0a7da03f3)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)A-destructorsArea: Destructors (`Drop`, …)A-fmtArea: `core::fmt`C-discussionCategory: Discussion or questions that doesn't represent real issues.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions