-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Closed
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
Assignments inside format_args!
are ignored. Instead only the right-hand side of the expression is used.
I tried this code:
fn main() {
let mut x = 1;
println!("first: {}", x = 3);
println!("second: {}", x);
}
or a similar one, using directly format_args
:
use std::io::{self, Write};
fn main() {
let mut x = 1;
io::stdout().write_fmt(format_args!("first: {}\n", x = 3));
io::stdout().write_fmt(format_args!("second: {}\n", x));
}
I expected to see this:
first: ()
second: 3
Instead the output was:
first: 3
second: 1
It looks like the the assignment x = 3
is ignored and is instead treated as if it was just 3
.
I could only replicate this with format_args!
and macros that use it. Other macros, like assert_eq!
, work as expected.
Meta
rustc --version --verbose
:
rustc 1.22.0-nightly (dcbbfb6e8 2017-10-12)
binary: rustc
commit-hash: dcbbfb6e807fdff9c9ba80073bb755f9d9d95e31
commit-date: 2017-10-12
host: x86_64-unknown-linux-gnu
release: 1.22.0-nightly
LLVM version: 4.0
(also tried on rustc 1.20.0-stable
and rustc 1.21.0-stable
)
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-lintsArea: Lints (warnings about flaws in source code) such as unused_mut.Area: Lints (warnings about flaws in source code) such as unused_mut.C-bugCategory: This is a bug.Category: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Projects
Milestone
Relationships
Development
Select code repository
Activity
sinkuu commentedon Oct 13, 2017
format_args
supports named arguments withname = value
syntax. Assignments can be written as{x = 3}
so that they won't be treated as named argument.What's odd is that
{}
formats arguments just in the sequence of arguments, ignoring if they are named or positional. Is this intended behavior?kennytm commentedon Oct 13, 2017
The
x = 3
is not parsed as assignment, but named parameters.The bug here is that
println!("first: {}", x = 3);
should not compile since parameter 0 is missing.nagisa commentedon Oct 13, 2017
What @kennytm and @sinku said is correct, but I’m not sure it (the behaviour of how named arguments are considered in context of positional arguments) can be considered a bug anymore. At least I can easily see somebody using this, intentionally or not, even if it wasn’t documented to have specifically this behaviour. Therefore nominating it for T-lang (since format_args! is a part of language) to decide what the intended behaviour is.
ollie27 commentedon Oct 13, 2017
From Positional parameters:
Which suggests this is working as intended.
If anything I'd say there should be a warning if you name a parameter but never reference it by its name.
sinkuu commentedon Oct 13, 2017
@ollie27 Isn't that talking only about positional parameters?
The behavior in question have been introduced in Rust 1.12. I speculate that #33642 (which seems to have added internal translation of named args into positional args) unintentionally did it.
Example:
Rust 1.11.0:
Rust 1.12.0
(compiles fine, and the program prints "1")
joshtriplett commentedon Oct 19, 2017
Consensus in the lang team meeting is that we should reintroduce a lint for "named argument never used". And if it's just a lint, we don't need a full crater run.
estebank commentedon Jul 8, 2022
#98580 will lint against this as warn-by-default.
PrestonFrom commentedon Jul 14, 2022
#98580 has been merged -- should this issue be closed?