From 2148bdfcc7ea7b9614d8cbe596cbe7bb75b57cd1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 3 Oct 2016 09:49:39 -0700 Subject: rustc: Rename rustc_macro to proc_macro This commit blanket renames the `rustc_macro` infrastructure to `proc_macro`, which reflects the general consensus of #35900. A follow up PR to Cargo will be required to purge the `rustc-macro` name as well. --- src/libproc_macro/Cargo.toml | 4 - src/libproc_macro/build.rs | 89 ---- src/libproc_macro/lib.rs | 250 ++++++----- src/libproc_macro/parse.rs | 26 -- src/libproc_macro/prelude.rs | 12 - src/libproc_macro/qquote.rs | 470 --------------------- src/libproc_macro_plugin/Cargo.toml | 14 + src/libproc_macro_plugin/build.rs | 89 ++++ src/libproc_macro_plugin/lib.rs | 137 ++++++ src/libproc_macro_plugin/parse.rs | 26 ++ src/libproc_macro_plugin/prelude.rs | 12 + src/libproc_macro_plugin/qquote.rs | 470 +++++++++++++++++++++ src/librustc/middle/dependency_format.rs | 6 +- src/librustc/middle/reachable.rs | 2 +- src/librustc/middle/weak_lang_items.rs | 2 +- src/librustc/session/config.rs | 10 +- src/librustc/ty/context.rs | 2 +- src/librustc_driver/Cargo.toml | 8 +- src/librustc_driver/driver.rs | 20 +- src/librustc_macro/Cargo.toml | 12 - src/librustc_macro/lib.rs | 169 -------- src/librustc_metadata/Cargo.toml | 2 +- src/librustc_metadata/creader.rs | 12 +- src/librustc_metadata/encoder.rs | 6 +- src/librustc_metadata/lib.rs | 12 +- src/librustc_metadata/macro_import.rs | 8 +- src/librustc_resolve/build_reduced_graph.rs | 4 +- src/librustc_trans/back/link.rs | 8 +- src/librustc_trans/back/linker.rs | 4 +- src/libsyntax/ext/expand.rs | 2 +- src/libsyntax/feature_gate.rs | 12 +- src/libsyntax_ext/Cargo.toml | 2 +- src/libsyntax_ext/deriving/custom.rs | 2 +- src/libsyntax_ext/lib.rs | 8 +- src/libsyntax_ext/proc_macro_registrar.rs | 277 ++++++++++++ src/libsyntax_ext/rustc_macro_registrar.rs | 277 ------------ src/rustc/Cargo.lock | 20 +- .../proc-macro/at-the-root.rs | 25 ++ .../compile-fail-fulldeps/proc-macro/attribute.rs | 46 ++ .../proc-macro/auxiliary/derive-a-2.rs | 25 ++ .../proc-macro/auxiliary/derive-a.rs | 25 ++ .../proc-macro/auxiliary/derive-bad.rs | 26 ++ .../proc-macro/auxiliary/derive-panic.rs | 25 ++ .../proc-macro/auxiliary/derive-unstable-2.rs | 29 ++ .../proc-macro/auxiliary/derive-unstable.rs | 26 ++ .../proc-macro/cannot-link.rs | 16 + .../compile-fail-fulldeps/proc-macro/define-two.rs | 28 ++ .../compile-fail-fulldeps/proc-macro/derive-bad.rs | 25 ++ .../proc-macro/derive-still-gated.rs | 22 + .../proc-macro/expand-to-unstable-2.rs | 25 ++ .../proc-macro/expand-to-unstable.rs | 25 ++ .../proc-macro/export-macro.rs | 19 + .../compile-fail-fulldeps/proc-macro/exports.rs | 22 + .../proc-macro/feature-gate-1.rs | 13 + .../proc-macro/feature-gate-2.rs | 13 + .../proc-macro/feature-gate-3.rs | 15 + .../proc-macro/feature-gate-4.rs | 15 + .../proc-macro/feature-gate-5.rs | 12 + .../compile-fail-fulldeps/proc-macro/import.rs | 22 + .../compile-fail-fulldeps/proc-macro/load-panic.rs | 23 + .../proc-macro/require-rustc-macro-crate-type.rs | 21 + .../proc-macro/shadow-builtin.rs | 22 + .../compile-fail-fulldeps/proc-macro/shadow.rs | 21 + .../compile-fail-fulldeps/proc-macro/signature.rs | 24 ++ .../proc-macro/two-crate-types-1.rs | 14 + .../proc-macro/two-crate-types-2.rs | 12 + .../rustc-macro/at-the-root.rs | 25 -- .../compile-fail-fulldeps/rustc-macro/attribute.rs | 46 -- .../rustc-macro/auxiliary/derive-a-2.rs | 25 -- .../rustc-macro/auxiliary/derive-a.rs | 25 -- .../rustc-macro/auxiliary/derive-bad.rs | 26 -- .../rustc-macro/auxiliary/derive-panic.rs | 25 -- .../rustc-macro/auxiliary/derive-unstable-2.rs | 29 -- .../rustc-macro/auxiliary/derive-unstable.rs | 26 -- .../rustc-macro/cannot-link.rs | 16 - .../rustc-macro/define-two.rs | 28 -- .../rustc-macro/derive-bad.rs | 25 -- .../rustc-macro/derive-still-gated.rs | 22 - .../rustc-macro/expand-to-unstable-2.rs | 25 -- .../rustc-macro/expand-to-unstable.rs | 25 -- .../rustc-macro/export-macro.rs | 19 - .../compile-fail-fulldeps/rustc-macro/exports.rs | 22 - .../rustc-macro/feature-gate-1.rs | 13 - .../rustc-macro/feature-gate-2.rs | 13 - .../rustc-macro/feature-gate-3.rs | 15 - .../rustc-macro/feature-gate-4.rs | 15 - .../rustc-macro/feature-gate-5.rs | 12 - .../compile-fail-fulldeps/rustc-macro/import.rs | 22 - .../rustc-macro/load-panic.rs | 23 - .../rustc-macro/require-rustc-macro-crate-type.rs | 21 - .../rustc-macro/shadow-builtin.rs | 22 - .../compile-fail-fulldeps/rustc-macro/shadow.rs | 21 - .../compile-fail-fulldeps/rustc-macro/signature.rs | 24 -- .../rustc-macro/two-crate-types-1.rs | 14 - .../rustc-macro/two-crate-types-2.rs | 12 - src/test/run-make/rustc-macro-dep-files/Makefile | 2 +- src/test/run-make/rustc-macro-dep-files/bar.rs | 2 +- src/test/run-make/rustc-macro-dep-files/foo.rs | 12 +- .../auxiliary/cond_noprelude_plugin.rs | 6 +- .../run-pass-fulldeps/auxiliary/cond_plugin.rs | 6 +- .../auxiliary/cond_prelude_plugin.rs | 6 +- .../run-pass-fulldeps/auxiliary/proc_macro_def.rs | 4 +- src/test/run-pass-fulldeps/macro-quote-1.rs | 6 +- src/test/run-pass-fulldeps/proc-macro/add-impl.rs | 25 ++ .../run-pass-fulldeps/proc-macro/append-impl.rs | 32 ++ .../proc-macro/auxiliary/add-impl.rs | 33 ++ .../proc-macro/auxiliary/append-impl.rs | 31 ++ .../proc-macro/auxiliary/derive-a.rs | 27 ++ .../proc-macro/auxiliary/derive-atob.rs | 26 ++ .../proc-macro/auxiliary/derive-ctod.rs | 26 ++ .../proc-macro/auxiliary/derive-same-struct.rs | 32 ++ .../proc-macro/auxiliary/expand-with-a-macro.rs | 36 ++ .../proc-macro/derive-same-struct.rs | 23 + .../proc-macro/expand-with-a-macro.rs | 30 ++ src/test/run-pass-fulldeps/proc-macro/load-two.rs | 30 ++ src/test/run-pass-fulldeps/proc-macro/smoke.rs | 29 ++ src/test/run-pass-fulldeps/rustc-macro/add-impl.rs | 25 -- .../run-pass-fulldeps/rustc-macro/append-impl.rs | 32 -- .../rustc-macro/auxiliary/add-impl.rs | 33 -- .../rustc-macro/auxiliary/append-impl.rs | 31 -- .../rustc-macro/auxiliary/derive-a.rs | 27 -- .../rustc-macro/auxiliary/derive-atob.rs | 26 -- .../rustc-macro/auxiliary/derive-ctod.rs | 26 -- .../rustc-macro/auxiliary/derive-same-struct.rs | 32 -- .../rustc-macro/auxiliary/expand-with-a-macro.rs | 36 -- .../rustc-macro/derive-same-struct.rs | 23 - .../rustc-macro/expand-with-a-macro.rs | 30 -- src/test/run-pass-fulldeps/rustc-macro/load-two.rs | 30 -- src/test/run-pass-fulldeps/rustc-macro/smoke.rs | 29 -- src/test/rustdoc/rustc-macro-crate.rs | 12 +- src/tools/cargotest/main.rs | 2 +- src/tools/tidy/src/cargo.rs | 8 +- 132 files changed, 2291 insertions(+), 2293 deletions(-) delete mode 100644 src/libproc_macro/build.rs delete mode 100644 src/libproc_macro/parse.rs delete mode 100644 src/libproc_macro/prelude.rs delete mode 100644 src/libproc_macro/qquote.rs create mode 100644 src/libproc_macro_plugin/Cargo.toml create mode 100644 src/libproc_macro_plugin/build.rs create mode 100644 src/libproc_macro_plugin/lib.rs create mode 100644 src/libproc_macro_plugin/parse.rs create mode 100644 src/libproc_macro_plugin/prelude.rs create mode 100644 src/libproc_macro_plugin/qquote.rs delete mode 100644 src/librustc_macro/Cargo.toml delete mode 100644 src/librustc_macro/lib.rs create mode 100644 src/libsyntax_ext/proc_macro_registrar.rs delete mode 100644 src/libsyntax_ext/rustc_macro_registrar.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/at-the-root.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/attribute.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-2.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-panic.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/cannot-link.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/define-two.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/export-macro.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/exports.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/feature-gate-1.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/feature-gate-2.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/feature-gate-3.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/feature-gate-4.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/feature-gate-5.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/import.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/load-panic.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/require-rustc-macro-crate-type.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/shadow.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/signature.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs create mode 100644 src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/at-the-root.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/attribute.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-a-2.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-a.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-bad.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-panic.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-unstable-2.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-unstable.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/cannot-link.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/define-two.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/derive-bad.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/derive-still-gated.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/expand-to-unstable-2.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/expand-to-unstable.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/export-macro.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/exports.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/feature-gate-1.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/feature-gate-2.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/feature-gate-3.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/feature-gate-4.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/feature-gate-5.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/import.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/load-panic.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/require-rustc-macro-crate-type.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/shadow-builtin.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/shadow.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/signature.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/two-crate-types-1.rs delete mode 100644 src/test/compile-fail-fulldeps/rustc-macro/two-crate-types-2.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/add-impl.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/append-impl.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/load-two.rs create mode 100644 src/test/run-pass-fulldeps/proc-macro/smoke.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/add-impl.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/append-impl.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/auxiliary/add-impl.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/auxiliary/append-impl.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-atob.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-ctod.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-same-struct.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/auxiliary/expand-with-a-macro.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/derive-same-struct.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/expand-with-a-macro.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/load-two.rs delete mode 100644 src/test/run-pass-fulldeps/rustc-macro/smoke.rs (limited to 'src') diff --git a/src/libproc_macro/Cargo.toml b/src/libproc_macro/Cargo.toml index 99fb1d65cda..7ce65d0fe4d 100644 --- a/src/libproc_macro/Cargo.toml +++ b/src/libproc_macro/Cargo.toml @@ -4,12 +4,8 @@ name = "proc_macro" version = "0.0.0" [lib] -name = "proc_macro" path = "lib.rs" crate-type = ["dylib"] [dependencies] -log = { path = "../liblog" } -rustc_plugin = { path = "../librustc_plugin" } syntax = { path = "../libsyntax" } -syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/libproc_macro/build.rs b/src/libproc_macro/build.rs deleted file mode 100644 index 7b7590b863b..00000000000 --- a/src/libproc_macro/build.rs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate syntax; -extern crate syntax_pos; - -use syntax::ast::Ident; -use syntax::codemap::DUMMY_SP; -use syntax::parse::token::{self, Token, keywords, str_to_ident}; -use syntax::tokenstream::{self, TokenTree, TokenStream}; -use std::rc::Rc; - -/// A wrapper around `TokenStream::concat` to avoid extra namespace specification and -/// provide TokenStream concatenation as a generic operator. -pub fn concat(ts1: TokenStream, ts2: TokenStream) -> TokenStream { - TokenStream::concat(ts1, ts2) -} - -/// Checks if two identifiers have the same name, disregarding context. This allows us to -/// fake 'reserved' keywords. -// FIXME We really want `free-identifier-=?` (a la Dybvig 1993). von Tander 2007 is -// probably the easiest way to do that. -pub fn ident_eq(tident: &TokenTree, id: Ident) -> bool { - let tid = match *tident { - TokenTree::Token(_, Token::Ident(ref id)) => id, - _ => { - return false; - } - }; - - tid.name == id.name -} - -// ____________________________________________________________________________________________ -// Conversion operators - -/// Convert a `&str` into a Token. -pub fn str_to_token_ident(s: &str) -> Token { - Token::Ident(str_to_ident(s)) -} - -/// Converts a keyword (from `syntax::parse::token::keywords`) into a Token that -/// corresponds to it. -pub fn keyword_to_token_ident(kw: keywords::Keyword) -> Token { - Token::Ident(str_to_ident(&kw.name().as_str()[..])) -} - -// ____________________________________________________________________________________________ -// Build Procedures - -/// Generically takes a `ts` and delimiter and returns `ts` delimited by the specified -/// delimiter. -pub fn build_delimited(ts: TokenStream, delim: token::DelimToken) -> TokenStream { - let tts = ts.to_tts(); - TokenStream::from_tts(vec![TokenTree::Delimited(DUMMY_SP, - Rc::new(tokenstream::Delimited { - delim: delim, - open_span: DUMMY_SP, - tts: tts, - close_span: DUMMY_SP, - }))]) -} - -/// Takes `ts` and returns `[ts]`. -pub fn build_bracket_delimited(ts: TokenStream) -> TokenStream { - build_delimited(ts, token::DelimToken::Bracket) -} - -/// Takes `ts` and returns `{ts}`. -pub fn build_brace_delimited(ts: TokenStream) -> TokenStream { - build_delimited(ts, token::DelimToken::Brace) -} - -/// Takes `ts` and returns `(ts)`. -pub fn build_paren_delimited(ts: TokenStream) -> TokenStream { - build_delimited(ts, token::DelimToken::Paren) -} - -/// Constructs `()`. -pub fn build_empty_args() -> TokenStream { - build_paren_delimited(TokenStream::mk_empty()) -} diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 9e25cb88e01..4b9b92fb3bb 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -8,130 +8,160 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! # Proc_Macro +//! A support library for macro authors when defining new macros. //! -//! A library for procedural macro writers. +//! This library, provided by the standard distribution, provides the types +//! consumed in the interfaces of procedurally defined macro definitions. +//! Currently the primary use of this crate is to provide the ability to define +//! new custom derive modes through `#[proc_macro_derive]`. //! -//! ## Usage -//! This package provides the `qquote!` macro for syntax creation, and the prelude -//! (at libproc_macro::prelude) provides a number of operations: -//! - `concat`, for concatenating two TokenStreams. -//! - `ident_eq`, for checking if two identifiers are equal regardless of syntax context. -//! - `str_to_token_ident`, for converting an `&str` into a Token. -//! - `keyword_to_token_delim`, for converting a `parse::token::keywords::Keyword` into a -//! Token. -//! - `build_delimited`, for creating a new TokenStream from an existing one and a delimiter -//! by wrapping the TokenStream in the delimiter. -//! - `build_bracket_delimited`, `build_brace_delimited`, and `build_paren_delimited`, for -//! easing the above. -//! - `build_empty_args`, which returns a TokenStream containing `()`. -//! - `lex`, which takes an `&str` and returns the TokenStream it represents. +//! Added recently as part of [RFC 1681] this crate is currently *unstable* and +//! requires the `#![feature(proc_macro_lib)]` directive to use. //! -//! The `qquote!` macro also imports `syntax::ext::proc_macro_shim::prelude::*`, so you -//! will need to `extern crate syntax` for usage. (This is a temporary solution until more -//! of the external API in libproc_macro is stabilized to support the token construction -//! operations that the qausiquoter relies on.) The shim file also provides additional -//! operations, such as `build_block_emitter` (as used in the `cond` example below). -//! -//! ## TokenStreams -//! -//! TokenStreams serve as the basis of the macro system. They are, in essence, vectors of -//! TokenTrees, where indexing treats delimited values as a single term. That is, the term -//! `even(a+c) && even(b)` will be indexibly encoded as `even | (a+c) | even | (b)` where, -//! in reality, `(a+c)` is actually a decorated pointer to `a | + | c`. -//! -//! If a user has a TokenStream that is a single, delimited value, they can use -//! `maybe_delimited` to destruct it and receive the internal vector as a new TokenStream -//! as: -//! ``` -//! `(a+c)`.maybe_delimited() ~> Some(a | + | c)` -//! ``` -//! -//! Check the TokenStream documentation for more information; the structure also provides -//! cheap concatenation and slicing. -//! -//! ## Quasiquotation -//! -//! The quasiquoter creates output that, when run, constructs the tokenstream specified as -//! input. For example, `qquote!(5 + 5)` will produce a program, that, when run, will -//! construct the TokenStream `5 | + | 5`. -//! -//! ### Unquoting -//! -//! Unquoting is currently done as `unquote`, and works by taking the single next -//! TokenTree in the TokenStream as the unquoted term. Ergonomically, `unquote(foo)` works -//! fine, but `unquote foo` is also supported. -//! -//! A simple example might be: -//! -//!``` -//!fn double(tmp: TokenStream) -> TokenStream { -//! qquote!(unquote(tmp) * 2) -//!} -//!``` -//! -//! ### Large Example: Implementing Scheme's `cond` -//! -//! Below is the full implementation of Scheme's `cond` operator. -//! -//! ``` -//! fn cond_rec(input: TokenStream) -> TokenStream { -//! if input.is_empty() { return quote!(); } -//! -//! let next = input.slice(0..1); -//! let rest = input.slice_from(1..); -//! -//! let clause : TokenStream = match next.maybe_delimited() { -//! Some(ts) => ts, -//! _ => panic!("Invalid input"), -//! }; -//! -//! // clause is ([test]) [rhs] -//! if clause.len() < 2 { panic!("Invalid macro usage in cond: {:?}", clause) } -//! -//! let test: TokenStream = clause.slice(0..1); -//! let rhs: TokenStream = clause.slice_from(1..); -//! -//! if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() { -//! quote!({unquote(rhs)}) -//! } else { -//! quote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } }) -//! } -//! } -//! ``` +//! [RFC 1681]: https://github.com/rust-lang/rfcs/blob/master/text/1681-macros-1.1.md //! +//! Note that this crate is intentionally very bare-bones currently. The main +//! type, `TokenStream`, only supports `fmt::Display` and `FromStr` +//! implementations, indicating that it can only go to and come from a string. +//! This functionality is intended to be expanded over time as more surface +//! area for macro authors is stabilized. #![crate_name = "proc_macro"] -#![unstable(feature = "rustc_private", issue = "27812")] -#![feature(plugin_registrar)] -#![crate_type = "dylib"] +#![unstable(feature = "proc_macro_lib", issue = "27812")] #![crate_type = "rlib"] -#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", - html_favicon_url = "https://doc.rust-lang.org/favicon.ico", - html_root_url = "https://doc.rust-lang.org/nightly/")] +#![crate_type = "dylib"] #![cfg_attr(not(stage0), deny(warnings))] +#![deny(missing_docs)] -#![feature(staged_api)] -#![feature(rustc_diagnostic_macros)] #![feature(rustc_private)] +#![feature(staged_api)] +#![feature(lang_items)] -extern crate rustc_plugin; extern crate syntax; -extern crate syntax_pos; -#[macro_use] extern crate log; -mod qquote; -pub mod build; -pub mod parse; -pub mod prelude; -use qquote::qquote; +use std::fmt; +use std::str::FromStr; + +use syntax::ast; +use syntax::parse; +use syntax::ptr::P; + +/// The main type provided by this crate, representing an abstract stream of +/// tokens. +/// +/// This is both the input and output of `#[proc_macro_derive]` definitions. +/// Currently it's required to be a list of valid Rust items, but this +/// restriction may be lifted in the future. +/// +/// The API of this type is intentionally bare-bones, but it'll be expanded over +/// time! +pub struct TokenStream { + inner: Vec>, +} + +/// Error returned from `TokenStream::from_str`. +#[derive(Debug)] +pub struct LexError { + _inner: (), +} + +/// Permanently unstable internal implementation details of this crate. This +/// should not be used. +/// +/// These methods are used by the rest of the compiler to generate instances of +/// `TokenStream` to hand to macro definitions, as well as consume the output. +/// +/// Note that this module is also intentionally separate from the rest of the +/// crate. This allows the `#[unstable]` directive below to naturally apply to +/// all of the contents. +#[unstable(feature = "proc_macro_internals", issue = "27812")] +#[doc(hidden)] +pub mod __internal { + use std::cell::Cell; + + use syntax::ast; + use syntax::ptr::P; + use syntax::parse::ParseSess; + use super::TokenStream; + + pub fn new_token_stream(item: P) -> TokenStream { + TokenStream { inner: vec![item] } + } -use rustc_plugin::Registry; + pub fn token_stream_items(stream: TokenStream) -> Vec> { + stream.inner + } -// ____________________________________________________________________________________________ -// Main macro definition + pub trait Registry { + fn register_custom_derive(&mut self, + trait_name: &str, + expand: fn(TokenStream) -> TokenStream); + } + + // Emulate scoped_thread_local!() here essentially + thread_local! { + static CURRENT_SESS: Cell<*const ParseSess> = Cell::new(0 as *const _); + } + + pub fn set_parse_sess(sess: &ParseSess, f: F) -> R + where F: FnOnce() -> R + { + struct Reset { prev: *const ParseSess } + + impl Drop for Reset { + fn drop(&mut self) { + CURRENT_SESS.with(|p| p.set(self.prev)); + } + } + + CURRENT_SESS.with(|p| { + let _reset = Reset { prev: p.get() }; + p.set(sess); + f() + }) + } + + pub fn with_parse_sess(f: F) -> R + where F: FnOnce(&ParseSess) -> R + { + let p = CURRENT_SESS.with(|p| p.get()); + assert!(!p.is_null()); + f(unsafe { &*p }) + } +} + +impl FromStr for TokenStream { + type Err = LexError; + + fn from_str(src: &str) -> Result { + __internal::with_parse_sess(|sess| { + let src = src.to_string(); + let cfg = Vec::new(); + let name = "".to_string(); + let mut parser = parse::new_parser_from_source_str(sess, cfg, name, + src); + let mut ret = TokenStream { inner: Vec::new() }; + loop { + match parser.parse_item() { + Ok(Some(item)) => ret.inner.push(item), + Ok(None) => return Ok(ret), + Err(mut err) => { + err.cancel(); + return Err(LexError { _inner: () }) + } + } + } + }) + } +} -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_macro("qquote", qquote); +impl fmt::Display for TokenStream { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + for item in self.inner.iter() { + let item = syntax::print::pprust::item_to_string(item); + try!(f.write_str(&item)); + try!(f.write_str("\n")); + } + Ok(()) + } } diff --git a/src/libproc_macro/parse.rs b/src/libproc_macro/parse.rs deleted file mode 100644 index 9af8a68cdcf..00000000000 --- a/src/libproc_macro/parse.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Parsing utilities for writing procedural macros. - -extern crate syntax; - -use syntax::parse::{ParseSess, filemap_to_tts}; -use syntax::tokenstream::TokenStream; - -/// Map a string to tts, using a made-up filename. For example, `lex(15)` will return a -/// TokenStream containing the literal 15. -pub fn lex(source_str: &str) -> TokenStream { - let ps = ParseSess::new(); - TokenStream::from_tts(filemap_to_tts(&ps, - ps.codemap().new_filemap("procmacro_lex".to_string(), - None, - source_str.to_owned()))) -} diff --git a/src/libproc_macro/prelude.rs b/src/libproc_macro/prelude.rs deleted file mode 100644 index 4c0c8ba6c66..00000000000 --- a/src/libproc_macro/prelude.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -pub use build::*; -pub use parse::*; diff --git a/src/libproc_macro/qquote.rs b/src/libproc_macro/qquote.rs deleted file mode 100644 index 67d0c77b00d..00000000000 --- a/src/libproc_macro/qquote.rs +++ /dev/null @@ -1,470 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! # Quasiquoter -//! This file contains the implementation internals of the quasiquoter provided by `quote!`. -//! -//! ## Ouput -//! The quasiquoter produces output of the form: -//! let tmp0 = ...; -//! let tmp1 = ...; -//! ... -//! concat(from_tokens(...), concat(...)) -//! -//! To the more explicit, the quasiquoter produces a series of bindings that each -//! construct TokenStreams via constructing Tokens and using `from_tokens`, ultimately -//! invoking `concat` on these bindings (and inlined expressions) to construct a -//! TokenStream that resembles the output syntax. -//! - -extern crate rustc_plugin; -extern crate syntax; -extern crate syntax_pos; - -use build::*; -use parse::lex; -use qquote::int_build::*; - -use syntax::ast::Ident; -use syntax::codemap::Span; -use syntax::ext::base::*; -use syntax::ext::base; -use syntax::ext::proc_macro_shim::build_block_emitter; -use syntax::parse::token::{self, Token, gensym_ident, str_to_ident}; -use syntax::print::pprust; -use syntax::tokenstream::{TokenTree, TokenStream}; - -// ____________________________________________________________________________________________ -// Main definition -/// The user should use the macro, not this procedure. -pub fn qquote<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree]) - -> Box { - - debug!("\nTTs in: {:?}\n", pprust::tts_to_string(&tts[..])); - let output = qquoter(cx, TokenStream::from_tts(tts.clone().to_owned())); - debug!("\nQQ out: {}\n", pprust::tts_to_string(&output.to_tts()[..])); - let imports = concat(lex("use syntax::ext::proc_macro_shim::prelude::*;"), - lex("use proc_macro::prelude::*;")); - build_block_emitter(cx, sp, build_brace_delimited(concat(imports, output))) -} - -// ____________________________________________________________________________________________ -// Datatype Definitions - -#[derive(Debug)] -struct QDelimited { - delim: token::DelimToken, - open_span: Span, - tts: Vec, - close_span: Span, -} - -#[derive(Debug)] -enum QTT { - TT(TokenTree), - QDL(QDelimited), - QIdent(TokenTree), -} - -type Bindings = Vec<(Ident, TokenStream)>; - -// ____________________________________________________________________________________________ -// Quasiquoter Algorithm -// This algorithm works as follows: -// Input: TokenStream -// 1. Walk the TokenStream, gathering up the unquoted expressions and marking them separately. -// 2. Hoist any unquoted term into its own let-binding via a gensym'd identifier -// 3. Convert the body from a `complex expression` into a simplified one via `convert_complex_tts -// 4. Stitch everything together with `concat`. -fn qquoter<'cx>(cx: &'cx mut ExtCtxt, ts: TokenStream) -> TokenStream { - if ts.is_empty() { - return lex("TokenStream::mk_empty()"); - } - let qq_res = qquote_iter(cx, 0, ts); - let mut bindings = qq_res.0; - let body = qq_res.1; - let mut cct_res = convert_complex_tts(cx, body); - - bindings.append(&mut cct_res.0); - - if bindings.is_empty() { - cct_res.1 - } else { - debug!("BINDINGS"); - for b in bindings.clone() { - debug!("{:?} = {}", b.0, pprust::tts_to_string(&b.1.to_tts()[..])); - } - TokenStream::concat(unravel(bindings), cct_res.1) - } -} - -fn qquote_iter<'cx>(cx: &'cx mut ExtCtxt, depth: i64, ts: TokenStream) -> (Bindings, Vec) { - let mut depth = depth; - let mut bindings: Bindings = Vec::new(); - let mut output: Vec = Vec::new(); - - let mut iter = ts.iter(); - - loop { - let next = iter.next(); - if next.is_none() { - break; - } - let next = next.unwrap().clone(); - match next { - TokenTree::Token(_, Token::Ident(id)) if is_unquote(id) => { - if depth == 0 { - let exp = iter.next(); - if exp.is_none() { - break; - } // produce an error or something first - let exp = vec![exp.unwrap().to_owned()]; - debug!("RHS: {:?}", exp.clone()); - let new_id = gensym_ident("tmp"); - debug!("RHS TS: {:?}", TokenStream::from_tts(exp.clone())); - debug!("RHS TS TT: {:?}", TokenStream::from_tts(exp.clone()).to_vec()); - bindings.push((new_id, TokenStream::from_tts(exp))); - debug!("BINDINGS"); - for b in bindings.clone() { - debug!("{:?} = {}", b.0, pprust::tts_to_string(&b.1.to_tts()[..])); - } - output.push(QTT::QIdent(as_tt(Token::Ident(new_id.clone())))); - } else { - depth = depth - 1; - output.push(QTT::TT(next.clone())); - } - } - TokenTree::Token(_, Token::Ident(id)) if is_qquote(id) => { - depth = depth + 1; - } - TokenTree::Delimited(_, ref dl) => { - let br = qquote_iter(cx, depth, TokenStream::from_tts(dl.tts.clone().to_owned())); - let mut bind_ = br.0; - let res_ = br.1; - bindings.append(&mut bind_); - - let new_dl = QDelimited { - delim: dl.delim, - open_span: dl.open_span, - tts: res_, - close_span: dl.close_span, - }; - - output.push(QTT::QDL(new_dl)); - } - t => { - output.push(QTT::TT(t)); - } - } - } - - (bindings, output) -} - -// ____________________________________________________________________________________________ -// Turns QQTs into a TokenStream and some Bindings. -/// Construct a chain of concatenations. -fn unravel_concats(tss: Vec) -> TokenStream { - let mut pushes: Vec = - tss.into_iter().filter(|&ref ts| !ts.is_empty()).collect(); - let mut output = match pushes.pop() { - Some(ts) => ts, - None => { - return TokenStream::mk_empty(); - } - }; - - while let Some(ts) = pushes.pop() { - output = build_fn_call(str_to_ident("concat"), - concat(concat(ts, - from_tokens(vec![Token::Comma])), - output)); - } - output -} - -/// This converts the vector of QTTs into a seet of Bindings for construction and the main -/// body as a TokenStream. -fn convert_complex_tts<'cx>(cx: &'cx mut ExtCtxt, tts: Vec) -> (Bindings, TokenStream) { - let mut pushes: Vec = Vec::new(); - let mut bindings: Bindings = Vec::new(); - - let mut iter = tts.into_iter(); - - loop { - let next = iter.next(); - if next.is_none() { - break; - } - let next = next.unwrap(); - match next { - QTT::TT(TokenTree::Token(_, t)) => { - let token_out = emit_token(t); - pushes.push(token_out); - } - // FIXME handle sequence repetition tokens - QTT::QDL(qdl) => { - debug!(" QDL: {:?} ", qdl.tts); - let new_id = gensym_ident("qdl_tmp"); - let mut cct_rec = convert_complex_tts(cx, qdl.tts); - bindings.append(&mut cct_rec.0); - bindings.push((new_id, cct_rec.1)); - - let sep = build_delim_tok(qdl.delim); - - pushes.push(build_mod_call(vec![str_to_ident("proc_macro"), - str_to_ident("build"), - str_to_ident("build_delimited")], - concat(from_tokens(vec![Token::Ident(new_id)]), - concat(lex(","), sep)))); - } - QTT::QIdent(t) => { - pushes.push(TokenStream::from_tts(vec![t])); - pushes.push(TokenStream::mk_empty()); - } - _ => panic!("Unhandled case!"), - } - - } - - (bindings, unravel_concats(pushes)) -} - -// ____________________________________________________________________________________________ -// Utilities - -/// Unravels Bindings into a TokenStream of `let` declarations. -fn unravel(binds: Bindings) -> TokenStream { - let mut output = TokenStream::mk_empty(); - - for b in binds { - output = concat(output, build_let(b.0, b.1)); - } - - output -} - -/// Checks if the Ident is `unquote`. -fn is_unquote(id: Ident) -> bool { - let qq = str_to_ident("unquote"); - id.name == qq.name // We disregard context; unquote is _reserved_ -} - -/// Checks if the Ident is `quote`. -fn is_qquote(id: Ident) -> bool { - let qq = str_to_ident("qquote"); - id.name == qq.name // We disregard context; qquote is _reserved_ -} - -mod int_build { - extern crate syntax; - extern crate syntax_pos; - - use parse::*; - use build::*; - - use syntax::ast::{self, Ident}; - use syntax::codemap::{DUMMY_SP}; - use syntax::parse::token::{self, Token, keywords, str_to_ident}; - use syntax::tokenstream::{TokenTree, TokenStream}; - - // ____________________________________________________________________________________________ - // Emitters - - pub fn emit_token(t: Token) -> TokenStream { - concat(lex("TokenStream::from_tokens"), - build_paren_delimited(build_vec(build_token_tt(t)))) - } - - pub fn emit_lit(l: token::Lit, n: Option) -> TokenStream { - let suf = match n { - Some(n) => format!("Some(ast::Name({}))", n.0), - None => "None".to_string(), - }; - - let lit = match l { - token::Lit::Byte(n) => format!("Lit::Byte(token::intern(\"{}\"))", n.to_string()), - token::Lit::Char(n) => format!("Lit::Char(token::intern(\"{}\"))", n.to_string()), - token::Lit::Integer(n) => format!("Lit::Integer(token::intern(\"{}\"))", n.to_string()), - token::Lit::Float(n) => format!("Lit::Float(token::intern(\"{}\"))", n.to_string()), - token::Lit::Str_(n) => format!("Lit::Str_(token::intern(\"{}\"))", n.to_string()), - token::Lit::ByteStr(n) => format!("Lit::ByteStr(token::intern(\"{}\"))", n.to_string()), - _ => panic!("Unsupported literal"), - }; - - let res = format!("Token::Literal({},{})", lit, suf); - debug!("{}", res); - lex(&res) - } - - // ____________________________________________________________________________________________ - // Token Builders - - pub fn build_binop_tok(bot: token::BinOpToken) -> TokenStream { - match bot { - token::BinOpToken::Plus => lex("Token::BinOp(BinOpToken::Plus)"), - token::BinOpToken::Minus => lex("Token::BinOp(BinOpToken::Minus)"), - token::BinOpToken::Star => lex("Token::BinOp(BinOpToken::Star)"), - token::BinOpToken::Slash => lex("Token::BinOp(BinOpToken::Slash)"), - token::BinOpToken::Percent => lex("Token::BinOp(BinOpToken::Percent)"), - token::BinOpToken::Caret => lex("Token::BinOp(BinOpToken::Caret)"), - token::BinOpToken::And => lex("Token::BinOp(BinOpToken::And)"), - token::BinOpToken::Or => lex("Token::BinOp(BinOpToken::Or)"), - token::BinOpToken::Shl => lex("Token::BinOp(BinOpToken::Shl)"), - token::BinOpToken::Shr => lex("Token::BinOp(BinOpToken::Shr)"), - } - } - - pub fn build_binopeq_tok(bot: token::BinOpToken) -> TokenStream { - match bot { - token::BinOpToken::Plus => lex("Token::BinOpEq(BinOpToken::Plus)"), - token::BinOpToken::Minus => lex("Token::BinOpEq(BinOpToken::Minus)"), - token::BinOpToken::Star => lex("Token::BinOpEq(BinOpToken::Star)"), - token::BinOpToken::Slash => lex("Token::BinOpEq(BinOpToken::Slash)"), - token::BinOpToken::Percent => lex("Token::BinOpEq(BinOpToken::Percent)"), - token::BinOpToken::Caret => lex("Token::BinOpEq(BinOpToken::Caret)"), - token::BinOpToken::And => lex("Token::BinOpEq(BinOpToken::And)"), - token::BinOpToken::Or => lex("Token::BinOpEq(BinOpToken::Or)"), - token::BinOpToken::Shl => lex("Token::BinOpEq(BinOpToken::Shl)"), - token::BinOpToken::Shr => lex("Token::BinOpEq(BinOpToken::Shr)"), - } - } - - pub fn build_delim_tok(dt: token::DelimToken) -> TokenStream { - match dt { - token::DelimToken::Paren => lex("DelimToken::Paren"), - token::DelimToken::Bracket => lex("DelimToken::Bracket"), - token::DelimToken::Brace => lex("DelimToken::Brace"), - token::DelimToken::NoDelim => lex("DelimToken::NoDelim"), - } - } - - pub fn build_token_tt(t: Token) -> TokenStream { - match t { - Token::Eq => lex("Token::Eq"), - Token::Lt => lex("Token::Lt"), - Token::Le => lex("Token::Le"), - Token::EqEq => lex("Token::EqEq"), - Token::Ne => lex("Token::Ne"), - Token::Ge => lex("Token::Ge"), - Token::Gt => lex("Token::Gt"), - Token::AndAnd => lex("Token::AndAnd"), - Token::OrOr => lex("Token::OrOr"), - Token::Not => lex("Token::Not"), - Token::Tilde => lex("Token::Tilde"), - Token::BinOp(tok) => build_binop_tok(tok), - Token::BinOpEq(tok) => build_binopeq_tok(tok), - Token::At => lex("Token::At"), - Token::Dot => lex("Token::Dot"), - Token::DotDot => lex("Token::DotDot"), - Token::DotDotDot => lex("Token::DotDotDot"), - Token::Comma => lex("Token::Comma"), - Token::Semi => lex("Token::Semi"), - Token::Colon => lex("Token::Colon"), - Token::ModSep => lex("Token::ModSep"), - Token::RArrow => lex("Token::RArrow"), - Token::LArrow => lex("Token::LArrow"), - Token::FatArrow => lex("Token::FatArrow"), - Token::Pound => lex("Token::Pound"), - Token::Dollar => lex("Token::Dollar"), - Token::Question => lex("Token::Question"), - Token::OpenDelim(dt) => { - match dt { - token::DelimToken::Paren => lex("Token::OpenDelim(DelimToken::Paren)"), - token::DelimToken::Bracket => lex("Token::OpenDelim(DelimToken::Bracket)"), - token::DelimToken::Brace => lex("Token::OpenDelim(DelimToken::Brace)"), - token::DelimToken::NoDelim => lex("DelimToken::NoDelim"), - } - } - Token::CloseDelim(dt) => { - match dt { - token::DelimToken::Paren => lex("Token::CloseDelim(DelimToken::Paren)"), - token::DelimToken::Bracket => lex("Token::CloseDelim(DelimToken::Bracket)"), - token::DelimToken::Brace => lex("Token::CloseDelim(DelimToken::Brace)"), - token::DelimToken::NoDelim => lex("DelimToken::NoDelim"), - } - } - Token::Underscore => lex("_"), - Token::Literal(lit, sfx) => emit_lit(lit, sfx), - // fix ident expansion information... somehow - Token::Ident(ident) => lex(&format!("Token::Ident(str_to_ident(\"{}\"))", ident.name)), - Token::Lifetime(ident) => lex(&format!("Token::Ident(str_to_ident(\"{}\"))", - ident.name)), - _ => panic!("Unhandled case!"), - } - } - - // ____________________________________________________________________________________________ - // Conversion operators - - pub fn as_tt(t: Token) -> TokenTree { - // FIXME do something nicer with the spans - TokenTree::Token(DUMMY_SP, t) - } - - // ____________________________________________________________________________________________ - // Build Procedures - - /// Takes `input` and returns `vec![input]`. - pub fn build_vec(ts: TokenStream) -> TokenStream { - build_mac_call(str_to_ident("vec"), ts) - // tts.clone().to_owned() - } - - /// Takes `ident` and `rhs` and produces `let ident = rhs;`. - pub fn build_let(id: Ident, tts: TokenStream) -> TokenStream { - concat(from_tokens(vec![keyword_to_token_ident(keywords::Let), - Token::Ident(id), - Token::Eq]), - concat(tts, from_tokens(vec![Token::Semi]))) - } - - /// Takes `ident ...`, and `args ...` and produces `ident::...(args ...)`. - pub fn build_mod_call(ids: Vec, args: TokenStream) -> TokenStream { - let call = from_tokens(intersperse(ids.into_iter().map(|id| Token::Ident(id)).collect(), - Token::ModSep)); - concat(call, build_paren_delimited(args)) - } - - /// Takes `ident` and `args ...` and produces `ident(args ...)`. - pub fn build_fn_call(name: Ident, args: TokenStream) -> TokenStream { - concat(from_tokens(vec![Token::Ident(name)]), build_paren_delimited(args)) - } - - /// Takes `ident` and `args ...` and produces `ident!(args ...)`. - pub fn build_mac_call(name: Ident, args: TokenStream) -> TokenStream { - concat(from_tokens(vec![Token::Ident(name), Token::Not]), - build_paren_delimited(args)) - } - - // ____________________________________________________________________________________________ - // Utilities - - /// A wrapper around `TokenStream::from_tokens` to avoid extra namespace specification and - /// provide it as a generic operator. - pub fn from_tokens(tokens: Vec) -> TokenStream { - TokenStream::from_tokens(tokens) - } - - pub fn intersperse(vs: Vec, t: T) -> Vec - where T: Clone - { - if vs.len() < 2 { - return vs; - } - let mut output = vec![vs.get(0).unwrap().to_owned()]; - - for v in vs.into_iter().skip(1) { - output.push(t.clone()); - output.push(v); - } - output - } -} diff --git a/src/libproc_macro_plugin/Cargo.toml b/src/libproc_macro_plugin/Cargo.toml new file mode 100644 index 00000000000..70bb86d0f58 --- /dev/null +++ b/src/libproc_macro_plugin/Cargo.toml @@ -0,0 +1,14 @@ +[package] +authors = ["The Rust Project Developers"] +name = "proc_macro_plugin" +version = "0.0.0" + +[lib] +path = "lib.rs" +crate-type = ["dylib"] + +[dependencies] +log = { path = "../liblog" } +rustc_plugin = { path = "../librustc_plugin" } +syntax = { path = "../libsyntax" } +syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/libproc_macro_plugin/build.rs b/src/libproc_macro_plugin/build.rs new file mode 100644 index 00000000000..7b7590b863b --- /dev/null +++ b/src/libproc_macro_plugin/build.rs @@ -0,0 +1,89 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate syntax; +extern crate syntax_pos; + +use syntax::ast::Ident; +use syntax::codemap::DUMMY_SP; +use syntax::parse::token::{self, Token, keywords, str_to_ident}; +use syntax::tokenstream::{self, TokenTree, TokenStream}; +use std::rc::Rc; + +/// A wrapper around `TokenStream::concat` to avoid extra namespace specification and +/// provide TokenStream concatenation as a generic operator. +pub fn concat(ts1: TokenStream, ts2: TokenStream) -> TokenStream { + TokenStream::concat(ts1, ts2) +} + +/// Checks if two identifiers have the same name, disregarding context. This allows us to +/// fake 'reserved' keywords. +// FIXME We really want `free-identifier-=?` (a la Dybvig 1993). von Tander 2007 is +// probably the easiest way to do that. +pub fn ident_eq(tident: &TokenTree, id: Ident) -> bool { + let tid = match *tident { + TokenTree::Token(_, Token::Ident(ref id)) => id, + _ => { + return false; + } + }; + + tid.name == id.name +} + +// ____________________________________________________________________________________________ +// Conversion operators + +/// Convert a `&str` into a Token. +pub fn str_to_token_ident(s: &str) -> Token { + Token::Ident(str_to_ident(s)) +} + +/// Converts a keyword (from `syntax::parse::token::keywords`) into a Token that +/// corresponds to it. +pub fn keyword_to_token_ident(kw: keywords::Keyword) -> Token { + Token::Ident(str_to_ident(&kw.name().as_str()[..])) +} + +// ____________________________________________________________________________________________ +// Build Procedures + +/// Generically takes a `ts` and delimiter and returns `ts` delimited by the specified +/// delimiter. +pub fn build_delimited(ts: TokenStream, delim: token::DelimToken) -> TokenStream { + let tts = ts.to_tts(); + TokenStream::from_tts(vec![TokenTree::Delimited(DUMMY_SP, + Rc::new(tokenstream::Delimited { + delim: delim, + open_span: DUMMY_SP, + tts: tts, + close_span: DUMMY_SP, + }))]) +} + +/// Takes `ts` and returns `[ts]`. +pub fn build_bracket_delimited(ts: TokenStream) -> TokenStream { + build_delimited(ts, token::DelimToken::Bracket) +} + +/// Takes `ts` and returns `{ts}`. +pub fn build_brace_delimited(ts: TokenStream) -> TokenStream { + build_delimited(ts, token::DelimToken::Brace) +} + +/// Takes `ts` and returns `(ts)`. +pub fn build_paren_delimited(ts: TokenStream) -> TokenStream { + build_delimited(ts, token::DelimToken::Paren) +} + +/// Constructs `()`. +pub fn build_empty_args() -> TokenStream { + build_paren_delimited(TokenStream::mk_empty()) +} diff --git a/src/libproc_macro_plugin/lib.rs b/src/libproc_macro_plugin/lib.rs new file mode 100644 index 00000000000..e82e97b5134 --- /dev/null +++ b/src/libproc_macro_plugin/lib.rs @@ -0,0 +1,137 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! # Proc_Macro +//! +//! A library for procedural macro writers. +//! +//! ## Usage +//! This package provides the `qquote!` macro for syntax creation, and the prelude +//! (at libproc_macro::prelude) provides a number of operations: +//! - `concat`, for concatenating two TokenStreams. +//! - `ident_eq`, for checking if two identifiers are equal regardless of syntax context. +//! - `str_to_token_ident`, for converting an `&str` into a Token. +//! - `keyword_to_token_delim`, for converting a `parse::token::keywords::Keyword` into a +//! Token. +//! - `build_delimited`, for creating a new TokenStream from an existing one and a delimiter +//! by wrapping the TokenStream in the delimiter. +//! - `build_bracket_delimited`, `build_brace_delimited`, and `build_paren_delimited`, for +//! easing the above. +//! - `build_empty_args`, which returns a TokenStream containing `()`. +//! - `lex`, which takes an `&str` and returns the TokenStream it represents. +//! +//! The `qquote!` macro also imports `syntax::ext::proc_macro_shim::prelude::*`, so you +//! will need to `extern crate syntax` for usage. (This is a temporary solution until more +//! of the external API in libproc_macro is stabilized to support the token construction +//! operations that the qausiquoter relies on.) The shim file also provides additional +//! operations, such as `build_block_emitter` (as used in the `cond` example below). +//! +//! ## TokenStreams +//! +//! TokenStreams serve as the basis of the macro system. They are, in essence, vectors of +//! TokenTrees, where indexing treats delimited values as a single term. That is, the term +//! `even(a+c) && even(b)` will be indexibly encoded as `even | (a+c) | even | (b)` where, +//! in reality, `(a+c)` is actually a decorated pointer to `a | + | c`. +//! +//! If a user has a TokenStream that is a single, delimited value, they can use +//! `maybe_delimited` to destruct it and receive the internal vector as a new TokenStream +//! as: +//! ``` +//! `(a+c)`.maybe_delimited() ~> Some(a | + | c)` +//! ``` +//! +//! Check the TokenStream documentation for more information; the structure also provides +//! cheap concatenation and slicing. +//! +//! ## Quasiquotation +//! +//! The quasiquoter creates output that, when run, constructs the tokenstream specified as +//! input. For example, `qquote!(5 + 5)` will produce a program, that, when run, will +//! construct the TokenStream `5 | + | 5`. +//! +//! ### Unquoting +//! +//! Unquoting is currently done as `unquote`, and works by taking the single next +//! TokenTree in the TokenStream as the unquoted term. Ergonomically, `unquote(foo)` works +//! fine, but `unquote foo` is also supported. +//! +//! A simple example might be: +//! +//!``` +//!fn double(tmp: TokenStream) -> TokenStream { +//! qquote!(unquote(tmp) * 2) +//!} +//!``` +//! +//! ### Large Example: Implementing Scheme's `cond` +//! +//! Below is the full implementation of Scheme's `cond` operator. +//! +//! ``` +//! fn cond_rec(input: TokenStream) -> TokenStream { +//! if input.is_empty() { return quote!(); } +//! +//! let next = input.slice(0..1); +//! let rest = input.slice_from(1..); +//! +//! let clause : TokenStream = match next.maybe_delimited() { +//! Some(ts) => ts, +//! _ => panic!("Invalid input"), +//! }; +//! +//! // clause is ([test]) [rhs] +//! if clause.len() < 2 { panic!("Invalid macro usage in cond: {:?}", clause) } +//! +//! let test: TokenStream = clause.slice(0..1); +//! let rhs: TokenStream = clause.slice_from(1..); +//! +//! if ident_eq(&test[0], str_to_ident("else")) || rest.is_empty() { +//! quote!({unquote(rhs)}) +//! } else { +//! quote!({if unquote(test) { unquote(rhs) } else { cond!(unquote(rest)) } }) +//! } +//! } +//! ``` +//! + +#![crate_name = "proc_macro_plugin"] +#![unstable(feature = "rustc_private", issue = "27812")] +#![feature(plugin_registrar)] +#![crate_type = "dylib"] +#![crate_type = "rlib"] +#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", + html_favicon_url = "https://doc.rust-lang.org/favicon.ico", + html_root_url = "https://doc.rust-lang.org/nightly/")] +#![cfg_attr(not(stage0), deny(warnings))] + +#![feature(staged_api)] +#![feature(rustc_diagnostic_macros)] +#![feature(rustc_private)] + +extern crate rustc_plugin; +extern crate syntax; +extern crate syntax_pos; +#[macro_use] extern crate log; + +mod qquote; +pub mod build; +pub mod parse; +pub mod prelude; +use qquote::qquote; + +use rustc_plugin::Registry; + +// ____________________________________________________________________________________________ +// Main macro definition + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("qquote", qquote); +} diff --git a/src/libproc_macro_plugin/parse.rs b/src/libproc_macro_plugin/parse.rs new file mode 100644 index 00000000000..9af8a68cdcf --- /dev/null +++ b/src/libproc_macro_plugin/parse.rs @@ -0,0 +1,26 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Parsing utilities for writing procedural macros. + +extern crate syntax; + +use syntax::parse::{ParseSess, filemap_to_tts}; +use syntax::tokenstream::TokenStream; + +/// Map a string to tts, using a made-up filename. For example, `lex(15)` will return a +/// TokenStream containing the literal 15. +pub fn lex(source_str: &str) -> TokenStream { + let ps = ParseSess::new(); + TokenStream::from_tts(filemap_to_tts(&ps, + ps.codemap().new_filemap("procmacro_lex".to_string(), + None, + source_str.to_owned()))) +} diff --git a/src/libproc_macro_plugin/prelude.rs b/src/libproc_macro_plugin/prelude.rs new file mode 100644 index 00000000000..4c0c8ba6c66 --- /dev/null +++ b/src/libproc_macro_plugin/prelude.rs @@ -0,0 +1,12 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub use build::*; +pub use parse::*; diff --git a/src/libproc_macro_plugin/qquote.rs b/src/libproc_macro_plugin/qquote.rs new file mode 100644 index 00000000000..b73d085656e --- /dev/null +++ b/src/libproc_macro_plugin/qquote.rs @@ -0,0 +1,470 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! # Quasiquoter +//! This file contains the implementation internals of the quasiquoter provided by `quote!`. +//! +//! ## Ouput +//! The quasiquoter produces output of the form: +//! let tmp0 = ...; +//! let tmp1 = ...; +//! ... +//! concat(from_tokens(...), concat(...)) +//! +//! To the more explicit, the quasiquoter produces a series of bindings that each +//! construct TokenStreams via constructing Tokens and using `from_tokens`, ultimately +//! invoking `concat` on these bindings (and inlined expressions) to construct a +//! TokenStream that resembles the output syntax. +//! + +extern crate rustc_plugin; +extern crate syntax; +extern crate syntax_pos; + +use build::*; +use parse::lex; +use qquote::int_build::*; + +use syntax::ast::Ident; +use syntax::codemap::Span; +use syntax::ext::base::*; +use syntax::ext::base; +use syntax::ext::proc_macro_shim::build_block_emitter; +use syntax::parse::token::{self, Token, gensym_ident, str_to_ident}; +use syntax::print::pprust; +use syntax::tokenstream::{TokenTree, TokenStream}; + +// ____________________________________________________________________________________________ +// Main definition +/// The user should use the macro, not this procedure. +pub fn qquote<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree]) + -> Box { + + debug!("\nTTs in: {:?}\n", pprust::tts_to_string(&tts[..])); + let output = qquoter(cx, TokenStream::from_tts(tts.clone().to_owned())); + debug!("\nQQ out: {}\n", pprust::tts_to_string(&output.to_tts()[..])); + let imports = concat(lex("use syntax::ext::proc_macro_shim::prelude::*;"), + lex("use proc_macro_plugin::prelude::*;")); + build_block_emitter(cx, sp, build_brace_delimited(concat(imports, output))) +} + +// ____________________________________________________________________________________________ +// Datatype Definitions + +#[derive(Debug)] +struct QDelimited { + delim: token::DelimToken, + open_span: Span, + tts: Vec, + close_span: Span, +} + +#[derive(Debug)] +enum QTT { + TT(TokenTree), + QDL(QDelimited), + QIdent(TokenTree), +} + +type Bindings = Vec<(Ident, TokenStream)>; + +// ____________________________________________________________________________________________ +// Quasiquoter Algorithm +// This algorithm works as follows: +// Input: TokenStream +// 1. Walk the TokenStream, gathering up the unquoted expressions and marking them separately. +// 2. Hoist any unquoted term into its own let-binding via a gensym'd identifier +// 3. Convert the body from a `complex expression` into a simplified one via `convert_complex_tts +// 4. Stitch everything together with `concat`. +fn qquoter<'cx>(cx: &'cx mut ExtCtxt, ts: TokenStream) -> TokenStream { + if ts.is_empty() { + return lex("TokenStream::mk_empty()"); + } + let qq_res = qquote_iter(cx, 0, ts); + let mut bindings = qq_res.0; + let body = qq_res.1; + let mut cct_res = convert_complex_tts(cx, body); + + bindings.append(&mut cct_res.0); + + if bindings.is_empty() { + cct_res.1 + } else { + debug!("BINDINGS"); + for b in bindings.clone() { + debug!("{:?} = {}", b.0, pprust::tts_to_string(&b.1.to_tts()[..])); + } + TokenStream::concat(unravel(bindings), cct_res.1) + } +} + +fn qquote_iter<'cx>(cx: &'cx mut ExtCtxt, depth: i64, ts: TokenStream) -> (Bindings, Vec) { + let mut depth = depth; + let mut bindings: Bindings = Vec::new(); + let mut output: Vec = Vec::new(); + + let mut iter = ts.iter(); + + loop { + let next = iter.next(); + if next.is_none() { + break; + } + let next = next.unwrap().clone(); + match next { + TokenTree::Token(_, Token::Ident(id)) if is_unquote(id) => { + if depth == 0 { + let exp = iter.next(); + if exp.is_none() { + break; + } // produce an error or something first + let exp = vec![exp.unwrap().to_owned()]; + debug!("RHS: {:?}", exp.clone()); + let new_id = gensym_ident("tmp"); + debug!("RHS TS: {:?}", TokenStream::from_tts(exp.clone())); + debug!("RHS TS TT: {:?}", TokenStream::from_tts(exp.clone()).to_vec()); + bindings.push((new_id, TokenStream::from_tts(exp))); + debug!("BINDINGS"); + for b in bindings.clone() { + debug!("{:?} = {}", b.0, pprust::tts_to_string(&b.1.to_tts()[..])); + } + output.push(QTT::QIdent(as_tt(Token::Ident(new_id.clone())))); + } else { + depth = depth - 1; + output.push(QTT::TT(next.clone())); + } + } + TokenTree::Token(_, Token::Ident(id)) if is_qquote(id) => { + depth = depth + 1; + } + TokenTree::Delimited(_, ref dl) => { + let br = qquote_iter(cx, depth, TokenStream::from_tts(dl.tts.clone().to_owned())); + let mut bind_ = br.0; + let res_ = br.1; + bindings.append(&mut bind_); + + let new_dl = QDelimited { + delim: dl.delim, + open_span: dl.open_span, + tts: res_, + close_span: dl.close_span, + }; + + output.push(QTT::QDL(new_dl)); + } + t => { + output.push(QTT::TT(t)); + } + } + } + + (bindings, output) +} + +// ____________________________________________________________________________________________ +// Turns QQTs into a TokenStream and some Bindings. +/// Construct a chain of concatenations. +fn unravel_concats(tss: Vec) -> TokenStream { + let mut pushes: Vec = + tss.into_iter().filter(|&ref ts| !ts.is_empty()).collect(); + let mut output = match pushes.pop() { + Some(ts) => ts, + None => { + return TokenStream::mk_empty(); + } + }; + + while let Some(ts) = pushes.pop() { + output = build_fn_call(str_to_ident("concat"), + concat(concat(ts, + from_tokens(vec![Token::Comma])), + output)); + } + output +} + +/// This converts the vector of QTTs into a seet of Bindings for construction and the main +/// body as a TokenStream. +fn convert_complex_tts<'cx>(cx: &'cx mut ExtCtxt, tts: Vec) -> (Bindings, TokenStream) { + let mut pushes: Vec = Vec::new(); + let mut bindings: Bindings = Vec::new(); + + let mut iter = tts.into_iter(); + + loop { + let next = iter.next(); + if next.is_none() { + break; + } + let next = next.unwrap(); + match next { + QTT::TT(TokenTree::Token(_, t)) => { + let token_out = emit_token(t); + pushes.push(token_out); + } + // FIXME handle sequence repetition tokens + QTT::QDL(qdl) => { + debug!(" QDL: {:?} ", qdl.tts); + let new_id = gensym_ident("qdl_tmp"); + let mut cct_rec = convert_complex_tts(cx, qdl.tts); + bindings.append(&mut cct_rec.0); + bindings.push((new_id, cct_rec.1)); + + let sep = build_delim_tok(qdl.delim); + + pushes.push(build_mod_call(vec![str_to_ident("proc_macro_plugin"), + str_to_ident("build"), + str_to_ident("build_delimited")], + concat(from_tokens(vec![Token::Ident(new_id)]), + concat(lex(","), sep)))); + } + QTT::QIdent(t) => { + pushes.push(TokenStream::from_tts(vec![t])); + pushes.push(TokenStream::mk_empty()); + } + _ => panic!("Unhandled case!"), + } + + } + + (bindings, unravel_concats(pushes)) +} + +// ____________________________________________________________________________________________ +// Utilities + +/// Unravels Bindings into a TokenStream of `let` declarations. +fn unravel(binds: Bindings) -> TokenStream { + let mut output = TokenStream::mk_empty(); + + for b in binds { + output = concat(output, build_let(b.0, b.1)); + } + + output +} + +/// Checks if the Ident is `unquote`. +fn is_unquote(id: Ident) -> bool { + let qq = str_to_ident("unquote"); + id.name == qq.name // We disregard context; unquote is _reserved_ +} + +/// Checks if the Ident is `quote`. +fn is_qquote(id: Ident) -> bool { + let qq = str_to_ident("qquote"); + id.name == qq.name // We disregard context; qquote is _reserved_ +} + +mod int_build { + extern crate syntax; + extern crate syntax_pos; + + use parse::*; + use build::*; + + use syntax::ast::{self, Ident}; + use syntax::codemap::{DUMMY_SP}; + use syntax::parse::token::{self, Token, keywords, str_to_ident}; + use syntax::tokenstream::{TokenTree, TokenStream}; + + // ____________________________________________________________________________________________ + // Emitters + + pub fn emit_token(t: Token) -> TokenStream { + concat(lex("TokenStream::from_tokens"), + build_paren_delimited(build_vec(build_token_tt(t)))) + } + + pub fn emit_lit(l: token::Lit, n: Option) -> TokenStream { + let suf = match n { + Some(n) => format!("Some(ast::Name({}))", n.0), + None => "None".to_string(), + }; + + let lit = match l { + token::Lit::Byte(n) => format!("Lit::Byte(token::intern(\"{}\"))", n.to_string()), + token::Lit::Char(n) => format!("Lit::Char(token::intern(\"{}\"))", n.to_string()), + token::Lit::Integer(n) => format!("Lit::Integer(token::intern(\"{}\"))", n.to_string()), + token::Lit::Float(n) => format!("Lit::Float(token::intern(\"{}\"))", n.to_string()), + token::Lit::Str_(n) => format!("Lit::Str_(token::intern(\"{}\"))", n.to_string()), + token::Lit::ByteStr(n) => format!("Lit::ByteStr(token::intern(\"{}\"))", n.to_string()), + _ => panic!("Unsupported literal"), + }; + + let res = format!("Token::Literal({},{})", lit, suf); + debug!("{}", res); + lex(&res) + } + + // ____________________________________________________________________________________________ + // Token Builders + + pub fn build_binop_tok(bot: token::BinOpToken) -> TokenStream { + match bot { + token::BinOpToken::Plus => lex("Token::BinOp(BinOpToken::Plus)"), + token::BinOpToken::Minus => lex("Token::BinOp(BinOpToken::Minus)"), + token::BinOpToken::Star => lex("Token::BinOp(BinOpToken::Star)"), + token::BinOpToken::Slash => lex("Token::BinOp(BinOpToken::Slash)"), + token::BinOpToken::Percent => lex("Token::BinOp(BinOpToken::Percent)"), + token::BinOpToken::Caret => lex("Token::BinOp(BinOpToken::Caret)"), + token::BinOpToken::And => lex("Token::BinOp(BinOpToken::And)"), + token::BinOpToken::Or => lex("Token::BinOp(BinOpToken::Or)"), + token::BinOpToken::Shl => lex("Token::BinOp(BinOpToken::Shl)"), + token::BinOpToken::Shr => lex("Token::BinOp(BinOpToken::Shr)"), + } + } + + pub fn build_binopeq_tok(bot: token::BinOpToken) -> TokenStream { + match bot { + token::BinOpToken::Plus => lex("Token::BinOpEq(BinOpToken::Plus)"), + token::BinOpToken::Minus => lex("Token::BinOpEq(BinOpToken::Minus)"), + token::BinOpToken::Star => lex("Token::BinOpEq(BinOpToken::Star)"), + token::BinOpToken::Slash => lex("Token::BinOpEq(BinOpToken::Slash)"), + token::BinOpToken::Percent => lex("Token::BinOpEq(BinOpToken::Percent)"), + token::BinOpToken::Caret => lex("Token::BinOpEq(BinOpToken::Caret)"), + token::BinOpToken::And => lex("Token::BinOpEq(BinOpToken::And)"), + token::BinOpToken::Or => lex("Token::BinOpEq(BinOpToken::Or)"), + token::BinOpToken::Shl => lex("Token::BinOpEq(BinOpToken::Shl)"), + token::BinOpToken::Shr => lex("Token::BinOpEq(BinOpToken::Shr)"), + } + } + + pub fn build_delim_tok(dt: token::DelimToken) -> TokenStream { + match dt { + token::DelimToken::Paren => lex("DelimToken::Paren"), + token::DelimToken::Bracket => lex("DelimToken::Bracket"), + token::DelimToken::Brace => lex("DelimToken::Brace"), + token::DelimToken::NoDelim => lex("DelimToken::NoDelim"), + } + } + + pub fn build_token_tt(t: Token) -> TokenStream { + match t { + Token::Eq => lex("Token::Eq"), + Token::Lt => lex("Token::Lt"), + Token::Le => lex("Token::Le"), + Token::EqEq => lex("Token::EqEq"), + Token::Ne => lex("Token::Ne"), + Token::Ge => lex("Token::Ge"), + Token::Gt => lex("Token::Gt"), + Token::AndAnd => lex("Token::AndAnd"), + Token::OrOr => lex("Token::OrOr"), + Token::Not => lex("Token::Not"), + Token::Tilde => lex("Token::Tilde"), + Token::BinOp(tok) => build_binop_tok(tok), + Token::BinOpEq(tok) => build_binopeq_tok(tok), + Token::At => lex("Token::At"), + Token::Dot => lex("Token::Dot"), + Token::DotDot => lex("Token::DotDot"), + Token::DotDotDot => lex("Token::DotDotDot"), + Token::Comma => lex("Token::Comma"), + Token::Semi => lex("Token::Semi"), + Token::Colon => lex("Token::Colon"), + Token::ModSep => lex("Token::ModSep"), + Token::RArrow => lex("Token::RArrow"), + Token::LArrow => lex("Token::LArrow"), + Token::FatArrow => lex("Token::FatArrow"), + Token::Pound => lex("Token::Pound"), + Token::Dollar => lex("Token::Dollar"), + Token::Question => lex("Token::Question"), + Token::OpenDelim(dt) => { + match dt { + token::DelimToken::Paren => lex("Token::OpenDelim(DelimToken::Paren)"), + token::DelimToken::Bracket => lex("Token::OpenDelim(DelimToken::Bracket)"), + token::DelimToken::Brace => lex("Token::OpenDelim(DelimToken::Brace)"), + token::DelimToken::NoDelim => lex("DelimToken::NoDelim"), + } + } + Token::CloseDelim(dt) => { + match dt { + token::DelimToken::Paren => lex("Token::CloseDelim(DelimToken::Paren)"), + token::DelimToken::Bracket => lex("Token::CloseDelim(DelimToken::Bracket)"), + token::DelimToken::Brace => lex("Token::CloseDelim(DelimToken::Brace)"), + token::DelimToken::NoDelim => lex("DelimToken::NoDelim"), + } + } + Token::Underscore => lex("_"), + Token::Literal(lit, sfx) => emit_lit(lit, sfx), + // fix ident expansion information... somehow + Token::Ident(ident) => lex(&format!("Token::Ident(str_to_ident(\"{}\"))", ident.name)), + Token::Lifetime(ident) => lex(&format!("Token::Ident(str_to_ident(\"{}\"))", + ident.name)), + _ => panic!("Unhandled case!"), + } + } + + // ____________________________________________________________________________________________ + // Conversion operators + + pub fn as_tt(t: Token) -> TokenTree { + // FIXME do something nicer with the spans + TokenTree::Token(DUMMY_SP, t) + } + + // ____________________________________________________________________________________________ + // Build Procedures + + /// Takes `input` and returns `vec![input]`. + pub fn build_vec(ts: TokenStream) -> TokenStream { + build_mac_call(str_to_ident("vec"), ts) + // tts.clone().to_owned() + } + + /// Takes `ident` and `rhs` and produces `let ident = rhs;`. + pub fn build_let(id: Ident, tts: TokenStream) -> TokenStream { + concat(from_tokens(vec![keyword_to_token_ident(keywords::Let), + Token::Ident(id), + Token::Eq]), + concat(tts, from_tokens(vec![Token::Semi]))) + } + + /// Takes `ident ...`, and `args ...` and produces `ident::...(args ...)`. + pub fn build_mod_call(ids: Vec, args: TokenStream) -> TokenStream { + let call = from_tokens(intersperse(ids.into_iter().map(|id| Token::Ident(id)).collect(), + Token::ModSep)); + concat(call, build_paren_delimited(args)) + } + + /// Takes `ident` and `args ...` and produces `ident(args ...)`. + pub fn build_fn_call(name: Ident, args: TokenStream) -> TokenStream { + concat(from_tokens(vec![Token::Ident(name)]), build_paren_delimited(args)) + } + + /// Takes `ident` and `args ...` and produces `ident!(args ...)`. + pub fn build_mac_call(name: Ident, args: TokenStream) -> TokenStream { + concat(from_tokens(vec![Token::Ident(name), Token::Not]), + build_paren_delimited(args)) + } + + // ____________________________________________________________________________________________ + // Utilities + + /// A wrapper around `TokenStream::from_tokens` to avoid extra namespace specification and + /// provide it as a generic operator. + pub fn from_tokens(tokens: Vec) -> TokenStream { + TokenStream::from_tokens(tokens) + } + + pub fn intersperse(vs: Vec, t: T) -> Vec + where T: Clone + { + if vs.len() < 2 { + return vs; + } + let mut output = vec![vs.get(0).unwrap().to_owned()]; + + for v in vs.into_iter().skip(1) { + output.push(t.clone()); + output.push(v); + } + output + } +} diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs index 159b7256c7a..656d3146fe5 100644 --- a/src/librustc/middle/dependency_format.rs +++ b/src/librustc/middle/dependency_format.rs @@ -141,12 +141,12 @@ fn calculate_type(sess: &session::Session, } // Everything else falls through below. This will happen either with the - // `-C prefer-dynamic` or because we're a rustc-macro crate. Note that - // rustc-macro crates are required to be dylibs, and they're currently + // `-C prefer-dynamic` or because we're a proc-macro crate. Note that + // proc-macro crates are required to be dylibs, and they're currently // required to link to libsyntax as well. config::CrateTypeExecutable | config::CrateTypeDylib | - config::CrateTypeRustcMacro => {}, + config::CrateTypeProcMacro => {}, } let mut formats = FnvHashMap(); diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index beffaff1e5b..a476d0f6f30 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ReachableContext<'a, 'tcx> { let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| { *ty == config::CrateTypeRlib || *ty == config::CrateTypeDylib || - *ty == config::CrateTypeRustcMacro + *ty == config::CrateTypeProcMacro }); ReachableContext { tcx: tcx, diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs index aa75c7a572b..2c08e17f8f1 100644 --- a/src/librustc/middle/weak_lang_items.rs +++ b/src/librustc/middle/weak_lang_items.rs @@ -71,7 +71,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) { let needs_check = sess.crate_types.borrow().iter().any(|kind| { match *kind { config::CrateTypeDylib | - config::CrateTypeRustcMacro | + config::CrateTypeProcMacro | config::CrateTypeCdylib | config::CrateTypeExecutable | config::CrateTypeStaticlib => true, diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 3372f221729..c7b4a3dfca5 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -482,7 +482,7 @@ pub enum CrateType { CrateTypeRlib, CrateTypeStaticlib, CrateTypeCdylib, - CrateTypeRustcMacro, + CrateTypeProcMacro, } #[derive(Clone, Hash)] @@ -972,8 +972,8 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig { if sess.opts.debug_assertions { ret.push(attr::mk_word_item(InternedString::new("debug_assertions"))); } - if sess.opts.crate_types.contains(&CrateTypeRustcMacro) { - ret.push(attr::mk_word_item(InternedString::new("rustc_macro"))); + if sess.opts.crate_types.contains(&CrateTypeProcMacro) { + ret.push(attr::mk_word_item(InternedString::new("proc_macro"))); } return ret; } @@ -1546,7 +1546,7 @@ pub fn parse_crate_types_from_list(list_list: Vec) -> Result CrateTypeDylib, "cdylib" => CrateTypeCdylib, "bin" => CrateTypeExecutable, - "rustc-macro" => CrateTypeRustcMacro, + "proc-macro" => CrateTypeProcMacro, _ => { return Err(format!("unknown crate type: `{}`", part)); @@ -1630,7 +1630,7 @@ impl fmt::Display for CrateType { CrateTypeRlib => "rlib".fmt(f), CrateTypeStaticlib => "staticlib".fmt(f), CrateTypeCdylib => "cdylib".fmt(f), - CrateTypeRustcMacro => "rustc-macro".fmt(f), + CrateTypeProcMacro => "proc-macro".fmt(f), } } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index b1f80455dd9..d371cc2f8ad 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -493,7 +493,7 @@ pub struct GlobalCtxt<'tcx> { pub layout_depth: Cell, /// Map from function to the `#[derive]` mode that it's defining. Only used - /// by `rustc-macro` crates. + /// by `proc-macro` crates. pub derive_macros: RefCell>, } diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 772d83eb2cf..98e2aa88189 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -13,25 +13,25 @@ arena = { path = "../libarena" } flate = { path = "../libflate" } graphviz = { path = "../libgraphviz" } log = { path = "../liblog" } +proc_macro_plugin = { path = "../libproc_macro_plugin" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_borrowck = { path = "../librustc_borrowck" } rustc_const_eval = { path = "../librustc_const_eval" } rustc_errors = { path = "../librustc_errors" } +rustc_incremental = { path = "../librustc_incremental" } rustc_lint = { path = "../librustc_lint" } rustc_llvm = { path = "../librustc_llvm" } +rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } -rustc_plugin = { path = "../librustc_plugin" } rustc_passes = { path = "../librustc_passes" } +rustc_plugin = { path = "../librustc_plugin" } rustc_privacy = { path = "../librustc_privacy" } -rustc_incremental = { path = "../librustc_incremental" } rustc_resolve = { path = "../librustc_resolve" } rustc_save_analysis = { path = "../librustc_save_analysis" } rustc_trans = { path = "../librustc_trans" } rustc_typeck = { path = "../librustc_typeck" } -rustc_metadata = { path = "../librustc_metadata" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } -proc_macro = { path = "../libproc_macro" } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 8059ef61eab..ea42f7ba93e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -710,14 +710,14 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session, krate = time(time_passes, "maybe creating a macro crate", || { let crate_types = sess.crate_types.borrow(); let num_crate_types = crate_types.len(); - let is_rustc_macro_crate = crate_types.contains(&config::CrateTypeRustcMacro); - syntax_ext::rustc_macro_registrar::modify(&sess.parse_sess, - &mut resolver, - krate, - is_rustc_macro_crate, - num_crate_types, - sess.diagnostic(), - &sess.features.borrow()) + let is_proc_macro_crate = crate_types.contains(&config::CrateTypeProcMacro); + syntax_ext::proc_macro_registrar::modify(&sess.parse_sess, + &mut resolver, + krate, + is_proc_macro_crate, + num_crate_types, + sess.diagnostic(), + &sess.features.borrow()) }); } @@ -1181,8 +1181,8 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec { Some(config::CrateTypeStaticlib) } - Some(ref n) if *n == "rustc-macro" => { - Some(config::CrateTypeRustcMacro) + Some(ref n) if *n == "proc-macro" => { + Some(config::CrateTypeProcMacro) } Some(ref n) if *n == "bin" => Some(config::CrateTypeExecutable), Some(_) => { diff --git a/src/librustc_macro/Cargo.toml b/src/librustc_macro/Cargo.toml deleted file mode 100644 index 6b3ee21d9ac..00000000000 --- a/src/librustc_macro/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -authors = ["The Rust Project Developers"] -name = "rustc_macro" -version = "0.0.0" - -[lib] -name = "rustc_macro" -path = "lib.rs" -crate-type = ["dylib"] - -[dependencies] -syntax = { path = "../libsyntax" } diff --git a/src/librustc_macro/lib.rs b/src/librustc_macro/lib.rs deleted file mode 100644 index 1f3b705671d..00000000000 --- a/src/librustc_macro/lib.rs +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! A support library for macro authors when defining new macros. -//! -//! This library, provided by the standard distribution, provides the types -//! consumed in the interfaces of procedurally defined macro definitions. -//! Currently the primary use of this crate is to provide the ability to define -//! new custom derive modes through `#[rustc_macro_derive]`. -//! -//! Added recently as part of [RFC 1681] this crate is currently *unstable* and -//! requires the `#![feature(rustc_macro_lib)]` directive to use. Eventually, -//! though, it is intended for this crate to become stable to use (perhaps under -//! a different name). -//! -//! [RFC 1681]: https://github.com/rust-lang/rfcs/blob/master/text/1681-macros-1.1.md -//! -//! Note that this crate is intentionally very bare-bones currently. The main -//! type, `TokenStream`, only supports `fmt::Display` and `FromStr` -//! implementations, indicating that it can only go to and come from a string. -//! This functionality is intended to be expanded over time as more surface -//! area for macro authors is stabilized. - -#![crate_name = "rustc_macro"] -#![unstable(feature = "rustc_macro_lib", issue = "27812")] -#![crate_type = "rlib"] -#![crate_type = "dylib"] -#![cfg_attr(not(stage0), deny(warnings))] -#![deny(missing_docs)] - -#![feature(rustc_private)] -#![feature(staged_api)] -#![feature(lang_items)] - -extern crate syntax; - -use std::fmt; -use std::str::FromStr; - -use syntax::ast; -use syntax::parse; -use syntax::ptr::P; - -/// The main type provided by this crate, representing an abstract stream of -/// tokens. -/// -/// This is both the input and output of `#[rustc_macro_derive]` definitions. -/// Currently it's required to be a list of valid Rust items, but this -/// restriction may be lifted in the future. -/// -/// The API of this type is intentionally bare-bones, but it'll be expanded over -/// time! -pub struct TokenStream { - inner: Vec>, -} - -/// Error returned from `TokenStream::from_str`. -#[derive(Debug)] -pub struct LexError { - _inner: (), -} - -/// Permanently unstable internal implementation details of this crate. This -/// should not be used. -/// -/// These methods are used by the rest of the compiler to generate instances of -/// `TokenStream` to hand to macro definitions, as well as consume the output. -/// -/// Note that this module is also intentionally separate from the rest of the -/// crate. This allows the `#[unstable]` directive below to naturally apply to -/// all of the contents. -#[unstable(feature = "rustc_macro_internals", issue = "27812")] -#[doc(hidden)] -pub mod __internal { - use std::cell::Cell; - - use syntax::ast; - use syntax::ptr::P; - use syntax::parse::ParseSess; - use super::TokenStream; - - pub fn new_token_stream(item: P) -> TokenStream { - TokenStream { inner: vec![item] } - } - - pub fn token_stream_items(stream: TokenStream) -> Vec> { - stream.inner - } - - pub trait Registry { - fn register_custom_derive(&mut self, - trait_name: &str, - expand: fn(TokenStream) -> TokenStream); - } - - // Emulate scoped_thread_local!() here essentially - thread_local! { - static CURRENT_SESS: Cell<*const ParseSess> = Cell::new(0 as *const _); - } - - pub fn set_parse_sess(sess: &ParseSess, f: F) -> R - where F: FnOnce() -> R - { - struct Reset { prev: *const ParseSess } - - impl Drop for Reset { - fn drop(&mut self) { - CURRENT_SESS.with(|p| p.set(self.prev)); - } - } - - CURRENT_SESS.with(|p| { - let _reset = Reset { prev: p.get() }; - p.set(sess); - f() - }) - } - - pub fn with_parse_sess(f: F) -> R - where F: FnOnce(&ParseSess) -> R - { - let p = CURRENT_SESS.with(|p| p.get()); - assert!(!p.is_null()); - f(unsafe { &*p }) - } -} - -impl FromStr for TokenStream { - type Err = LexError; - - fn from_str(src: &str) -> Result { - __internal::with_parse_sess(|sess| { - let src = src.to_string(); - let cfg = Vec::new(); - let name = "".to_string(); - let mut parser = parse::new_parser_from_source_str(sess, cfg, name, - src); - let mut ret = TokenStream { inner: Vec::new() }; - loop { - match parser.parse_item() { - Ok(Some(item)) => ret.inner.push(item), - Ok(None) => return Ok(ret), - Err(mut err) => { - err.cancel(); - return Err(LexError { _inner: () }) - } - } - } - }) - } -} - -impl fmt::Display for TokenStream { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - for item in self.inner.iter() { - let item = syntax::print::pprust::item_to_string(item); - try!(f.write_str(&item)); - try!(f.write_str("\n")); - } - Ok(()) - } -} diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 680d55955bb..6f7f03ca216 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -11,13 +11,13 @@ crate-type = ["dylib"] [dependencies] flate = { path = "../libflate" } log = { path = "../liblog" } +proc_macro = { path = "../libproc_macro" } rustc = { path = "../librustc" } rustc_back = { path = "../librustc_back" } rustc_const_math = { path = "../librustc_const_math" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_llvm = { path = "../librustc_llvm" } -rustc_macro = { path = "../librustc_macro" } serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 0c7f6204438..a57207dc089 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -311,7 +311,7 @@ impl<'a> CrateReader<'a> { let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, span); if crate_root.macro_derive_registrar.is_some() { - self.sess.span_err(span, "crates of the `rustc-macro` crate type \ + self.sess.span_err(span, "crates of the `proc-macro` crate type \ cannot be linked at runtime"); } @@ -609,11 +609,11 @@ impl<'a> CrateReader<'a> { match root.macro_derive_registrar { Some(id) => ret.custom_derive_registrar = Some(id), - // If this crate is not a rustc-macro crate then we might be able to + // If this crate is not a proc-macro crate then we might be able to // register it with the local crate store to prevent loading the // metadata twice. // - // If it's a rustc-macro crate, though, then we definitely don't + // If it's a proc-macro crate, though, then we definitely don't // want to register it with the local crate store as we're just // going to use it as we would a plugin. None => { @@ -625,11 +625,11 @@ impl<'a> CrateReader<'a> { self.cstore.add_used_for_derive_macros(item); ret.dylib = ekrate.dylib.clone(); if ret.dylib.is_none() { - span_bug!(item.span, "rustc-macro crate not dylib"); + span_bug!(item.span, "proc-macro crate not dylib"); } if ekrate.target_only { - let message = format!("rustc-macro crate is not available for \ + let message = format!("proc-macro crate is not available for \ triple `{}` (only found {})", config::host_triple(), self.sess.opts.target_triple); @@ -804,7 +804,7 @@ impl<'a> CrateReader<'a> { match *ct { config::CrateTypeExecutable => need_exe_alloc = true, config::CrateTypeDylib | - config::CrateTypeRustcMacro | + config::CrateTypeProcMacro | config::CrateTypeCdylib | config::CrateTypeStaticlib => need_lib_alloc = true, config::CrateTypeRlib => {} diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 4d18462848e..01b106682bb 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -23,7 +23,7 @@ use rustc::traits::specialization_graph; use rustc::ty::{self, Ty, TyCtxt}; use rustc::mir::mir_map::MirMap; -use rustc::session::config::{self, CrateTypeRustcMacro}; +use rustc::session::config::{self, CrateTypeProcMacro}; use rustc::util::nodemap::{FnvHashMap, NodeSet}; use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque}; @@ -1286,7 +1286,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; let link_meta = self.link_meta; - let is_rustc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeRustcMacro); + let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro); let root = self.lazy(&CrateRoot { rustc_version: rustc_version(), name: link_meta.crate_name.clone(), @@ -1297,7 +1297,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { plugin_registrar_fn: tcx.sess.plugin_registrar_fn.get().map(|id| { tcx.map.local_def_id(id).index }), - macro_derive_registrar: if is_rustc_macro { + macro_derive_registrar: if is_proc_macro { let id = tcx.sess.derive_registrar_fn.get().unwrap(); Some(tcx.map.local_def_id(id).index) } else { diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 4fc5a46762d..acaafb35425 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -17,15 +17,15 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![cfg_attr(not(stage0), deny(warnings))] +#![feature(box_patterns)] #![feature(conservative_impl_trait)] #![feature(core_intrinsics)] -#![feature(box_patterns)] #![feature(dotdot_in_tuple_patterns)] +#![feature(proc_macro_internals)] +#![feature(proc_macro_lib)] #![feature(question_mark)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] -#![feature(rustc_macro_lib)] -#![feature(rustc_macro_internals)] #![feature(rustc_private)] #![feature(specialization)] #![feature(staged_api)] @@ -37,14 +37,14 @@ extern crate flate; extern crate serialize as rustc_serialize; // used by deriving extern crate rustc_errors as errors; extern crate syntax_ext; +extern crate proc_macro; #[macro_use] extern crate rustc; -extern crate rustc_data_structures; extern crate rustc_back; -extern crate rustc_llvm; -extern crate rustc_macro; extern crate rustc_const_math; +extern crate rustc_data_structures; +extern crate rustc_llvm; mod diagnostics; diff --git a/src/librustc_metadata/macro_import.rs b/src/librustc_metadata/macro_import.rs index 385f582e2d3..7cd03b2d5b9 100644 --- a/src/librustc_metadata/macro_import.rs +++ b/src/librustc_metadata/macro_import.rs @@ -17,13 +17,13 @@ use std::mem; use creader::{CrateLoader, Macros}; +use proc_macro::TokenStream; +use proc_macro::__internal::Registry; use rustc::hir::def_id::DefIndex; use rustc::middle::cstore::{LoadedMacro, LoadedMacroKind}; use rustc::session::Session; use rustc::util::nodemap::FnvHashMap; use rustc_back::dynamic_lib::DynamicLibrary; -use rustc_macro::TokenStream; -use rustc_macro::__internal::Registry; use syntax::ast; use syntax::attr; use syntax::parse::token; @@ -145,13 +145,13 @@ impl<'a> CrateLoader<'a> { assert_eq!(ret.len(), 0); if let ImportSelection::Some(..) = import { - self.sess.span_err(vi.span, "`rustc-macro` crates cannot be \ + self.sess.span_err(vi.span, "`proc-macro` crates cannot be \ selectively imported from, must \ use `#[macro_use]`"); } if reexport.len() > 0 { - self.sess.span_err(vi.span, "`rustc-macro` crates cannot be \ + self.sess.span_err(vi.span, "`proc-macro` crates cannot be \ reexported from"); } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 2bf517600b7..eb4e3b2a3be 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -535,10 +535,10 @@ impl<'b> Resolver<'b> { } fn insert_custom_derive(&mut self, name: &str, ext: Rc, sp: Span) { - if !self.session.features.borrow().rustc_macro { + if !self.session.features.borrow().proc_macro { let sess = &self.session.parse_sess; let msg = "loading custom derive macro crates is experimentally supported"; - emit_feature_err(sess, "rustc_macro", sp, feature_gate::GateIssue::Language, msg); + emit_feature_err(sess, "proc_macro", sp, feature_gate::GateIssue::Language, msg); } if self.derive_modes.insert(token::intern(name), ext).is_some() { self.session.span_err(sp, &format!("cannot shadow existing derive mode `{}`", name)); diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 5dab82dbc7a..5a8c5cb4b82 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -239,7 +239,7 @@ pub fn invalid_output_for_target(sess: &Session, match (sess.target.target.options.dynamic_linking, sess.target.target.options.executables, crate_type) { (false, _, config::CrateTypeCdylib) | - (false, _, config::CrateTypeRustcMacro) | + (false, _, config::CrateTypeProcMacro) | (false, _, config::CrateTypeDylib) => true, (_, false, config::CrateTypeExecutable) => true, _ => false @@ -263,7 +263,7 @@ pub fn filename_for_input(sess: &Session, outputs.out_directory.join(&format!("lib{}.rlib", libname)) } config::CrateTypeCdylib | - config::CrateTypeRustcMacro | + config::CrateTypeProcMacro | config::CrateTypeDylib => { let (prefix, suffix) = (&sess.target.target.options.dll_prefix, &sess.target.target.options.dll_suffix); @@ -295,7 +295,7 @@ pub fn each_linked_rlib(sess: &Session, let fmts = fmts.get(&config::CrateTypeExecutable) .or_else(|| fmts.get(&config::CrateTypeStaticlib)) .or_else(|| fmts.get(&config::CrateTypeCdylib)) - .or_else(|| fmts.get(&config::CrateTypeRustcMacro)); + .or_else(|| fmts.get(&config::CrateTypeProcMacro)); let fmts = fmts.unwrap_or_else(|| { bug!("could not find formats for rlibs") }); @@ -736,7 +736,7 @@ fn link_args(cmd: &mut Linker, // executable. This metadata is in a separate object file from the main // object file, so we link that in here. if crate_type == config::CrateTypeDylib || - crate_type == config::CrateTypeRustcMacro { + crate_type == config::CrateTypeProcMacro { cmd.add_object(&outputs.with_extension("metadata.o")); } diff --git a/src/librustc_trans/back/linker.rs b/src/librustc_trans/back/linker.rs index dd14f98c920..3222571a76e 100644 --- a/src/librustc_trans/back/linker.rs +++ b/src/librustc_trans/back/linker.rs @@ -245,7 +245,7 @@ impl<'a> Linker for GnuLinker<'a> { // have far more public symbols than we actually want to export, so we // hide them all here. if crate_type == CrateType::CrateTypeDylib || - crate_type == CrateType::CrateTypeRustcMacro { + crate_type == CrateType::CrateTypeProcMacro { return } @@ -450,7 +450,7 @@ fn exported_symbols(scx: &SharedCrateContext, // See explanation in GnuLinker::export_symbols, for // why we don't ever need dylib symbols on non-MSVC. if crate_type == CrateType::CrateTypeDylib || - crate_type == CrateType::CrateTypeRustcMacro { + crate_type == CrateType::CrateTypeProcMacro { if !scx.sess().target.target.options.is_like_msvc { return vec![]; } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index b1d828d0e3e..3abe7626efc 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -862,7 +862,7 @@ impl<'feat> ExpansionConfig<'feat> { fn enable_allow_internal_unstable = allow_internal_unstable, fn enable_custom_derive = custom_derive, fn enable_pushpop_unsafe = pushpop_unsafe, - fn enable_rustc_macro = rustc_macro, + fn enable_proc_macro = proc_macro, } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 079d7175822..9eed1d61244 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -292,7 +292,7 @@ declare_features! ( (active, item_like_imports, "1.13.0", Some(35120)), // Macros 1.1 - (active, rustc_macro, "1.13.0", Some(35900)), + (active, proc_macro, "1.13.0", Some(35900)), // Allows untagged unions `union U { ... }` (active, untagged_unions, "1.13.0", Some(32836)), @@ -576,10 +576,10 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeGat is an experimental feature", cfg_fn!(linked_from))), - ("rustc_macro_derive", Normal, Gated("rustc_macro", - "the `#[rustc_macro_derive]` attribute \ - is an experimental feature", - cfg_fn!(rustc_macro))), + ("proc_macro_derive", Normal, Gated("proc_macro", + "the `#[proc_macro_derive]` attribute \ + is an experimental feature", + cfg_fn!(proc_macro))), ("rustc_copy_clone_marker", Whitelisted, Gated("rustc_attrs", "internal implementation detail", @@ -658,7 +658,7 @@ const GATED_CFGS: &'static [(&'static str, &'static str, fn(&Features) -> bool)] ("target_vendor", "cfg_target_vendor", cfg_fn!(cfg_target_vendor)), ("target_thread_local", "cfg_target_thread_local", cfg_fn!(cfg_target_thread_local)), ("target_has_atomic", "cfg_target_has_atomic", cfg_fn!(cfg_target_has_atomic)), - ("rustc_macro", "rustc_macro", cfg_fn!(rustc_macro)), + ("proc_macro", "proc_macro", cfg_fn!(proc_macro)), ]; #[derive(Debug, Eq, PartialEq)] diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml index 6910e6400d4..960db792a62 100644 --- a/src/libsyntax_ext/Cargo.toml +++ b/src/libsyntax_ext/Cargo.toml @@ -11,7 +11,7 @@ crate-type = ["dylib"] [dependencies] fmt_macros = { path = "../libfmt_macros" } log = { path = "../liblog" } +proc_macro = { path = "../libproc_macro" } rustc_errors = { path = "../librustc_errors" } -rustc_macro = { path = "../librustc_macro" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/libsyntax_ext/deriving/custom.rs b/src/libsyntax_ext/deriving/custom.rs index 624fabd1424..f8cb1294a66 100644 --- a/src/libsyntax_ext/deriving/custom.rs +++ b/src/libsyntax_ext/deriving/custom.rs @@ -11,7 +11,7 @@ use std::panic; use errors::FatalError; -use rustc_macro::{TokenStream, __internal}; +use proc_macro::{TokenStream, __internal}; use syntax::ast::{self, ItemKind}; use syntax::codemap::{ExpnInfo, MacroAttribute, NameAndSpan, Span}; use syntax::ext::base::*; diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index 6e4f3dde4bd..e9d2c0a503b 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -20,8 +20,8 @@ #![cfg_attr(not(stage0), deny(warnings))] #![feature(dotdot_in_tuple_patterns)] -#![feature(rustc_macro_lib)] -#![feature(rustc_macro_internals)] +#![feature(proc_macro_lib)] +#![feature(proc_macro_internals)] #![feature(rustc_private)] #![feature(staged_api)] @@ -31,7 +31,7 @@ extern crate log; #[macro_use] extern crate syntax; extern crate syntax_pos; -extern crate rustc_macro; +extern crate proc_macro; extern crate rustc_errors as errors; mod asm; @@ -43,7 +43,7 @@ mod format; mod log_syntax; mod trace_macros; -pub mod rustc_macro_registrar; +pub mod proc_macro_registrar; // for custom_derive pub mod deriving; diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs new file mode 100644 index 00000000000..b96fb08e59e --- /dev/null +++ b/src/libsyntax_ext/proc_macro_registrar.rs @@ -0,0 +1,277 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::mem; + +use errors; +use syntax::ast::{self, Ident, NodeId}; +use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute}; +use syntax::ext::base::ExtCtxt; +use syntax::ext::build::AstBuilder; +use syntax::ext::expand::ExpansionConfig; +use syntax::parse::ParseSess; +use syntax::parse::token::{self, InternedString}; +use syntax::feature_gate::Features; +use syntax::fold::Folder; +use syntax::ptr::P; +use syntax_pos::{Span, DUMMY_SP}; +use syntax::visit::{self, Visitor}; + +use deriving; + +struct CustomDerive { + trait_name: InternedString, + function_name: Ident, + span: Span, +} + +struct CollectCustomDerives<'a> { + derives: Vec, + in_root: bool, + handler: &'a errors::Handler, + is_proc_macro_crate: bool, +} + +pub fn modify(sess: &ParseSess, + resolver: &mut ::syntax::ext::base::Resolver, + mut krate: ast::Crate, + is_proc_macro_crate: bool, + num_crate_types: usize, + handler: &errors::Handler, + features: &Features) -> ast::Crate { + let ecfg = ExpansionConfig::default("proc_macro".to_string()); + let mut cx = ExtCtxt::new(sess, Vec::new(), ecfg, resolver); + + let mut collect = CollectCustomDerives { + derives: Vec::new(), + in_root: true, + handler: handler, + is_proc_macro_crate: is_proc_macro_crate, + }; + visit::walk_crate(&mut collect, &krate); + + if !is_proc_macro_crate { + return krate + } else if !features.proc_macro { + let mut err = handler.struct_err("the `proc-macro` crate type is \ + experimental"); + err.help("add #![feature(proc_macro)] to the crate attributes to \ + enable"); + err.emit(); + } + + if num_crate_types > 1 { + handler.err("cannot mix `proc-macro` crate type with others"); + } + + krate.module.items.push(mk_registrar(&mut cx, &collect.derives)); + + if krate.exported_macros.len() > 0 { + handler.err("cannot export macro_rules! macros from a `proc-macro` \ + crate type currently"); + } + + return krate +} + +impl<'a> CollectCustomDerives<'a> { + fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) { + if self.is_proc_macro_crate && + self.in_root && + *vis == ast::Visibility::Public { + self.handler.span_err(sp, + "`proc-macro` crate types cannot \ + export any items other than functions \ + tagged with `#[proc_macro_derive]` \ + currently"); + } + } +} + +impl<'a> Visitor for CollectCustomDerives<'a> { + fn visit_item(&mut self, item: &ast::Item) { + // First up, make sure we're checking a bare function. If we're not then + // we're just not interested in this item. + // + // If we find one, try to locate a `#[proc_macro_derive]` attribute on + // it. + match item.node { + ast::ItemKind::Fn(..) => {} + _ => { + self.check_not_pub_in_root(&item.vis, item.span); + return visit::walk_item(self, item) + } + } + + let mut attrs = item.attrs.iter() + .filter(|a| a.check_name("proc_macro_derive")); + let attr = match attrs.next() { + Some(attr) => attr, + None => { + self.check_not_pub_in_root(&item.vis, item.span); + return visit::walk_item(self, item) + } + }; + + if let Some(a) = attrs.next() { + self.handler.span_err(a.span(), "multiple `#[proc_macro_derive]` \ + attributes found"); + } + + if !self.is_proc_macro_crate { + self.handler.span_err(attr.span(), + "the `#[proc_macro_derive]` attribute is \ + only usable with crates of the `proc-macro` \ + crate type"); + } + + // Once we've located the `#[proc_macro_derive]` attribute, verify + // that it's of the form `#[proc_macro_derive(Foo)]` + let list = match attr.meta_item_list() { + Some(list) => list, + None => { + self.handler.span_err(attr.span(), + "attribute must be of form: \ + #[proc_macro_derive(TraitName)]"); + return + } + }; + if list.len() != 1 { + self.handler.span_err(attr.span(), + "attribute must only have one argument"); + return + } + let attr = &list[0]; + let trait_name = match attr.name() { + Some(name) => name, + _ => { + self.handler.span_err(attr.span(), "not a meta item"); + return + } + }; + if !attr.is_word() { + self.handler.span_err(attr.span(), "must only be one word"); + } + + if deriving::is_builtin_trait(&trait_name) { + self.handler.span_err(attr.span(), + "cannot override a built-in #[derive] mode"); + } + + if self.derives.iter().any(|d| d.trait_name == trait_name) { + self.handler.span_err(attr.span(), + "derive mode defined twice in this crate"); + } + + if self.in_root { + self.derives.push(CustomDerive { + span: item.span, + trait_name: trait_name, + function_name: item.ident, + }); + } else { + let msg = "functions tagged with `#[proc_macro_derive]` must \ + currently reside in the root of the crate"; + self.handler.span_err(item.span, msg); + } + + visit::walk_item(self, item); + } + + fn visit_mod(&mut self, m: &ast::Mod, _s: Span, id: NodeId) { + let mut prev_in_root = self.in_root; + if id != ast::CRATE_NODE_ID { + prev_in_root = mem::replace(&mut self.in_root, false); + } + visit::walk_mod(self, m); + self.in_root = prev_in_root; + } + + fn visit_mac(&mut self, mac: &ast::Mac) { + visit::walk_mac(self, mac) + } +} + +// Creates a new module which looks like: +// +// mod $gensym { +// extern crate proc_macro; +// +// use proc_macro::__internal::Registry; +// +// #[plugin_registrar] +// fn registrar(registrar: &mut Registry) { +// registrar.register_custom_derive($name_trait1, ::$name1); +// registrar.register_custom_derive($name_trait2, ::$name2); +// // ... +// } +// } +fn mk_registrar(cx: &mut ExtCtxt, + custom_derives: &[CustomDerive]) -> P { + let eid = cx.codemap().record_expansion(ExpnInfo { + call_site: DUMMY_SP, + callee: NameAndSpan { + format: MacroAttribute(token::intern("proc_macro")), + span: None, + allow_internal_unstable: true, + } + }); + let span = Span { expn_id: eid, ..DUMMY_SP }; + + let proc_macro = token::str_to_ident("proc_macro"); + let krate = cx.item(span, + proc_macro, + Vec::new(), + ast::ItemKind::ExternCrate(None)); + + let __internal = token::str_to_ident("__internal"); + let registry = token::str_to_ident("Registry"); + let registrar = token::str_to_ident("registrar"); + let register_custom_derive = token::str_to_ident("register_custom_derive"); + let stmts = custom_derives.iter().map(|cd| { + let path = cx.path_global(cd.span, vec![cd.function_name]); + let trait_name = cx.expr_str(cd.span, cd.trait_name.clone()); + (path, trait_name) + }).map(|(path, trait_name)| { + let registrar = cx.expr_ident(span, registrar); + let ufcs_path = cx.path(span, vec![proc_macro, __internal, registry, + register_custom_derive]); + cx.expr_call(span, + cx.expr_path(ufcs_path), + vec![registrar, trait_name, cx.expr_path(path)]) + }).map(|expr| { + cx.stmt_expr(expr) + }).collect::>(); + + let path = cx.path(span, vec![proc_macro, __internal, registry]); + let registrar_path = cx.ty_path(path); + let arg_ty = cx.ty_rptr(span, registrar_path, None, ast::Mutability::Mutable); + let func = cx.item_fn(span, + registrar, + vec![cx.arg(span, registrar, arg_ty)], + cx.ty(span, ast::TyKind::Tup(Vec::new())), + cx.block(span, stmts)); + + let derive_registrar = token::intern_and_get_ident("rustc_derive_registrar"); + let derive_registrar = cx.meta_word(span, derive_registrar); + let derive_registrar = cx.attribute(span, derive_registrar); + let func = func.map(|mut i| { + i.attrs.push(derive_registrar); + i.vis = ast::Visibility::Public; + i + }); + let ident = ast::Ident::with_empty_ctxt(token::gensym("registrar")); + let module = cx.item_mod(span, span, ident, Vec::new(), vec![krate, func]).map(|mut i| { + i.vis = ast::Visibility::Public; + i + }); + + cx.monotonic_expander().fold_item(module).pop().unwrap() +} diff --git a/src/libsyntax_ext/rustc_macro_registrar.rs b/src/libsyntax_ext/rustc_macro_registrar.rs deleted file mode 100644 index ce3e53cdf97..00000000000 --- a/src/libsyntax_ext/rustc_macro_registrar.rs +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::mem; - -use errors; -use syntax::ast::{self, Ident, NodeId}; -use syntax::codemap::{ExpnInfo, NameAndSpan, MacroAttribute}; -use syntax::ext::base::ExtCtxt; -use syntax::ext::build::AstBuilder; -use syntax::ext::expand::ExpansionConfig; -use syntax::parse::ParseSess; -use syntax::parse::token::{self, InternedString}; -use syntax::feature_gate::Features; -use syntax::fold::Folder; -use syntax::ptr::P; -use syntax_pos::{Span, DUMMY_SP}; -use syntax::visit::{self, Visitor}; - -use deriving; - -struct CustomDerive { - trait_name: InternedString, - function_name: Ident, - span: Span, -} - -struct CollectCustomDerives<'a> { - derives: Vec, - in_root: bool, - handler: &'a errors::Handler, - is_rustc_macro_crate: bool, -} - -pub fn modify(sess: &ParseSess, - resolver: &mut ::syntax::ext::base::Resolver, - mut krate: ast::Crate, - is_rustc_macro_crate: bool, - num_crate_types: usize, - handler: &errors::Handler, - features: &Features) -> ast::Crate { - let ecfg = ExpansionConfig::default("rustc_macro".to_string()); - let mut cx = ExtCtxt::new(sess, Vec::new(), ecfg, resolver); - - let mut collect = CollectCustomDerives { - derives: Vec::new(), - in_root: true, - handler: handler, - is_rustc_macro_crate: is_rustc_macro_crate, - }; - visit::walk_crate(&mut collect, &krate); - - if !is_rustc_macro_crate { - return krate - } else if !features.rustc_macro { - let mut err = handler.struct_err("the `rustc-macro` crate type is \ - experimental"); - err.help("add #![feature(rustc_macro)] to the crate attributes to \ - enable"); - err.emit(); - } - - if num_crate_types > 1 { - handler.err("cannot mix `rustc-macro` crate type with others"); - } - - krate.module.items.push(mk_registrar(&mut cx, &collect.derives)); - - if krate.exported_macros.len() > 0 { - handler.err("cannot export macro_rules! macros from a `rustc-macro` \ - crate type currently"); - } - - return krate -} - -impl<'a> CollectCustomDerives<'a> { - fn check_not_pub_in_root(&self, vis: &ast::Visibility, sp: Span) { - if self.is_rustc_macro_crate && - self.in_root && - *vis == ast::Visibility::Public { - self.handler.span_err(sp, - "`rustc-macro` crate types cannot \ - export any items other than functions \ - tagged with `#[rustc_macro_derive]` \ - currently"); - } - } -} - -impl<'a> Visitor for CollectCustomDerives<'a> { - fn visit_item(&mut self, item: &ast::Item) { - // First up, make sure we're checking a bare function. If we're not then - // we're just not interested in this item. - // - // If we find one, try to locate a `#[rustc_macro_derive]` attribute on - // it. - match item.node { - ast::ItemKind::Fn(..) => {} - _ => { - self.check_not_pub_in_root(&item.vis, item.span); - return visit::walk_item(self, item) - } - } - - let mut attrs = item.attrs.iter() - .filter(|a| a.check_name("rustc_macro_derive")); - let attr = match attrs.next() { - Some(attr) => attr, - None => { - self.check_not_pub_in_root(&item.vis, item.span); - return visit::walk_item(self, item) - } - }; - - if let Some(a) = attrs.next() { - self.handler.span_err(a.span(), "multiple `#[rustc_macro_derive]` \ - attributes found"); - } - - if !self.is_rustc_macro_crate { - self.handler.span_err(attr.span(), - "the `#[rustc_macro_derive]` attribute is \ - only usable with crates of the `rustc-macro` \ - crate type"); - } - - // Once we've located the `#[rustc_macro_derive]` attribute, verify - // that it's of the form `#[rustc_macro_derive(Foo)]` - let list = match attr.meta_item_list() { - Some(list) => list, - None => { - self.handler.span_err(attr.span(), - "attribute must be of form: \ - #[rustc_macro_derive(TraitName)]"); - return - } - }; - if list.len() != 1 { - self.handler.span_err(attr.span(), - "attribute must only have one argument"); - return - } - let attr = &list[0]; - let trait_name = match attr.name() { - Some(name) => name, - _ => { - self.handler.span_err(attr.span(), "not a meta item"); - return - } - }; - if !attr.is_word() { - self.handler.span_err(attr.span(), "must only be one word"); - } - - if deriving::is_builtin_trait(&trait_name) { - self.handler.span_err(attr.span(), - "cannot override a built-in #[derive] mode"); - } - - if self.derives.iter().any(|d| d.trait_name == trait_name) { - self.handler.span_err(attr.span(), - "derive mode defined twice in this crate"); - } - - if self.in_root { - self.derives.push(CustomDerive { - span: item.span, - trait_name: trait_name, - function_name: item.ident, - }); - } else { - let msg = "functions tagged with `#[rustc_macro_derive]` must \ - currently reside in the root of the crate"; - self.handler.span_err(item.span, msg); - } - - visit::walk_item(self, item); - } - - fn visit_mod(&mut self, m: &ast::Mod, _s: Span, id: NodeId) { - let mut prev_in_root = self.in_root; - if id != ast::CRATE_NODE_ID { - prev_in_root = mem::replace(&mut self.in_root, false); - } - visit::walk_mod(self, m); - self.in_root = prev_in_root; - } - - fn visit_mac(&mut self, mac: &ast::Mac) { - visit::walk_mac(self, mac) - } -} - -// Creates a new module which looks like: -// -// mod $gensym { -// extern crate rustc_macro; -// -// use rustc_macro::__internal::Registry; -// -// #[plugin_registrar] -// fn registrar(registrar: &mut Registry) { -// registrar.register_custom_derive($name_trait1, ::$name1); -// registrar.register_custom_derive($name_trait2, ::$name2); -// // ... -// } -// } -fn mk_registrar(cx: &mut ExtCtxt, - custom_derives: &[CustomDerive]) -> P { - let eid = cx.codemap().record_expansion(ExpnInfo { - call_site: DUMMY_SP, - callee: NameAndSpan { - format: MacroAttribute(token::intern("rustc_macro")), - span: None, - allow_internal_unstable: true, - } - }); - let span = Span { expn_id: eid, ..DUMMY_SP }; - - let rustc_macro = token::str_to_ident("rustc_macro"); - let krate = cx.item(span, - rustc_macro, - Vec::new(), - ast::ItemKind::ExternCrate(None)); - - let __internal = token::str_to_ident("__internal"); - let registry = token::str_to_ident("Registry"); - let registrar = token::str_to_ident("registrar"); - let register_custom_derive = token::str_to_ident("register_custom_derive"); - let stmts = custom_derives.iter().map(|cd| { - let path = cx.path_global(cd.span, vec![cd.function_name]); - let trait_name = cx.expr_str(cd.span, cd.trait_name.clone()); - (path, trait_name) - }).map(|(path, trait_name)| { - let registrar = cx.expr_ident(span, registrar); - let ufcs_path = cx.path(span, vec![rustc_macro, __internal, registry, - register_custom_derive]); - cx.expr_call(span, - cx.expr_path(ufcs_path), - vec![registrar, trait_name, cx.expr_path(path)]) - }).map(|expr| { - cx.stmt_expr(expr) - }).collect::>(); - - let path = cx.path(span, vec![rustc_macro, __internal, registry]); - let registrar_path = cx.ty_path(path); - let arg_ty = cx.ty_rptr(span, registrar_path, None, ast::Mutability::Mutable); - let func = cx.item_fn(span, - registrar, - vec![cx.arg(span, registrar, arg_ty)], - cx.ty(span, ast::TyKind::Tup(Vec::new())), - cx.block(span, stmts)); - - let derive_registrar = token::intern_and_get_ident("rustc_derive_registrar"); - let derive_registrar = cx.meta_word(span, derive_registrar); - let derive_registrar = cx.attribute(span, derive_registrar); - let func = func.map(|mut i| { - i.attrs.push(derive_registrar); - i.vis = ast::Visibility::Public; - i - }); - let ident = ast::Ident::with_empty_ctxt(token::gensym("registrar")); - let module = cx.item_mod(span, span, ident, Vec::new(), vec![krate, func]).map(|mut i| { - i.vis = ast::Visibility::Public; - i - }); - - cx.monotonic_expander().fold_item(module).pop().unwrap() -} diff --git a/src/rustc/Cargo.lock b/src/rustc/Cargo.lock index 69e3eab22e9..192d14b8fb1 100644 --- a/src/rustc/Cargo.lock +++ b/src/rustc/Cargo.lock @@ -43,6 +43,13 @@ version = "0.0.0" [[package]] name = "proc_macro" version = "0.0.0" +dependencies = [ + "syntax 0.0.0", +] + +[[package]] +name = "proc_macro_plugin" +version = "0.0.0" dependencies = [ "log 0.0.0", "rustc_plugin 0.0.0", @@ -137,7 +144,7 @@ dependencies = [ "flate 0.0.0", "graphviz 0.0.0", "log 0.0.0", - "proc_macro 0.0.0", + "proc_macro_plugin 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_borrowck 0.0.0", @@ -204,26 +211,19 @@ dependencies = [ "rustc_bitflags 0.0.0", ] -[[package]] -name = "rustc_macro" -version = "0.0.0" -dependencies = [ - "syntax 0.0.0", -] - [[package]] name = "rustc_metadata" version = "0.0.0" dependencies = [ "flate 0.0.0", "log 0.0.0", + "proc_macro 0.0.0", "rustc 0.0.0", "rustc_back 0.0.0", "rustc_const_math 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", "rustc_llvm 0.0.0", - "rustc_macro 0.0.0", "serialize 0.0.0", "syntax 0.0.0", "syntax_ext 0.0.0", @@ -396,8 +396,8 @@ version = "0.0.0" dependencies = [ "fmt_macros 0.0.0", "log 0.0.0", + "proc_macro 0.0.0", "rustc_errors 0.0.0", - "rustc_macro 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/test/compile-fail-fulldeps/proc-macro/at-the-root.rs b/src/test/compile-fail-fulldeps/proc-macro/at-the-root.rs new file mode 100644 index 00000000000..b03e1e4f919 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/at-the-root.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] + +extern crate proc_macro; + +pub mod a { //~ `proc-macro` crate types cannot export any items + use proc_macro::TokenStream; + + #[proc_macro_derive(B)] + pub fn bar(a: TokenStream) -> TokenStream { + //~^ ERROR: must currently reside in the root of the crate + a + } +} + diff --git a/src/test/compile-fail-fulldeps/proc-macro/attribute.rs b/src/test/compile-fail-fulldeps/proc-macro/attribute.rs new file mode 100644 index 00000000000..d1b2aa330ed --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/attribute.rs @@ -0,0 +1,46 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] + +extern crate proc_macro; + +#[proc_macro_derive] +//~^ ERROR: attribute must be of form: #[proc_macro_derive(TraitName)] +pub fn foo1(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} + +#[proc_macro_derive = "foo"] +//~^ ERROR: attribute must be of form: #[proc_macro_derive(TraitName)] +pub fn foo2(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} + +#[proc_macro_derive( + a = "b" +)] +//~^^ ERROR: must only be one word +pub fn foo3(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} + +#[proc_macro_derive(b, c)] +//~^ ERROR: attribute must only have one argument +pub fn foo4(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} + +#[proc_macro_derive(d(e))] +//~^ ERROR: must only be one word +pub fn foo5(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + input +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-2.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-2.rs new file mode 100644 index 00000000000..4aa4238611d --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a-2.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host +// no-prefer-dynamic + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive_a(input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs new file mode 100644 index 00000000000..4aa4238611d --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-a.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host +// no-prefer-dynamic + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive_a(input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs new file mode 100644 index 00000000000..aae8b63e253 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-bad.rs @@ -0,0 +1,26 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic +// force-host + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive_a(_input: TokenStream) -> TokenStream { + "struct A { inner }".parse().unwrap() +} + diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-panic.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-panic.rs new file mode 100644 index 00000000000..f426fe54376 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-panic.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic +// force-host + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive_a(_input: TokenStream) -> TokenStream { + panic!("nope!"); +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs new file mode 100644 index 00000000000..d8952e3478b --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable-2.rs @@ -0,0 +1,29 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host +// no-prefer-dynamic + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Unstable)] +pub fn derive(_input: TokenStream) -> TokenStream { + + " + #[rustc_foo] + fn foo() {} + ".parse().unwrap() +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs new file mode 100644 index 00000000000..1187b5102e2 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/auxiliary/derive-unstable.rs @@ -0,0 +1,26 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host +// no-prefer-dynamic + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Unstable)] +pub fn derive(_input: TokenStream) -> TokenStream { + + "unsafe fn foo() -> u32 { ::std::intrinsics::init() }".parse().unwrap() +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/cannot-link.rs b/src/test/compile-fail-fulldeps/proc-macro/cannot-link.rs new file mode 100644 index 00000000000..f6f1be37fc3 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/cannot-link.rs @@ -0,0 +1,16 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-a.rs + +extern crate derive_a; +//~^ ERROR: crates of the `proc-macro` crate type cannot be linked at runtime + +fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/define-two.rs b/src/test/compile-fail-fulldeps/proc-macro/define-two.rs new file mode 100644 index 00000000000..420249b2581 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/define-two.rs @@ -0,0 +1,28 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn foo(input: TokenStream) -> TokenStream { + input +} + +#[proc_macro_derive(A)] //~ ERROR: derive mode defined twice in this crate +pub fn bar(input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs b/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs new file mode 100644 index 00000000000..4cc6b9f984c --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/derive-bad.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-bad.rs + +#![feature(proc_macro)] + +#[macro_use] +extern crate derive_bad; + +#[derive( + A +)] +//~^^ ERROR: custom derive attribute panicked +//~| HELP: called `Result::unwrap()` on an `Err` value: LexError +struct A; + +fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs b/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs new file mode 100644 index 00000000000..eb0bb00be91 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/derive-still-gated.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-a.rs + +#![feature(proc_macro)] +#![allow(warnings)] + +#[macro_use] +extern crate derive_a; + +#[derive_A] //~ ERROR: attributes of the form `#[derive_*]` are reserved for the compiler +struct A; + +fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs new file mode 100644 index 00000000000..23dcbe03b5f --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable-2.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-unstable-2.rs + +#![feature(proc_macro)] +#![allow(warnings)] + +#[macro_use] +extern crate derive_unstable_2; + +#[derive(Unstable)] +struct A; +//~^ ERROR: reserved for internal compiler + +fn main() { + foo(); +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs new file mode 100644 index 00000000000..fb86f6f1b65 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/expand-to-unstable.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-unstable.rs + +#![feature(proc_macro)] +#![allow(warnings)] + +#[macro_use] +extern crate derive_unstable; + +#[derive(Unstable)] +struct A; +//~^ ERROR: use of unstable library feature + +fn main() { + unsafe { foo(); } +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs b/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs new file mode 100644 index 00000000000..48b73e73331 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/export-macro.rs @@ -0,0 +1,19 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern: cannot export macro_rules! macros from a `proc-macro` crate + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] + +#[macro_export] +macro_rules! foo { + ($e:expr) => ($e) +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/exports.rs b/src/test/compile-fail-fulldeps/proc-macro/exports.rs new file mode 100644 index 00000000000..41b94d04e8c --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/exports.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "proc-macro"] +#![allow(warnings)] + +pub fn a() {} //~ ERROR: cannot export any items +pub struct B; //~ ERROR: cannot export any items +pub enum C {} //~ ERROR: cannot export any items +pub mod d {} //~ ERROR: cannot export any items + +mod e {} +struct F; +enum G {} +fn h() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-1.rs b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-1.rs new file mode 100644 index 00000000000..f5618fc6425 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-1.rs @@ -0,0 +1,13 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern: the `proc-macro` crate type is experimental + +#![crate_type = "proc-macro"] diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-2.rs b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-2.rs new file mode 100644 index 00000000000..9c4053266f4 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-2.rs @@ -0,0 +1,13 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate proc_macro; //~ ERROR: use of unstable library feature + +fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-3.rs b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-3.rs new file mode 100644 index 00000000000..bb6b5759622 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-3.rs @@ -0,0 +1,15 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "proc-macro"] + +#[proc_macro_derive(Foo)] //~ ERROR: is an experimental feature +pub fn foo() { +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-4.rs b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-4.rs new file mode 100644 index 00000000000..0fdd13bc30c --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-4.rs @@ -0,0 +1,15 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-a.rs + +#[macro_use] +extern crate derive_a; +//~^ ERROR: loading custom derive macro crates is experimentally supported diff --git a/src/test/compile-fail-fulldeps/proc-macro/feature-gate-5.rs b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-5.rs new file mode 100644 index 00000000000..672579ce8f1 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/feature-gate-5.rs @@ -0,0 +1,12 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[cfg(proc_macro)] //~ ERROR: experimental and subject to change +fn foo() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/import.rs b/src/test/compile-fail-fulldeps/proc-macro/import.rs new file mode 100644 index 00000000000..8f907183cc3 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/import.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-a.rs + +#![feature(proc_macro)] +#![allow(warnings)] + +#[macro_use] +extern crate derive_a; + +use derive_a::derive_a; +//~^ ERROR: unresolved import `derive_a::derive_a` + +fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/load-panic.rs b/src/test/compile-fail-fulldeps/proc-macro/load-panic.rs new file mode 100644 index 00000000000..39c27e82fa5 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/load-panic.rs @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-panic.rs + +#![feature(proc_macro)] + +#[macro_use] +extern crate derive_panic; + +#[derive(A)] +//~^ ERROR: custom derive attribute panicked +//~| HELP: message: nope! +struct Foo; + +fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/require-rustc-macro-crate-type.rs b/src/test/compile-fail-fulldeps/proc-macro/require-rustc-macro-crate-type.rs new file mode 100644 index 00000000000..44397cdde0c --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/require-rustc-macro-crate-type.rs @@ -0,0 +1,21 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(proc_macro)] + +extern crate proc_macro; + +#[proc_macro_derive(Foo)] +//~^ ERROR: only usable with crates of the `proc-macro` crate type +pub fn foo(a: proc_macro::TokenStream) -> proc_macro::TokenStream { + a +} + +fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs b/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs new file mode 100644 index 00000000000..5cb2cc59aab --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/shadow-builtin.rs @@ -0,0 +1,22 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(PartialEq)] +//~^ ERROR: cannot override a built-in #[derive] mode +pub fn foo(input: TokenStream) -> TokenStream { + input +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/shadow.rs b/src/test/compile-fail-fulldeps/proc-macro/shadow.rs new file mode 100644 index 00000000000..7b1a73d50f6 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/shadow.rs @@ -0,0 +1,21 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-a.rs +// aux-build:derive-a-2.rs + +#![feature(proc_macro)] + +#[macro_use] +extern crate derive_a; +#[macro_use] +extern crate derive_a_2; //~ ERROR: cannot shadow existing derive mode `A` + +fn main() {} diff --git a/src/test/compile-fail-fulldeps/proc-macro/signature.rs b/src/test/compile-fail-fulldeps/proc-macro/signature.rs new file mode 100644 index 00000000000..468c970599e --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/signature.rs @@ -0,0 +1,24 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] +#![allow(warnings)] + +extern crate proc_macro; + +#[proc_macro_derive(A)] +unsafe extern fn foo(a: i32, b: u32) -> u32 { + //~^ ERROR: mismatched types + //~| NOTE: expected normal fn, found unsafe fn + //~| NOTE: expected type `fn(proc_macro::TokenStream) -> proc_macro::TokenStream` + //~| NOTE: found type `unsafe extern "C" fn(i32, u32) -> u32 {foo}` + loop {} +} diff --git a/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs b/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs new file mode 100644 index 00000000000..db646fb7815 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-1.rs @@ -0,0 +1,14 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern: cannot mix `proc-macro` crate type with others + +#![crate_type = "proc-macro"] +#![crate_type = "rlib"] diff --git a/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs b/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs new file mode 100644 index 00000000000..97b0f844604 --- /dev/null +++ b/src/test/compile-fail-fulldeps/proc-macro/two-crate-types-2.rs @@ -0,0 +1,12 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// error-pattern: cannot mix `proc-macro` crate type with others +// compile-flags: --crate-type rlib --crate-type proc-macro diff --git a/src/test/compile-fail-fulldeps/rustc-macro/at-the-root.rs b/src/test/compile-fail-fulldeps/rustc-macro/at-the-root.rs deleted file mode 100644 index 46724523d1c..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/at-the-root.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] - -extern crate rustc_macro; - -pub mod a { //~ `rustc-macro` crate types cannot export any items - use rustc_macro::TokenStream; - - #[rustc_macro_derive(B)] - pub fn bar(a: TokenStream) -> TokenStream { - //~^ ERROR: must currently reside in the root of the crate - a - } -} - diff --git a/src/test/compile-fail-fulldeps/rustc-macro/attribute.rs b/src/test/compile-fail-fulldeps/rustc-macro/attribute.rs deleted file mode 100644 index 7740238aeac..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/attribute.rs +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] - -extern crate rustc_macro; - -#[rustc_macro_derive] -//~^ ERROR: attribute must be of form: #[rustc_macro_derive(TraitName)] -pub fn foo1(input: rustc_macro::TokenStream) -> rustc_macro::TokenStream { - input -} - -#[rustc_macro_derive = "foo"] -//~^ ERROR: attribute must be of form: #[rustc_macro_derive(TraitName)] -pub fn foo2(input: rustc_macro::TokenStream) -> rustc_macro::TokenStream { - input -} - -#[rustc_macro_derive( - a = "b" -)] -//~^^ ERROR: must only be one word -pub fn foo3(input: rustc_macro::TokenStream) -> rustc_macro::TokenStream { - input -} - -#[rustc_macro_derive(b, c)] -//~^ ERROR: attribute must only have one argument -pub fn foo4(input: rustc_macro::TokenStream) -> rustc_macro::TokenStream { - input -} - -#[rustc_macro_derive(d(e))] -//~^ ERROR: must only be one word -pub fn foo5(input: rustc_macro::TokenStream) -> rustc_macro::TokenStream { - input -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-a-2.rs b/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-a-2.rs deleted file mode 100644 index ff00a9d96a3..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-a-2.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// force-host -// no-prefer-dynamic - -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![crate_type = "rustc-macro"] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(A)] -pub fn derive_a(input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-a.rs b/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-a.rs deleted file mode 100644 index ff00a9d96a3..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-a.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// force-host -// no-prefer-dynamic - -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![crate_type = "rustc-macro"] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(A)] -pub fn derive_a(input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-bad.rs b/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-bad.rs deleted file mode 100644 index 5dd42d28b7b..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-bad.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic -// force-host - -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![crate_type = "rustc-macro"] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(A)] -pub fn derive_a(_input: TokenStream) -> TokenStream { - "struct A { inner }".parse().unwrap() -} - diff --git a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-panic.rs b/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-panic.rs deleted file mode 100644 index d867082ed5e..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-panic.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic -// force-host - -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![crate_type = "rustc-macro"] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(A)] -pub fn derive_a(_input: TokenStream) -> TokenStream { - panic!("nope!"); -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-unstable-2.rs b/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-unstable-2.rs deleted file mode 100644 index 9eebad89756..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-unstable-2.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// force-host -// no-prefer-dynamic - -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![crate_type = "rustc-macro"] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(Unstable)] -pub fn derive(_input: TokenStream) -> TokenStream { - - " - #[rustc_foo] - fn foo() {} - ".parse().unwrap() -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-unstable.rs b/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-unstable.rs deleted file mode 100644 index f4a1ec99700..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/auxiliary/derive-unstable.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// force-host -// no-prefer-dynamic - -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![crate_type = "rustc-macro"] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(Unstable)] -pub fn derive(_input: TokenStream) -> TokenStream { - - "unsafe fn foo() -> u32 { ::std::intrinsics::init() }".parse().unwrap() -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/cannot-link.rs b/src/test/compile-fail-fulldeps/rustc-macro/cannot-link.rs deleted file mode 100644 index 1f135330a99..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/cannot-link.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-a.rs - -extern crate derive_a; -//~^ ERROR: crates of the `rustc-macro` crate type cannot be linked at runtime - -fn main() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/define-two.rs b/src/test/compile-fail-fulldeps/rustc-macro/define-two.rs deleted file mode 100644 index e4f21dc2384..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/define-two.rs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(A)] -pub fn foo(input: TokenStream) -> TokenStream { - input -} - -#[rustc_macro_derive(A)] //~ ERROR: derive mode defined twice in this crate -pub fn bar(input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/derive-bad.rs b/src/test/compile-fail-fulldeps/rustc-macro/derive-bad.rs deleted file mode 100644 index f3a73af2993..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/derive-bad.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-bad.rs - -#![feature(rustc_macro)] - -#[macro_use] -extern crate derive_bad; - -#[derive( - A -)] -//~^^ ERROR: custom derive attribute panicked -//~| HELP: called `Result::unwrap()` on an `Err` value: LexError -struct A; - -fn main() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/derive-still-gated.rs b/src/test/compile-fail-fulldeps/rustc-macro/derive-still-gated.rs deleted file mode 100644 index a46d79f517f..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/derive-still-gated.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-a.rs - -#![feature(rustc_macro)] -#![allow(warnings)] - -#[macro_use] -extern crate derive_a; - -#[derive_A] //~ ERROR: attributes of the form `#[derive_*]` are reserved for the compiler -struct A; - -fn main() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/expand-to-unstable-2.rs b/src/test/compile-fail-fulldeps/rustc-macro/expand-to-unstable-2.rs deleted file mode 100644 index 14c3d84e75b..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/expand-to-unstable-2.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-unstable-2.rs - -#![feature(rustc_macro)] -#![allow(warnings)] - -#[macro_use] -extern crate derive_unstable_2; - -#[derive(Unstable)] -struct A; -//~^ ERROR: reserved for internal compiler - -fn main() { - foo(); -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/expand-to-unstable.rs b/src/test/compile-fail-fulldeps/rustc-macro/expand-to-unstable.rs deleted file mode 100644 index aa9aaa81156..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/expand-to-unstable.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-unstable.rs - -#![feature(rustc_macro)] -#![allow(warnings)] - -#[macro_use] -extern crate derive_unstable; - -#[derive(Unstable)] -struct A; -//~^ ERROR: use of unstable library feature - -fn main() { - unsafe { foo(); } -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/export-macro.rs b/src/test/compile-fail-fulldeps/rustc-macro/export-macro.rs deleted file mode 100644 index 759f3d32e16..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/export-macro.rs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern: cannot export macro_rules! macros from a `rustc-macro` crate - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] - -#[macro_export] -macro_rules! foo { - ($e:expr) => ($e) -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/exports.rs b/src/test/compile-fail-fulldeps/rustc-macro/exports.rs deleted file mode 100644 index e985356dc58..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/exports.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_type = "rustc-macro"] -#![allow(warnings)] - -pub fn a() {} //~ ERROR: cannot export any items -pub struct B; //~ ERROR: cannot export any items -pub enum C {} //~ ERROR: cannot export any items -pub mod d {} //~ ERROR: cannot export any items - -mod e {} -struct F; -enum G {} -fn h() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-1.rs b/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-1.rs deleted file mode 100644 index 86afc08cae8..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-1.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern: the `rustc-macro` crate type is experimental - -#![crate_type = "rustc-macro"] diff --git a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-2.rs b/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-2.rs deleted file mode 100644 index 1a19f6046d9..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-2.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -extern crate rustc_macro; //~ ERROR: use of unstable library feature - -fn main() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-3.rs b/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-3.rs deleted file mode 100644 index 9f47f07bd02..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-3.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_type = "rustc-macro"] - -#[rustc_macro_derive(Foo)] //~ ERROR: is an experimental feature -pub fn foo() { -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-4.rs b/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-4.rs deleted file mode 100644 index 0fdd13bc30c..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-4.rs +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-a.rs - -#[macro_use] -extern crate derive_a; -//~^ ERROR: loading custom derive macro crates is experimentally supported diff --git a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-5.rs b/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-5.rs deleted file mode 100644 index e44b29a1705..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/feature-gate-5.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#[cfg(rustc_macro)] //~ ERROR: experimental and subject to change -fn foo() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/import.rs b/src/test/compile-fail-fulldeps/rustc-macro/import.rs deleted file mode 100644 index c1d0823cb6b..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/import.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-a.rs - -#![feature(rustc_macro)] -#![allow(warnings)] - -#[macro_use] -extern crate derive_a; - -use derive_a::derive_a; -//~^ ERROR: unresolved import `derive_a::derive_a` - -fn main() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/load-panic.rs b/src/test/compile-fail-fulldeps/rustc-macro/load-panic.rs deleted file mode 100644 index 0d08d27c38e..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/load-panic.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-panic.rs - -#![feature(rustc_macro)] - -#[macro_use] -extern crate derive_panic; - -#[derive(A)] -//~^ ERROR: custom derive attribute panicked -//~| HELP: message: nope! -struct Foo; - -fn main() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/require-rustc-macro-crate-type.rs b/src/test/compile-fail-fulldeps/rustc-macro/require-rustc-macro-crate-type.rs deleted file mode 100644 index cdc50acea92..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/require-rustc-macro-crate-type.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![feature(rustc_macro)] - -extern crate rustc_macro; - -#[rustc_macro_derive(Foo)] -//~^ ERROR: only usable with crates of the `rustc-macro` crate type -pub fn foo(a: rustc_macro::TokenStream) -> rustc_macro::TokenStream { - a -} - -fn main() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/shadow-builtin.rs b/src/test/compile-fail-fulldeps/rustc-macro/shadow-builtin.rs deleted file mode 100644 index 1353a234b48..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/shadow-builtin.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(PartialEq)] -//~^ ERROR: cannot override a built-in #[derive] mode -pub fn foo(input: TokenStream) -> TokenStream { - input -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/shadow.rs b/src/test/compile-fail-fulldeps/rustc-macro/shadow.rs deleted file mode 100644 index 33330ed8f6a..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/shadow.rs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-a.rs -// aux-build:derive-a-2.rs - -#![feature(rustc_macro)] - -#[macro_use] -extern crate derive_a; -#[macro_use] -extern crate derive_a_2; //~ ERROR: cannot shadow existing derive mode `A` - -fn main() {} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/signature.rs b/src/test/compile-fail-fulldeps/rustc-macro/signature.rs deleted file mode 100644 index 9662cc69e1e..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/signature.rs +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] -#![allow(warnings)] - -extern crate rustc_macro; - -#[rustc_macro_derive(A)] -unsafe extern fn foo(a: i32, b: u32) -> u32 { - //~^ ERROR: mismatched types - //~| NOTE: expected normal fn, found unsafe fn - //~| NOTE: expected type `fn(rustc_macro::TokenStream) -> rustc_macro::TokenStream` - //~| NOTE: found type `unsafe extern "C" fn(i32, u32) -> u32 {foo}` - loop {} -} diff --git a/src/test/compile-fail-fulldeps/rustc-macro/two-crate-types-1.rs b/src/test/compile-fail-fulldeps/rustc-macro/two-crate-types-1.rs deleted file mode 100644 index 35f6149ad49..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/two-crate-types-1.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern: cannot mix `rustc-macro` crate type with others - -#![crate_type = "rustc-macro"] -#![crate_type = "rlib"] diff --git a/src/test/compile-fail-fulldeps/rustc-macro/two-crate-types-2.rs b/src/test/compile-fail-fulldeps/rustc-macro/two-crate-types-2.rs deleted file mode 100644 index ec95e3e4685..00000000000 --- a/src/test/compile-fail-fulldeps/rustc-macro/two-crate-types-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// error-pattern: cannot mix `rustc-macro` crate type with others -// compile-flags: --crate-type rlib --crate-type rustc-macro diff --git a/src/test/run-make/rustc-macro-dep-files/Makefile b/src/test/run-make/rustc-macro-dep-files/Makefile index d27b5d0f3c4..e3a6776c808 100644 --- a/src/test/run-make/rustc-macro-dep-files/Makefile +++ b/src/test/run-make/rustc-macro-dep-files/Makefile @@ -3,4 +3,4 @@ all: $(RUSTC) foo.rs $(RUSTC) bar.rs --emit dep-info - grep "rustc-macro source" $(TMPDIR)/bar.d && exit 1 || exit 0 + grep "proc-macro source" $(TMPDIR)/bar.d && exit 1 || exit 0 diff --git a/src/test/run-make/rustc-macro-dep-files/bar.rs b/src/test/run-make/rustc-macro-dep-files/bar.rs index dac652797e6..a2db98049d2 100644 --- a/src/test/run-make/rustc-macro-dep-files/bar.rs +++ b/src/test/run-make/rustc-macro-dep-files/bar.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(rustc_macro)] +#![feature(proc_macro)] #[macro_use] extern crate foo; diff --git a/src/test/run-make/rustc-macro-dep-files/foo.rs b/src/test/run-make/rustc-macro-dep-files/foo.rs index c302ca824d0..bd9e9158c50 100644 --- a/src/test/run-make/rustc-macro-dep-files/foo.rs +++ b/src/test/run-make/rustc-macro-dep-files/foo.rs @@ -8,15 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] +#![crate_type = "proc-macro"] +#![feature(proc_macro)] +#![feature(proc_macro_lib)] -extern crate rustc_macro; +extern crate proc_macro; -use rustc_macro::TokenStream; +use proc_macro::TokenStream; -#[rustc_macro_derive(A)] +#[proc_macro_derive(A)] pub fn derive(input: TokenStream) -> TokenStream { let input = input.to_string(); assert!(input.contains("struct A;")); diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs index 6aee63e2858..78589546084 100644 --- a/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs @@ -12,13 +12,13 @@ #![feature(plugin)] #![feature(plugin_registrar)] #![feature(rustc_private)] -#![plugin(proc_macro)] +#![plugin(proc_macro_plugin)] extern crate rustc_plugin; -extern crate proc_macro; +extern crate proc_macro_plugin; extern crate syntax; -use proc_macro::build::ident_eq; +use proc_macro_plugin::build::ident_eq; use syntax::ext::base::{ExtCtxt, MacResult}; use syntax::ext::proc_macro_shim::build_block_emitter; diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs index 8291c8a1e41..11322bf76ff 100644 --- a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs @@ -12,13 +12,13 @@ #![feature(plugin)] #![feature(plugin_registrar)] #![feature(rustc_private)] -#![plugin(proc_macro)] +#![plugin(proc_macro_plugin)] extern crate rustc_plugin; -extern crate proc_macro; +extern crate proc_macro_plugin; extern crate syntax; -use proc_macro::prelude::*; +use proc_macro_plugin::prelude::*; use rustc_plugin::Registry; diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs index 2d92a0ef181..232a7166e3b 100644 --- a/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs +++ b/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs @@ -12,14 +12,14 @@ #![feature(plugin)] #![feature(plugin_registrar)] #![feature(rustc_private)] -#![plugin(proc_macro)] +#![plugin(proc_macro_plugin)] extern crate rustc_plugin; -extern crate proc_macro; +extern crate proc_macro_plugin; extern crate syntax; use syntax::ext::proc_macro_shim::prelude::*; -use proc_macro::prelude::*; +use proc_macro_plugin::prelude::*; use rustc_plugin::Registry; diff --git a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs index 52c38a6ee03..961df6d5c0c 100644 --- a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs +++ b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs @@ -10,11 +10,11 @@ #![feature(plugin, plugin_registrar, rustc_private)] -extern crate proc_macro; +extern crate proc_macro_plugin; extern crate rustc_plugin; extern crate syntax; -use proc_macro::prelude::*; +use proc_macro_plugin::prelude::*; use rustc_plugin::Registry; use syntax::ext::base::SyntaxExtension; use syntax::ext::proc_macro_shim::prelude::*; diff --git a/src/test/run-pass-fulldeps/macro-quote-1.rs b/src/test/run-pass-fulldeps/macro-quote-1.rs index 4ee775dec0c..a5ac546cba4 100644 --- a/src/test/run-pass-fulldeps/macro-quote-1.rs +++ b/src/test/run-pass-fulldeps/macro-quote-1.rs @@ -12,10 +12,10 @@ #![feature(plugin)] #![feature(rustc_private)] -#![plugin(proc_macro)] +#![plugin(proc_macro_plugin)] -extern crate proc_macro; -use proc_macro::prelude::*; +extern crate proc_macro_plugin; +use proc_macro_plugin::prelude::*; extern crate syntax; use syntax::ast::Ident; diff --git a/src/test/run-pass-fulldeps/proc-macro/add-impl.rs b/src/test/run-pass-fulldeps/proc-macro/add-impl.rs new file mode 100644 index 00000000000..e82282f3d8c --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/add-impl.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:add-impl.rs + +#![feature(proc_macro)] + +#[macro_use] +extern crate add_impl; + +#[derive(AddImpl)] +struct B; + +fn main() { + B.foo(); + foo(); + bar::foo(); +} diff --git a/src/test/run-pass-fulldeps/proc-macro/append-impl.rs b/src/test/run-pass-fulldeps/proc-macro/append-impl.rs new file mode 100644 index 00000000000..f062111df9d --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/append-impl.rs @@ -0,0 +1,32 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:append-impl.rs + +#![feature(proc_macro)] +#![allow(warnings)] + +#[macro_use] +extern crate append_impl; + +trait Append { + fn foo(&self); +} + +#[derive(PartialEq, + Append, + Eq)] +struct A { + inner: u32, +} + +fn main() { + A { inner: 3 }.foo(); +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs new file mode 100644 index 00000000000..99586b0bb49 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/add-impl.rs @@ -0,0 +1,33 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] +#![feature(proc_macro_lib)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(AddImpl)] +// #[cfg(proc_macro)] +pub fn derive(input: TokenStream) -> TokenStream { + (input.to_string() + " + impl B { + fn foo(&self) {} + } + + fn foo() {} + + mod bar { pub fn foo() {} } + ").parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs new file mode 100644 index 00000000000..27c3d643ca4 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/append-impl.rs @@ -0,0 +1,31 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host +// no-prefer-dynamic + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(Append)] +pub fn derive_a(input: TokenStream) -> TokenStream { + let mut input = input.to_string(); + input.push_str(" + impl Append for A { + fn foo(&self) {} + } + "); + input.parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs new file mode 100644 index 00000000000..c2de173568b --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-a.rs @@ -0,0 +1,27 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] +#![feature(proc_macro_lib)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert!(input.contains("struct A;")); + assert!(input.contains("#[derive(Debug, PartialEq, Eq, Copy, Clone)]")); + "#[derive(Debug, PartialEq, Eq, Copy, Clone)] struct A;".parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs new file mode 100644 index 00000000000..b9e31fc3329 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-atob.rs @@ -0,0 +1,26 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] +#![feature(proc_macro_lib)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(AToB)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert_eq!(input, "struct A;\n"); + "struct B;".parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs new file mode 100644 index 00000000000..50f1a390b29 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-ctod.rs @@ -0,0 +1,26 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] +#![feature(proc_macro_lib)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(CToD)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert_eq!(input, "struct C;\n"); + "struct D;".parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs new file mode 100644 index 00000000000..bd283ca57eb --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/derive-same-struct.rs @@ -0,0 +1,32 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic +// compile-flags:--crate-type proc-macro + +#![feature(proc_macro)] +#![feature(proc_macro_lib)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(AToB)] +pub fn derive1(input: TokenStream) -> TokenStream { + println!("input1: {:?}", input.to_string()); + assert_eq!(input.to_string(), "#[derive(BToC)]\nstruct A;\n"); + "#[derive(BToC)] struct B;".parse().unwrap() +} + +#[proc_macro_derive(BToC)] +pub fn derive2(input: TokenStream) -> TokenStream { + assert_eq!(input.to_string(), "struct B;\n"); + "struct C;".parse().unwrap() +} diff --git a/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs b/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs new file mode 100644 index 00000000000..155b125690c --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/auxiliary/expand-with-a-macro.rs @@ -0,0 +1,36 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![deny(warnings)] + +extern crate proc_macro; + +use proc_macro::TokenStream; + +#[proc_macro_derive(A)] +pub fn derive(input: TokenStream) -> TokenStream { + let input = input.to_string(); + assert!(input.contains("struct A;")); + r#" + struct A; + + impl A { + fn a(&self) { + panic!("hello"); + } + } + "#.parse().unwrap() +} + diff --git a/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs new file mode 100644 index 00000000000..b3edc8f1c31 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/derive-same-struct.rs @@ -0,0 +1,23 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-same-struct.rs + +#![feature(proc_macro)] + +#[macro_use] +extern crate derive_same_struct; + +#[derive(AToB, BToC)] +struct A; + +fn main() { + C; +} diff --git a/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs b/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs new file mode 100644 index 00000000000..16f3535adae --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/expand-with-a-macro.rs @@ -0,0 +1,30 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:expand-with-a-macro.rs +// ignore-stage1 + +#![feature(proc_macro)] +#![deny(warnings)] + +#[macro_use] +extern crate expand_with_a_macro; + +use std::panic; + +#[derive(A)] +struct A; + +fn main() { + assert!(panic::catch_unwind(|| { + A.a(); + }).is_err()); +} + diff --git a/src/test/run-pass-fulldeps/proc-macro/load-two.rs b/src/test/run-pass-fulldeps/proc-macro/load-two.rs new file mode 100644 index 00000000000..56f9768764c --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/load-two.rs @@ -0,0 +1,30 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-atob.rs +// aux-build:derive-ctod.rs + +#![feature(proc_macro)] + +#[macro_use] +extern crate derive_atob; +#[macro_use] +extern crate derive_ctod; + +#[derive(AToB)] +struct A; + +#[derive(CToD)] +struct C; + +fn main() { + B; + D; +} diff --git a/src/test/run-pass-fulldeps/proc-macro/smoke.rs b/src/test/run-pass-fulldeps/proc-macro/smoke.rs new file mode 100644 index 00000000000..cd7edb72644 --- /dev/null +++ b/src/test/run-pass-fulldeps/proc-macro/smoke.rs @@ -0,0 +1,29 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// aux-build:derive-a.rs +// ignore-stage1 + +#![feature(proc_macro)] + +#[macro_use] +extern crate derive_a; + +#[derive(Debug, PartialEq, A, Eq, Copy, Clone)] +struct A; + +fn main() { + A; + assert_eq!(A, A); + A.clone(); + let a = A; + let _c = a; + let _d = a; +} diff --git a/src/test/run-pass-fulldeps/rustc-macro/add-impl.rs b/src/test/run-pass-fulldeps/rustc-macro/add-impl.rs deleted file mode 100644 index 226c082564a..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/add-impl.rs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:add-impl.rs - -#![feature(rustc_macro)] - -#[macro_use] -extern crate add_impl; - -#[derive(AddImpl)] -struct B; - -fn main() { - B.foo(); - foo(); - bar::foo(); -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/append-impl.rs b/src/test/run-pass-fulldeps/rustc-macro/append-impl.rs deleted file mode 100644 index b7025c61fb6..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/append-impl.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:append-impl.rs - -#![feature(rustc_macro)] -#![allow(warnings)] - -#[macro_use] -extern crate append_impl; - -trait Append { - fn foo(&self); -} - -#[derive(PartialEq, - Append, - Eq)] -struct A { - inner: u32, -} - -fn main() { - A { inner: 3 }.foo(); -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/add-impl.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/add-impl.rs deleted file mode 100644 index 8aab423af0a..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/add-impl.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(AddImpl)] -// #[cfg(rustc_macro)] -pub fn derive(input: TokenStream) -> TokenStream { - (input.to_string() + " - impl B { - fn foo(&self) {} - } - - fn foo() {} - - mod bar { pub fn foo() {} } - ").parse().unwrap() -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/append-impl.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/append-impl.rs deleted file mode 100644 index c3d295e02c1..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/append-impl.rs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// force-host -// no-prefer-dynamic - -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![crate_type = "rustc-macro"] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(Append)] -pub fn derive_a(input: TokenStream) -> TokenStream { - let mut input = input.to_string(); - input.push_str(" - impl Append for A { - fn foo(&self) {} - } - "); - input.parse().unwrap() -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs deleted file mode 100644 index 42155383dec..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-a.rs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(A)] -pub fn derive(input: TokenStream) -> TokenStream { - let input = input.to_string(); - assert!(input.contains("struct A;")); - assert!(input.contains("#[derive(Debug, PartialEq, Eq, Copy, Clone)]")); - "#[derive(Debug, PartialEq, Eq, Copy, Clone)] struct A;".parse().unwrap() -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-atob.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-atob.rs deleted file mode 100644 index 5b85e2b2a7c..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-atob.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(AToB)] -pub fn derive(input: TokenStream) -> TokenStream { - let input = input.to_string(); - assert_eq!(input, "struct A;\n"); - "struct B;".parse().unwrap() -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-ctod.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-ctod.rs deleted file mode 100644 index 54f8dff509a..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-ctod.rs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(CToD)] -pub fn derive(input: TokenStream) -> TokenStream { - let input = input.to_string(); - assert_eq!(input, "struct C;\n"); - "struct D;".parse().unwrap() -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-same-struct.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-same-struct.rs deleted file mode 100644 index d83e352e3b1..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/derive-same-struct.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic -// compile-flags:--crate-type rustc-macro - -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(AToB)] -pub fn derive1(input: TokenStream) -> TokenStream { - println!("input1: {:?}", input.to_string()); - assert_eq!(input.to_string(), "#[derive(BToC)]\nstruct A;\n"); - "#[derive(BToC)] struct B;".parse().unwrap() -} - -#[rustc_macro_derive(BToC)] -pub fn derive2(input: TokenStream) -> TokenStream { - assert_eq!(input.to_string(), "struct B;\n"); - "struct C;".parse().unwrap() -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/expand-with-a-macro.rs b/src/test/run-pass-fulldeps/rustc-macro/auxiliary/expand-with-a-macro.rs deleted file mode 100644 index 96aea407e6e..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/auxiliary/expand-with-a-macro.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// no-prefer-dynamic - -#![crate_type = "rustc-macro"] -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![deny(warnings)] - -extern crate rustc_macro; - -use rustc_macro::TokenStream; - -#[rustc_macro_derive(A)] -pub fn derive(input: TokenStream) -> TokenStream { - let input = input.to_string(); - assert!(input.contains("struct A;")); - r#" - struct A; - - impl A { - fn a(&self) { - panic!("hello"); - } - } - "#.parse().unwrap() -} - diff --git a/src/test/run-pass-fulldeps/rustc-macro/derive-same-struct.rs b/src/test/run-pass-fulldeps/rustc-macro/derive-same-struct.rs deleted file mode 100644 index ee0d5945648..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/derive-same-struct.rs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-same-struct.rs - -#![feature(rustc_macro)] - -#[macro_use] -extern crate derive_same_struct; - -#[derive(AToB, BToC)] -struct A; - -fn main() { - C; -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/expand-with-a-macro.rs b/src/test/run-pass-fulldeps/rustc-macro/expand-with-a-macro.rs deleted file mode 100644 index cc59be2d75d..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/expand-with-a-macro.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:expand-with-a-macro.rs -// ignore-stage1 - -#![feature(rustc_macro)] -#![deny(warnings)] - -#[macro_use] -extern crate expand_with_a_macro; - -use std::panic; - -#[derive(A)] -struct A; - -fn main() { - assert!(panic::catch_unwind(|| { - A.a(); - }).is_err()); -} - diff --git a/src/test/run-pass-fulldeps/rustc-macro/load-two.rs b/src/test/run-pass-fulldeps/rustc-macro/load-two.rs deleted file mode 100644 index 1500970f02d..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/load-two.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-atob.rs -// aux-build:derive-ctod.rs - -#![feature(rustc_macro)] - -#[macro_use] -extern crate derive_atob; -#[macro_use] -extern crate derive_ctod; - -#[derive(AToB)] -struct A; - -#[derive(CToD)] -struct C; - -fn main() { - B; - D; -} diff --git a/src/test/run-pass-fulldeps/rustc-macro/smoke.rs b/src/test/run-pass-fulldeps/rustc-macro/smoke.rs deleted file mode 100644 index 588380f1140..00000000000 --- a/src/test/run-pass-fulldeps/rustc-macro/smoke.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -// aux-build:derive-a.rs -// ignore-stage1 - -#![feature(rustc_macro)] - -#[macro_use] -extern crate derive_a; - -#[derive(Debug, PartialEq, A, Eq, Copy, Clone)] -struct A; - -fn main() { - A; - assert_eq!(A, A); - A.clone(); - let a = A; - let _c = a; - let _d = a; -} diff --git a/src/test/rustdoc/rustc-macro-crate.rs b/src/test/rustdoc/rustc-macro-crate.rs index c8bf5b2b912..fe80a909550 100644 --- a/src/test/rustdoc/rustc-macro-crate.rs +++ b/src/test/rustdoc/rustc-macro-crate.rs @@ -10,15 +10,15 @@ // no-prefer-dynamic -#![feature(rustc_macro)] -#![feature(rustc_macro_lib)] -#![crate_type = "rustc-macro"] +#![feature(proc_macro)] +#![feature(proc_macro_lib)] +#![crate_type = "proc-macro"] -extern crate rustc_macro; +extern crate proc_macro; -use rustc_macro::TokenStream; +use proc_macro::TokenStream; -#[rustc_macro_derive(Foo)] +#[proc_macro_derive(Foo)] pub fn foo(input: TokenStream) -> TokenStream { input } diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs index 354cce69127..633ff6271b7 100644 --- a/src/tools/cargotest/main.rs +++ b/src/tools/cargotest/main.rs @@ -24,7 +24,7 @@ struct Test { const TEST_REPOS: &'static [Test] = &[Test { name: "cargo", repo: "https://github.com/rust-lang/cargo", - sha: "d8936af1390ab0844e5e68b459214f2529c9f647", + sha: "d3bad1ab29efae414e9b4c24534b2d02b3a59782", lock: None, }, Test { diff --git a/src/tools/tidy/src/cargo.rs b/src/tools/tidy/src/cargo.rs index 4932fd5147a..a7784e65c5b 100644 --- a/src/tools/tidy/src/cargo.rs +++ b/src/tools/tidy/src/cargo.rs @@ -88,9 +88,11 @@ fn verify(tomlfile: &Path, libfile: &Path, bad: &mut bool) { continue } - // We want the compiler to depend on the proc_macro crate so that it is built and - // included in the end, but we don't want to actually use it in the compiler. - if toml.contains("name = \"rustc_driver\"") && krate == "proc_macro" { + // We want the compiler to depend on the proc_macro_plugin crate so + // that it is built and included in the end, but we don't want to + // actually use it in the compiler. + if toml.contains("name = \"rustc_driver\"") && + krate == "proc_macro_plugin" { continue } -- cgit 1.4.1-3-g733a5