feature(proc_macro) breaks attributes on custom derive (original) (raw)
Using #![feature(proc_macro)]
in combination with attributes enabled by #[proc_macro_derive(MyTrait, attributes(mycrate))]
(e.g. #[mycrate(some_option = "something")]
) fails to compile on the current nightly with error: macro undefined: 'mycrate!'
.
Definition of custom derive:
#![feature(proc_macro)]
use std::str::FromStr;
extern crate proc_macro; use proc_macro::TokenStream;
#[proc_macro_derive(MyTrait, attributes(mycrate))] pub fn my_macro(_: TokenStream) -> TokenStream { TokenStream::from_str("").unwrap() }
Use which fails:
#![feature(proc_macro)]
#[macro_use] extern crate proc_macro_collision;
#[derive(MyTrait)] #[mycrate(some_option = "something")] struct Foo;
fn main() { }
If #![feature(proc_macro)]
is removed, compilation succeeds.
Compiling the above fails with the following output:
error: macro undefined: 'mycrate!'
--> examples/with.rs:7:1
|
7 | #[mycrate(some_option = "something")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Compilation fails on current nightly:
$ rustc --version --verbose rustc 1.16.0-nightly (df8debf6d 2017-01-25) binary: rustc commit-hash: df8debf6d9afc431adbbd8311dcaf2b70eb9762e commit-date: 2017-01-25 host: x86_64-apple-darwin release: 1.16.0-nightly LLVM version: 3.9
However, compilation succeeds on a week old nightly:
$ rustc --version --verbose rustc 1.16.0-nightly (c07a6ae77 2017-01-17) binary: rustc commit-hash: c07a6ae77cd4ceb3cf591d34c5608ca91d1f75d4 commit-date: 2017-01-17 host: x86_64-apple-darwin release: 1.16.0-nightly LLVM version: 3.9
This is probably connected to #[proc_macro_attribute]
which was merged in this timeframe (PR), and not the feature flag itself.
serde_derive-based example failing the same way:
#![feature(proc_macro)]
#[macro_use] extern crate serde_derive;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)] #[serde(deny_unknown_fields)] struct Point { x: i32, y: i32, }
fn main() { let point = Point { x: 1, y: 2 };
// Convert the Point to a JSON string.
let serialized = serde_json::to_string(&point).unwrap();
// Prints serialized = {"x":1,"y":2}
println!("serialized = {}", serialized);
// Convert the JSON string back to a Point.
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// Prints deserialized = Point { x: 1, y: 2 }
println!("deserialized = {:?}", deserialized);
}