Skip to content

Provide a way for derives to know if they were invoked with #[derive_const] #118304

Open
@jhpratt

Description

@jhpratt
Member

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).

cc @fee1-dead per this Zulip comment.

@rustbot label +A-proc-macros +C-enhancement +F-const-trait-impl +T-libs-api

Activity

added
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Nov 26, 2023
added
A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
and removed
needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.
on Nov 26, 2023
self-assigned this
on Dec 3, 2023
added
T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Dec 4, 2023
fmease

fmease commented on Jul 1, 2024

@fmease
Member

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.

Originally posted by @petrochenkov in #118580 (comment)

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.

Originally posted by @petrochenkov in #118580 (comment)

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.

Originally posted by @petrochenkov in #118580 (comment)

fmease

fmease commented on Jul 1, 2024

@fmease
Member

I will therefore close the aforementioned PR and block this issue on further design work to be done by PG-const-traits Project group: Const traits and likely also WG-macros Working group: Macros .

added
S-blockedStatus: Blocked on something else such as an RFC or other implementation work.
WG-macrosWorking group: Macros
on Jul 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)A-trait-systemArea: Trait systemC-enhancementCategory: An issue proposing an enhancement or a PR with one.F-const_trait_impl`#![feature(const_trait_impl)]`PG-const-traitsProject group: Const traitsS-blockedStatus: Blocked on something else such as an RFC or other implementation work.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.WG-macrosWorking group: Macros

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Participants

    @jhpratt@fmease@fee1-dead@rustbot

    Issue actions

      Provide a way for derives to know if they were invoked with `#[derive_const]` · Issue #118304 · rust-lang/rust