Hmm I can see that what you're saying is true. And yet the situation described still persists in my real code.
The real enum is a bit more complex, as it has a derive attribute, a tuple struct variant and a bunch of unit struct variants. So now I'm guessing something about that cocktail is confusing the compiler, because what else could it possibly be?
From first principles I wonder how the derive could even influence that. Derive macro's are limited to generating new code, and have read-only access to the type's tokens, correct? So what could possibly be generated that generates a warning of this kind on the input enum variant itself?
For reference, these are the traits being derived: Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize and one I've written called Delta that appropriately enough calculates deltas for 2 values of the same type as well as apply those deltas. But like I said, above, AFAIK derives have read-only access to their input, so it would have to be some generated code somehow that is triggering the warning on the input enum.
Also a note on cargo-expand: I actually tried to use it during the development of my derive macro. My takeaway was that its usability is greatly hampered by the fact that it does an expand-all in lisp terms, while what I need is an expand-1 i.e. just 1 level of macro expansion. This is because I don't care about generated code that uses macros in the output. In fact its presence is detrimental because it means that the information I care about (i.e. the signal) gets buried between bits and pieces of information I don't care about (i.e. the noise).
A derive could be creating a type with a name based on your type, and the warning is emitted due to the macro-created-type. I don't think Serialize and Deserialize do this, none of the std derives do this, so maybe Delta?
The Delta derive macro does in fact do this.
Okay so given that I also have the fix (which is easier said than done though): copy over the tokens for the enum variant's attribute macro to the corresponding enum variant of the generated type.
You could unconditionally #[allow(nonstandard_style)] on your derived code. If the user has something weird, they'll get those warnings on their own part, or mask it themselves, but I don't think you should worry about that on your part.
The input TokenStream is the token stream of the item that has the derive attribute on it. The output TokenStream must be a set of items that are then appended to the module or block that the item from the input TokenStream is in.
only attribute/function like macros replace their inputs
I have defined a #[deltoid(ignore_field)] attribute as part of the attribute macro that, when applied to a field, ignores that field when computing and applying a delta. (so no, luckily it's not removed from the token stream). Basically it's just a part of the input which can be parsed using syn, at which point you have an enum and struct based AST. So it's possible to just scan the AST for the information required, and generate code accordingly.
Derive macros can declare a number of “helper” attributes that they will parse during the expansion. These helpers are then treated as noop attribute macros after the expansion has completed. One key for this is that Serialize and Deserialize share the same attributes, if one of them were to remove the attribute during expansion then the second to run would not get to see it.
Rustc knows that these attributes belong to the derive macros, and ignores them for all other purposes. When declaring a derive proc macro, the macro programmer also declares all the attributes it takes in, like:
As I understand it, then, the attributes declared by a proc macro are treated as valid, and ignored for all purposes except being sent to proc macros. I think they're also scoped per-derive: a derive macro won't see #[serde(...)] unless it declares the serde attribute.