mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-02 10:18:25 +00:00

Add infrastructure to apply a derive macro to arguments, consuming and returning a `TokenTree` only. Handle `SyntaxExtensionKind::MacroRules` when expanding a derive, if the macro's kinds support derive. Add tests covering various cases of `macro_rules` derives. Note that due to a pre-existing FIXME in `expand.rs`, derives are re-queued and some errors get emitted twice. Duplicate diagnostic suppression makes them not visible, but the FIXME should still get fixed.
52 lines
1.6 KiB
Rust
52 lines
1.6 KiB
Rust
#![feature(macro_derive)]
|
|
|
|
macro_rules! MyDerive {
|
|
derive() { $($body:tt)* } => {
|
|
compile_error!(concat!("MyDerive: ", stringify!($($body)*)));
|
|
};
|
|
//~^^ ERROR: MyDerive
|
|
}
|
|
|
|
macro_rules! fn_only {
|
|
//~^ NOTE: `fn_only` exists, but has no `derive` rules
|
|
//~| NOTE: `fn_only` exists, but has no `derive` rules
|
|
{} => {}
|
|
}
|
|
|
|
//~v NOTE: `DeriveOnly` exists, but has no rules for function-like invocation
|
|
macro_rules! DeriveOnly {
|
|
derive() {} => {}
|
|
}
|
|
|
|
fn main() {
|
|
//~v NOTE: in this expansion of #[derive(MyDerive)]
|
|
#[derive(MyDerive)]
|
|
struct S1;
|
|
|
|
//~vv ERROR: cannot find macro `MyDerive` in this scope
|
|
//~| NOTE: `MyDerive` is in scope, but it is a derive
|
|
MyDerive!(arg);
|
|
|
|
#[derive(fn_only)]
|
|
struct S2;
|
|
//~^^ ERROR: cannot find derive macro `fn_only` in this scope
|
|
//~| ERROR: cannot find derive macro `fn_only` in this scope
|
|
//~| NOTE: duplicate diagnostic emitted
|
|
|
|
DeriveOnly!(); //~ ERROR: cannot find macro `DeriveOnly` in this scope
|
|
}
|
|
|
|
#[derive(ForwardReferencedDerive)]
|
|
struct S;
|
|
//~^^ ERROR: cannot find derive macro `ForwardReferencedDerive` in this scope
|
|
//~| NOTE: consider moving the definition of `ForwardReferencedDerive` before this call
|
|
//~| ERROR: cannot find derive macro `ForwardReferencedDerive` in this scope
|
|
//~| NOTE: consider moving the definition of `ForwardReferencedDerive` before this call
|
|
//~| NOTE: duplicate diagnostic emitted
|
|
|
|
macro_rules! ForwardReferencedDerive {
|
|
//~^ NOTE: a macro with the same name exists, but it appears later
|
|
//~| NOTE: a macro with the same name exists, but it appears later
|
|
derive() {} => {}
|
|
}
|