-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide a way for custom derives to know if they were invoked via #[derive_const]
#118580
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -484,12 +484,16 @@ impl ProcMacro { | |
} | ||
} | ||
|
||
pub const fn custom_derive( | ||
pub const fn custom_derive<Discriminant>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really hope that this type parameter doesn't “leak” in the sense that By the way, I can't replace this type parameter with impl-Trait since nested impl-Traits aren't supported at the moment (here: |
||
trait_name: &'static str, | ||
attributes: &'static [&'static str], | ||
expand: impl Fn(crate::TokenStream) -> crate::TokenStream + Copy, | ||
expand: impl ~const ExpandCustomDerive<Discriminant>, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's unfortunate that I had to enable |
||
) -> Self { | ||
ProcMacro::CustomDerive { trait_name, attributes, client: Client::expand1(expand) } | ||
ProcMacro::CustomDerive { | ||
trait_name, | ||
attributes, | ||
client: Client::expand1(expand.into_fn()), | ||
} | ||
} | ||
|
||
pub const fn attr( | ||
|
@@ -506,3 +510,26 @@ impl ProcMacro { | |
ProcMacro::Bang { name, client: Client::expand1(expand) } | ||
} | ||
} | ||
|
||
#[const_trait] | ||
pub trait ExpandCustomDerive<Discriminant> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know that adding a “discriminant” to this trait is slightly ugly but it's necessary to make the two |
||
fn into_fn(self) -> impl Fn(crate::TokenStream) -> crate::TokenStream + Copy; | ||
} | ||
|
||
impl<F> const ExpandCustomDerive<()> for F | ||
where | ||
F: Fn(crate::TokenStream) -> crate::TokenStream + Copy, | ||
{ | ||
fn into_fn(self) -> impl Fn(crate::TokenStream) -> crate::TokenStream + Copy { | ||
self | ||
} | ||
} | ||
|
||
impl<F> const ExpandCustomDerive<crate::DeriveExpansionOptions> for F | ||
where | ||
F: Fn(crate::TokenStream, crate::DeriveExpansionOptions) -> crate::TokenStream + Copy, | ||
{ | ||
fn into_fn(self) -> impl Fn(crate::TokenStream) -> crate::TokenStream + Copy { | ||
move |input| self(input, Default::default()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This feels a bit weird and it demonstrates that |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,7 +25,9 @@ | |
#![feature(rustc_allow_const_fn_unstable)] | ||
#![feature(staged_api)] | ||
#![feature(allow_internal_unstable)] | ||
#![feature(const_trait_impl)] | ||
#![feature(decl_macro)] | ||
#![feature(effects)] | ||
#![feature(maybe_uninit_write_slice)] | ||
#![feature(negative_impls)] | ||
#![feature(new_uninit)] | ||
|
@@ -85,6 +87,32 @@ impl !Send for TokenStream {} | |
#[stable(feature = "proc_macro_lib", since = "1.15.0")] | ||
impl !Sync for TokenStream {} | ||
|
||
/// Derive expansion options. | ||
#[rustc_diagnostic_item = "DeriveExpansionOptions"] | ||
#[unstable(feature = "derive_const", issue = "none")] | ||
#[derive(Default, Clone)] | ||
#[non_exhaustive] | ||
pub struct DeriveExpansionOptions; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bikeshed name |
||
|
||
impl DeriveExpansionOptions { | ||
/// Returns the default options. | ||
#[unstable(feature = "derive_const", issue = "none")] | ||
pub fn new() -> Self { | ||
Self::default() | ||
} | ||
|
||
/// Whether this is a `#[derive_const]` or a `#[derive]`. | ||
#[unstable(feature = "derive_const", issue = "none")] | ||
pub fn is_const(&self) -> bool { | ||
bridge::client::FreeFunctions::is_derive_const() | ||
} | ||
} | ||
|
||
#[unstable(feature = "derive_const", issue = "none")] | ||
impl !Send for DeriveExpansionOptions {} | ||
#[unstable(feature = "derive_const", issue = "none")] | ||
impl !Sync for DeriveExpansionOptions {} | ||
Comment on lines
+111
to
+114
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for forward compatibility |
||
|
||
/// Error returned from `TokenStream::from_str`. | ||
#[stable(feature = "proc_macro_lib", since = "1.15.0")] | ||
#[non_exhaustive] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// force-host | ||
// no-prefer-dynamic | ||
#![crate_type = "proc-macro"] | ||
#![feature(derive_const)] | ||
|
||
extern crate proc_macro; | ||
|
||
use proc_macro::{TokenStream, DeriveExpansionOptions}; | ||
|
||
#[proc_macro_derive(IsDeriveConst)] | ||
pub fn is_derive_const(_: TokenStream, options: DeriveExpansionOptions) -> TokenStream { | ||
format!("const IS_DERIVE_CONST: bool = {};", options.is_const()).parse().unwrap() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// check-pass | ||
// edition: 2021 | ||
// aux-crate:is_derive_const=is-derive-const.rs | ||
#![feature(derive_const)] | ||
|
||
const _: () = { | ||
#[derive(is_derive_const::IsDeriveConst)] | ||
struct _Type; | ||
|
||
assert!(!IS_DERIVE_CONST); | ||
}; | ||
|
||
const _: () = { | ||
#[derive_const(is_derive_const::IsDeriveConst)] | ||
struct _Type; | ||
|
||
assert!(IS_DERIVE_CONST); | ||
}; | ||
|
||
fn main() {} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
// Check that we suggest *both* possible signatures of derive proc macros, namely | ||
// fn(TokenStream) -> TokenStream | ||
// and | ||
// fn(TokenStream, DeriveExpansionOptions) -> TokenStream | ||
// provided libs feature `derive_const` is enabled. | ||
|
||
// force-host | ||
// no-prefer-dynamic | ||
|
||
#![crate_type = "proc-macro"] | ||
#![feature(derive_const)] | ||
|
||
extern crate proc_macro; | ||
|
||
#[proc_macro_derive(Blah)] | ||
pub fn bad_input() -> proc_macro::TokenStream { | ||
//~^ ERROR derive proc macro has incorrect signature | ||
Default::default() | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
error: derive proc macro has incorrect signature | ||
--> $DIR/signature-proc-macro-derive.rs:16:1 | ||
| | ||
LL | pub fn bad_input() -> proc_macro::TokenStream { | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | | ||
| incorrect number of function parameters | ||
| incorrect number of function parameters | ||
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This duplication makes me sad but it's annoying to fix. I'd need to modify |
||
| | ||
= note: expected signature `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` | ||
found signature `fn() -> proc_macro::TokenStream` | ||
= note: expected signature `fn(proc_macro::TokenStream, DeriveExpansionOptions) -> proc_macro::TokenStream` | ||
found signature `fn() -> proc_macro::TokenStream` | ||
|
||
error: aborting due to 1 previous error | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I should actually be able to do:
or is it