Skip to content

Inlining/flattening of format_args!() accidentally exposed as stable through const #139136

Description

@m-ou-se

format_args!() can currently only be stored (and used later) if it has no arguments:

let a = format_args!("1 + 1 = 2"); // ok
let b = format_args!("1 + 1 = {}", 2); // error

println!("{a} {b}");

However, format_args!("1 + 1 = {}", 2) is optimized to (effectively) format_args!("1 + 1 = 2") as part of ast lowering.
To avoid allowing more code because of this optimization, the lowering results in a slightly different expansion that would still result in the same error. (By using &none() rather than &[].)

However, I had failed to consider the effect in a const:

However, because of #135139, we now have:

const X: std::fmt::Arguments = format_args!("1 + 1 = 2"); // ok
const Y: std::fmt::Arguments = format_args!("1 + 1 = {}", 2); // ok
const Z: std::fmt::Arguments = format_args!("1 + 1 = {}", 1 + 1); // error

println!("{X} {Y} {Z}");

(The expression for Y is subject to format_args inlining/flattening. The one for Z is not.)

It means there can be code out there that relies on format_args inlining/flattening working the way it does today.

Two solutions:

  1. Make the Y example fail to compile as well. This would be a (small?) breaking change. Don't allow flattened format_args in const. #139624
  2. Make all these examples work. (We probably want that in the future.)

Activity

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-fmtArea: `core::fmt`C-bugCategory: This is a bug.T-langRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE]

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions