You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
@@ -18,6 +19,12 @@ This would result in downstream macros based on `format_args!` to accept implici
18
19
// implicit named arguments `species` and `name`
19
20
format!("The {species}'s name is {name}.");
20
21
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
+
21
28
(Downstream macros based on `format_args!` include but are not limited to `format!`, `print!`, `write!`, `panic!`, and macros in the `log` crate.)
22
29
23
30
@@ -46,9 +53,29 @@ Should `person` not exist in the scope, the usual error E0425 would be emitted b
46
53
47
54
error[E0425]: cannot find value `person` in this scope
48
55
--> .\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.
52
79
53
80
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:
54
81
@@ -62,10 +89,10 @@ As a result of this change, downstream macros based on `format_args!` would also
62
89
63
90
(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.)
The implementation pathway is directly motivated by the guide level explanation given above:
70
97
71
98
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
80
107
81
108
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.
82
109
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
+
83
112
## Macro Hygiene
84
113
85
114
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