Auto merge of #36154 - nrc:proc-macro-init, r=@jseyfried

Adds a `ProcMacro` form of syntax extension

This commit adds syntax extension forms matching the types for procedural macros 2.0 (RFC #1566), these still require the usual syntax extension boiler plate, but this is a first step towards proper implementation and should be useful for macros 1.1 stuff too.

Supports both attribute-like and function-like macros.

Note that RFC #1566 has not been accepted yet, but I think there is consensus that we want to head in vaguely that direction and so this PR will be useful in any case. It is also fairly easy to undo and does not break any existing programs.

This is related to #35957 in that I hope it can be used in the implementation of macros 1.1, however, there is no direct overlap and is more of a complement than a competing proposal. There is still a fair bit of work to do before the two can be combined.

r? @jseyfried

cc @alexcrichton, @cgswords, @eddyb, @aturon
This commit is contained in:
bors 2016-09-22 16:33:41 -07:00 committed by GitHub
commit 3a5d975fdc
12 changed files with 472 additions and 49 deletions

View file

@ -0,0 +1,56 @@
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(plugin, plugin_registrar, rustc_private)]
extern crate proc_macro;
extern crate rustc_plugin;
extern crate syntax;
use proc_macro::prelude::*;
use rustc_plugin::Registry;
use syntax::ext::base::SyntaxExtension;
use syntax::ext::proc_macro_shim::prelude::*;
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_syntax_extension(token::intern("attr_tru"),
SyntaxExtension::AttrProcMacro(Box::new(attr_tru)));
reg.register_syntax_extension(token::intern("attr_identity"),
SyntaxExtension::AttrProcMacro(Box::new(attr_identity)));
reg.register_syntax_extension(token::intern("tru"),
SyntaxExtension::ProcMacro(Box::new(tru)));
reg.register_syntax_extension(token::intern("ret_tru"),
SyntaxExtension::ProcMacro(Box::new(ret_tru)));
reg.register_syntax_extension(token::intern("identity"),
SyntaxExtension::ProcMacro(Box::new(identity)));
}
fn attr_tru(_attr: TokenStream, _item: TokenStream) -> TokenStream {
lex("fn f1() -> bool { true }")
}
fn attr_identity(_attr: TokenStream, item: TokenStream) -> TokenStream {
let source = item.to_string();
lex(&source)
}
fn tru(_ts: TokenStream) -> TokenStream {
lex("true")
}
fn ret_tru(_ts: TokenStream) -> TokenStream {
lex("return true;")
}
fn identity(ts: TokenStream) -> TokenStream {
let source = ts.to_string();
lex(&source)
}

View file

@ -0,0 +1,48 @@
// 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// aux-build:proc_macro_def.rs
// ignore-stage1
// ignore-cross-compile
#![feature(plugin, custom_attribute)]
#![feature(type_macros)]
#![plugin(proc_macro_def)]
#[attr_tru]
fn f1() -> bool {
return false;
}
#[attr_identity]
fn f2() -> bool {
return identity!(true);
}
fn f3() -> identity!(bool) {
ret_tru!();
}
fn f4(x: bool) -> bool {
match x {
identity!(true) => false,
identity!(false) => true,
}
}
fn main() {
assert!(f1());
assert!(f2());
assert!(tru!());
assert!(f3());
assert!(identity!(5 == 5));
assert!(f4(false));
}