Skip to content

feature(proc_macro) breaks attributes on custom derive #39347

Closed
@evestera

Description

@evestera

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);
}

Metadata

Metadata

Assignees

Labels

A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions