Skip to content

Commit 270bada

Browse files
committed
State precedence of implicit named arguments
In RFC discussion it emerged that it was not clearly stated in the RFC that implicit named arguments only apply if a corresponding explicit named argument is not passed to the macro invocation.
1 parent 090b356 commit 270bada

File tree

1 file changed

+33
-4
lines changed

1 file changed

+33
-4
lines changed

text/0000-format-args-implicit-identifiers.md

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000)
44
- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000)
55

6+
67
# Summary
78
[summary]: #summary
89

@@ -18,6 +19,12 @@ This would result in downstream macros based on `format_args!` to accept implici
1819
// implicit named arguments `species` and `name`
1920
format!("The {species}'s name is {name}.");
2021

22+
Implicit named argument capture only occurs when a corresponding named argument is not provided to the macro invocation. So in the below example, no implicit lookup for `species` is performed:
23+
24+
// explicit named argument `species`
25+
// implicit named argument `name`
26+
format!("The {species}'s name is {name}.", species="cat");
27+
2128
(Downstream macros based on `format_args!` include but are not limited to `format!`, `print!`, `write!`, `panic!`, and macros in the `log` crate.)
2229

2330

@@ -46,9 +53,29 @@ Should `person` not exist in the scope, the usual error E0425 would be emitted b
4653

4754
error[E0425]: cannot find value `person` in this scope
4855
--> .\foo.rs:X:Y
49-
|
50-
3 | println!("hello {person}");
51-
| ^^^^^^^^ not found in this scope
56+
|
57+
X | println!("hello {person}");
58+
| ^^^^^^^^ not found in this scope
59+
60+
Implicit arguments would have lower precedence than the existing named arguments `format_args!` already accepts. For example, in the example below, the `person` named argument is explicit, and so the `person` variable in the same scope would not be captured:
61+
62+
let person = "David";
63+
64+
// Person is an explicit named argument, so this
65+
// expands to "hello Matt".
66+
println!("hello {person}", person="Matt");
67+
68+
Indeed, in this example above the `person` variable would be unused, and so in this case the unused varible warning will apply, like the below:
69+
70+
warning: unused variable: `person`
71+
--> src/foo.rs:X:Y
72+
|
73+
X | let person = "David";
74+
| ^^^^^^ help: consider prefixing with an underscore: `_person`
75+
|
76+
= note: `#[warn(unused_variables)]` on by default
77+
78+
Because implicit named arguments would have lower precedence than explicit named arguments, it is anticipated that no breaking changes would occur to existing code by implementing this RFC.
5279

5380
As a result of this change, downstream macros based on `format_args!` would also be able to accept implicit named arguments in the same way. This would provide ergonomic benefit to many macros across the ecosystem, including:
5481

@@ -62,10 +89,10 @@ As a result of this change, downstream macros based on `format_args!` would also
6289

6390
(This is not an exhaustive list of the many macros this would affect. In discussion of this RFC if any further commonly-used macros are noted, they should be added to this list.)
6491

92+
6593
# Reference-level explanation
6694
[reference-level-explanation]: #reference-level-explanation
6795

68-
6996
The implementation pathway is directly motivated by the guide level explanation given above:
7097

7198
1. The `format_args!` macro can continue to parse the format string and arguments provided to it in the existing fashion, categorising arguments as either positional or named.
@@ -80,6 +107,8 @@ The implementation pathway is directly motivated by the guide level explanation
80107

81108
If this RFC were implemented, instead of this resulting in an error, this named argument would be treated as an **implicit named argument** and the final result of the expansion of the `format_args!` macro would be the same as if a named argument, with name equivalent to the identifier, had been provided to the macro invocation.
82109

110+
Because `person` is only treated as an implicit named argument if no exisiting named argument can be found, this ensures that implicit named arguments have lower precedence than explicit named arguments.
111+
83112
## Macro Hygiene
84113

85114
Expanding the macro in this fashion will need to generate an identifier which corresponds to the implicit named argument. The hygiene of this generated identifier would be inherited from the format string, with location information reduced to the section of the format string which contains the implicit named argument.

0 commit comments

Comments
 (0)