Description
Nobody responded to my URLO thread, and the rabbit hole has only gotten deeper and deeper since I've started trying to work around this in frunk's hlist_pat. It's time for an issue.
Here's a simple pattern macro:
pub struct Value<A> { pub value: A }
#[macro_export]
macro_rules! pat {
($a:pat) => { Value { value: $a }};
}
Trouble is, suppose somebody writes pat!(value)
. Then they'll get this:
warning: the `value:` in this pattern is redundant
--> src/main.rs:5:27
|
5 | ($a:pat) => { Value { value: $a }};
| ^^^^^ help: remove this
...
9 | let pat!(value) = Value { value: () };
| ----------- in this macro invocation
|
= note: #[warn(non_shorthand_field_patterns)] on by default
Finished dev [unoptimized + debuginfo] target(s) in 0.45 secs
Running `target/debug/playground`
Here is the simplest alternative I can come up with for working around this warning in this simple macro.
macro_rules! pat {
// Possibly rewrite ident patterns to avoid 'value: value'.
// We need to duplicate the ident in an intermediate rule first
// so we can match the ident to a literal without losing hygiene.
(ref mut $a:ident) => { pat![%HACK% [ref mut] $a $a] };
(ref $a:ident) => { pat![%HACK% [ref] $a $a] };
(mut $a:ident) => { pat![%HACK% [mut] $a $a] };
($a:ident) => { pat![%HACK% [] $a $a] };
// only the specific ident 'value' should be rewritten,
// since otherwise we might rewrite unit structs or constants.
(%HACK% [$($kw:tt)*] $ident:ident value ) => { Value { $($kw)* $ident } };
(%HACK% [$($kw:tt)*] $ident:ident $_x:tt) => { Value { value: $($kw)* $ident } };
// if it is any other kind of pattern, use it normally
($a:pat) => { Value { value: $a }};
}
Notice how proper support for ref
and mut
requires that the macro output uses shorthand field syntax, as opposed to a more scalable workaround like value: value@_
(where the value@_
is at least something that could be produced by a helper macro). A similar pattern macro for a struct with two fields basically requires an incremental muncher now, just to avoid the exponential blowup of 5^n
rules.
This is an awful lot of headache just for a little reminder to write more idiomatic code! Isn't that clippy's job, anyhow?