Skip to content

Conversation

@ginzahatemi
Copy link

This PR addresses #1601 by implementing a new lint that detects cases where format!() could be
replaced with concat!() for improved performance.

Problem

When all arguments to a format!() macro are compile-time constants and use
the standard Display formatting trait, the formatting can be done at compile time
with concat!() instead of being deferred to runtime.

Solution

This lint analyzes format string placeholders and their arguments to detect:

  1. When all placeholders use the Display trait (default {} format)
  2. When all arguments are const-evaluatable (compile-time constants)

When both conditions are met, it suggests replacing with an equivalent concat!()
expression.

Examples

// Will trigger the lint:
format!("hello {}", "world")  // suggests: concat!("hello ", "world")
format!("{}/file.txt", env!("CARGO_MANIFEST_DIR"))  // suggests: concat!(env!("CARGO_MANIFEST_DIR"), "/file.txt")

// Will not trigger:
format!("debug: {:?}", some_struct)  // Uses Debug trait
format!("value: {}", runtime_variable)  // Not const-evaluatable

Fixes #1601

@ginzahatemi ginzahatemi requested a review from smoelius as a code owner May 15, 2025 11:56
@ginzahatemi
Copy link
Author

Hello @smoelius, sorry to bother you. Could you please help me with the CI failures I'm encountering?

I tried to fix it myself, but it looks like I am repeatedly getting the clippy error. I tried adding the following to my Cargo.toml file:

clippy_utils = { workspace = true }

But I'm still seeing the same errors. Any idea what might be going wrong?

Thank You!

Copy link
Collaborator

@smoelius smoelius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ginzahatemi Sorry for being slow to respond.

Here are a few things I noticed.

I think the compilation errors you are seeing are from a mismatch between the rust-toolchain file and the clippy_utils version.

Specifically, for the clippy_utils version you are using, I think the toolchain should be nightly-2025-04-03.

Comment on lines +1 to +6
[target.'cfg(all())']
rustflags = ["-C", "linker=dylint-link"]

# For Rust versions 1.74.0 and onward, the following alternative can be used
# (see https://github.com/rust-lang/cargo/pull/12535):
# linker = "dylint-link"
Copy link
Collaborator

@smoelius smoelius May 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[target.'cfg(all())']
rustflags = ["-C", "linker=dylint-link"]
# For Rust versions 1.74.0 and onward, the following alternative can be used
# (see https://github.com/rust-lang/cargo/pull/12535):
# linker = "dylint-link"
[build]
target-dir = "../../target/examples"
[target.'cfg(all())']
linker = "dylint-link"

To match the other examples' configs.

@@ -0,0 +1 @@
/target
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file can be removed. A .gitignore in a parent directory accomplishes this.

version = "0.1.0"
authors = ["Your Name <[email protected]>"]
description = "A Dylint lint to suggest using `concat!(...)` instead of `format!(...)` for all-constant Display arguments."
edition = "2021"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
edition = "2021"
edition = "2024"

@@ -0,0 +1,3 @@
[toolchain]
channel = "nightly-2025-02-20"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
channel = "nightly-2025-02-20"
channel = "nightly-2025-04-03"

There's a test to ensure that all examples use the same toolchain, and this is the toolchain they currently use.

Also, I think this is the toolchain that goes with the version of clippy_utils you are currently using.

@@ -0,0 +1,26 @@
[package]
name = "format_concat_args"
version = "0.1.0"
Copy link
Collaborator

@smoelius smoelius May 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
version = "0.1.0"
version = "4.1.0"

To match the versions used elsewhere in this repository.

@smoelius
Copy link
Collaborator

@ginzahatemi Thank you very much for your work on this! I will pick up this PR, if you don't mind.

@smoelius smoelius reopened this Sep 28, 2025
@smoelius smoelius self-assigned this Sep 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

format!(...) with only constant arguments

2 participants