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
{{ message }}
Repository navigation
Provide a way for derives to know if they were invoked with #[derive_const] #118304
As part of #67792, #[derive_const] is the current way to indicate that a derive should be impl const Trait rather than impl Trait. However, this only works for built-in macros. It should be possible for end-user proc macros to know if they were invoked with #[derive_const], permitting the derive to emit the appropriate code.
In my opinion, this could be an opaque type provided as an additional parameter to the derive implementation. That type would have methods to obtain constness and any other future extension (i.e. effects).
PR #118580 extends support for #[derive_const] to user-defined derive proc-macros as outlined in the issue description. However, #[derive_const] itself is very ad-hoc and non-extensible as petrochenkov criticizes, justifiably so:
Both #[derive_const] itself, and this, are maximally ad hoc tools for addressing the issue.
How macros currently take their input - by a token stream, or two token streams if the macro has two inputs like #[attr(input1)] INPUT2.
This PR adds a third backdoor input tailored for a very specific use case.
The #[derive_const] added a whole new macro just to add one configuration bit to already existing #[derive] macro.
I would suggest keeping the current model and using already existing token-based methods for configuring macro behaviors.
Either helper attributes, like many derive macros, including derive_more, already do
Or giving derive macros the second input token stream - #[derive(Clone(input1))] INPUT2, that would also improve consistency with attributes.
Then the macros themselves can process the inputs as they want.
E.g. built-in macros could conventionally take a const token to produce a const impl - #[derive(Clone(const))] struct S;, others may accept more configuration.
If #[derive] needs some sugar to pass const to multiple derive macros that it applies at once, then it can grow such sugar itself, instead of delegating to a whole new special-purpose macro.
E.g. #[derive(const: Clone, PartialEq, PartialOrd)] struct S; or anything else, tokens inside the parentheses are an arbitrary token stream, I remind you, so #[derive] can create its own language for its input, like any other attribute macro.
On a second thought, there's a third way to pass inputs - the "global data" in struct Rustc.
Proc macro methods without arguments like Span::call_site() take their return values from that global data. I also planned to add some more data there to be available to proc macros, like the kind of brackets used by the macro.
If "derive expansion options" are placed into struct Rustc, then there's no need to add a second parameter to #[proc_macro_derive] functions for passing them.
What other similar configuration values we may need in the future?
Will we need to pass them to derive macros only, or for attribute possibly for attribute or fn-like macros too? With derive macros we have an intermediate layer, the #[derive] macro which has access to compiler magic to set such configuration values, but for attribute and fn-like macros we do not.
I will therefore close the aforementioned PR and block this issue on further design work to be done by
PG-const-traitsProject group: Const traits
and likely also
WG-macrosWorking group: Macros
.
I don't think option 3 is doable without resorting to https://crates.io/crates/whichever-compiles (this is a joke, Option 3 is not possible, there is nothing that allows a proc macro to make a decision like that).
You can manually try a const derive, if that doesn't work either change sth to make it work or switch to a normal non-const derive.
I think it's more a question of transition from const traits not existing to them existing - let's imagine I have a proc macro which derives an trait that it can always derive in a const way.
Will callers need to explicitly switch from #[derive] to #[const_derive] in order to get the const version? Should it be an error to #[derive] a const Trait? Is it ok for a proc macro to give a const impl when called with #[derive]?
Activity
fmease commentedon Jul 1, 2024
PR #118580 extends support for
#[derive_const]to user-defined derive proc-macros as outlined in the issue description. However,#[derive_const]itself is very ad-hoc and non-extensible as petrochenkov criticizes, justifiably so:Originally posted by @petrochenkov in #118580 (comment)
Originally posted by @petrochenkov in #118580 (comment)
Originally posted by @petrochenkov in #118580 (comment)
fmease commentedon Jul 1, 2024
I will therefore close the aforementioned PR and block this issue on further design work to be done by PG-const-traitsProject group: Const traits
and likely also
WG-macros
Working group: Macros
.
illicitonion commentedon Jul 17, 2025
It feels like there are three intentions that may be expressible:
constimplconstimplconst, great, if not, I'll take non-constDo we intend to make each of these intentions signal-able? Particularly, will
#[derive]imply 2 or 3? And will there be a way to express the other?oli-obk commentedon Jul 17, 2025
I don't think option 3 is doable without resorting to https://crates.io/crates/whichever-compiles (this is a joke, Option 3 is not possible, there is nothing that allows a proc macro to make a decision like that).
You can manually try a
constderive, if that doesn't work either change sth to make it work or switch to a normal non-const derive.illicitonion commentedon Jul 17, 2025
I think it's more a question of transition from const traits not existing to them existing - let's imagine I have a proc macro which derives an trait that it can always derive in a
constway.Will callers need to explicitly switch from
#[derive]to#[const_derive]in order to get the const version? Should it be an error to#[derive]aconst Trait? Is it ok for a proc macro to give aconstimpl when called with#[derive]?sunipkm commentedon May 11, 2026