Weirdly placed derive attributes undesiredly accepted
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Consider this ludicrous code:
use serde::Serialize;
#[derive(Serialize)]
struct Const<const X: i32>;
#[derive(Serialize)]
struct Struct {
field: Const<{
#[serde(absurd, transparent)]
mod inner {}
42
}>,
}
Currently this builds. I think it shouldn't. Essentially I'm sneaking random stuff into the scope of rustc's idea of where #[serde] is allowed and then applying #[serde] attributes to some of the random stuff. Obviously serde doesn't look in there so the misplaced attribute is ignored.
If we think it's the macro's job (serde in this case) to prevent this, then syn ought to have a handy function for "just doing it". Should we then call this function in every macro? That seems like an impractical prescription, both because we don't want to be changing every macro, and because not every macro uses syn.
So maybe this is a bug in Rust? I think you need const generics to do this (since that's how to get the block into the struct definition).I doubt that when const generics were stabilised this was intended.
But fixing it in Rust would have a backward compatibility problem. In theory someone might be doing something like this deliberately! So maybe the check needs to be opt-out?
I think the main points of the rustc built-in "unused attribute" warning are to spot (i) typoed attributes (ii) forgotten #[derive]. This situation can't arise from (i), since the attribute does exist. (ii) could only happen if the inner block contained a whole struct definition that someone was trying to derive on, and probably you'd notice another way since the derive's output would be missing (so the struct wouldn't implement the trait or whatever). So it doesn't seem a very serious problem, even though I guess some macros might have semantics that would encourage a user to try this syntax.
The derive macros in std aren't affected because they cheat: they use compiler magic for their attributes. I think Default is the only one that even has an attribute, and putting #[default] next to #[serde(absurd, transparent)] does produce an error.
Anyway, out of serde, syn, and rust, I have chosen to file this as a ticket against rust. CC @dtolnay
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the const-generic example in the linked Rust Playground and trace how rustc handles the misplaced attribute inside the const block. Compare whether the behavior belongs in rustc, serde, or syn, then establish whether the desired outcome is rejection, an opt-out check, or documented acceptance.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100