Auto merge of #36444 - jseyfried:macro_rules_ext, r=nrc
Remove variant `MacroRulesTT` of `SyntaxExtension` r? @nrc
This commit is contained in:
commit
d4037fc476
9 changed files with 63 additions and 114 deletions
|
|
@ -674,11 +674,11 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
|
|||
}
|
||||
let features = sess.features.borrow();
|
||||
let cfg = syntax::ext::expand::ExpansionConfig {
|
||||
crate_name: crate_name.to_string(),
|
||||
features: Some(&features),
|
||||
recursion_limit: sess.recursion_limit.get(),
|
||||
trace_mac: sess.opts.debugging_opts.trace_macros,
|
||||
should_test: sess.opts.test,
|
||||
..syntax::ext::expand::ExpansionConfig::default(crate_name.to_string())
|
||||
};
|
||||
let mut ecx = ExtCtxt::new(&sess.parse_sess, krate.config.clone(), cfg, &mut resolver);
|
||||
let ret = syntax::ext::expand::expand_crate(&mut ecx, syntax_exts, krate);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use rustc::mir::transform::MirMapPass;
|
|||
|
||||
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
|
||||
use syntax::ext::base::{IdentTT, MultiModifier, MultiDecorator};
|
||||
use syntax::ext::base::{MacroExpanderFn, MacroRulesTT};
|
||||
use syntax::ext::base::MacroExpanderFn;
|
||||
use syntax::parse::token;
|
||||
use syntax::ast;
|
||||
use syntax::feature_gate::AttributeType;
|
||||
|
|
@ -111,10 +111,6 @@ impl<'a> Registry<'a> {
|
|||
}
|
||||
MultiDecorator(ext) => MultiDecorator(ext),
|
||||
MultiModifier(ext) => MultiModifier(ext),
|
||||
MacroRulesTT => {
|
||||
self.sess.err("plugin tried to register a new MacroRulesTT");
|
||||
return;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,8 @@ pub trait IdentMacroExpander {
|
|||
cx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
ident: ast::Ident,
|
||||
token_tree: Vec<tokenstream::TokenTree> )
|
||||
token_tree: Vec<tokenstream::TokenTree>,
|
||||
attrs: Vec<ast::Attribute>)
|
||||
-> Box<MacResult+'cx>;
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +194,8 @@ impl<F> IdentMacroExpander for F
|
|||
cx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
ident: ast::Ident,
|
||||
token_tree: Vec<tokenstream::TokenTree> )
|
||||
token_tree: Vec<tokenstream::TokenTree>,
|
||||
_attrs: Vec<ast::Attribute>)
|
||||
-> Box<MacResult+'cx>
|
||||
{
|
||||
(*self)(cx, sp, ident, token_tree)
|
||||
|
|
@ -455,9 +457,6 @@ pub enum SyntaxExtension {
|
|||
/// the block.
|
||||
///
|
||||
IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>, bool),
|
||||
|
||||
/// Represents `macro_rules!` itself.
|
||||
MacroRulesTT,
|
||||
}
|
||||
|
||||
pub type NamedSyntaxExtension = (Name, SyntaxExtension);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use ast::{Block, Crate, Ident, Mac_, PatKind};
|
|||
use ast::{MacStmtStyle, StmtKind, ItemKind};
|
||||
use ast;
|
||||
use ext::hygiene::Mark;
|
||||
use ext::placeholders::{self, placeholder, PlaceholderExpander};
|
||||
use ext::placeholders::{placeholder, PlaceholderExpander};
|
||||
use attr::{self, HasAttrs};
|
||||
use codemap::{ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
|
||||
use syntax_pos::{self, Span, ExpnId};
|
||||
|
|
@ -173,19 +173,12 @@ impl Invocation {
|
|||
|
||||
pub struct MacroExpander<'a, 'b:'a> {
|
||||
pub cx: &'a mut ExtCtxt<'b>,
|
||||
pub single_step: bool,
|
||||
pub keep_macs: bool,
|
||||
monotonic: bool, // c.f. `cx.monotonic_expander()`
|
||||
}
|
||||
|
||||
impl<'a, 'b> MacroExpander<'a, 'b> {
|
||||
pub fn new(cx: &'a mut ExtCtxt<'b>, monotonic: bool) -> Self {
|
||||
MacroExpander {
|
||||
cx: cx,
|
||||
monotonic: monotonic,
|
||||
single_step: false,
|
||||
keep_macs: false,
|
||||
}
|
||||
MacroExpander { cx: cx, monotonic: monotonic }
|
||||
}
|
||||
|
||||
fn expand_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
|
||||
|
|
@ -238,7 +231,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
expansions.push(Vec::new());
|
||||
}
|
||||
expansions[depth].push((mark.as_u32(), expansion));
|
||||
if !self.single_step {
|
||||
if !self.cx.ecfg.single_step {
|
||||
invocations.extend(new_invocations.into_iter().rev());
|
||||
}
|
||||
}
|
||||
|
|
@ -381,47 +374,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
}
|
||||
});
|
||||
|
||||
kind.make_from(expander.expand(self.cx, span, ident, marked_tts))
|
||||
}
|
||||
|
||||
MacroRulesTT => {
|
||||
if ident.name == keywords::Invalid.name() {
|
||||
self.cx.span_err(path.span,
|
||||
&format!("macro {}! expects an ident argument", extname));
|
||||
return kind.dummy(span);
|
||||
};
|
||||
|
||||
self.cx.bt_push(ExpnInfo {
|
||||
call_site: span,
|
||||
callee: NameAndSpan {
|
||||
format: MacroBang(extname),
|
||||
span: None,
|
||||
// `macro_rules!` doesn't directly allow unstable
|
||||
// (this is orthogonal to whether the macro it creates allows it)
|
||||
allow_internal_unstable: false,
|
||||
}
|
||||
});
|
||||
|
||||
let def = ast::MacroDef {
|
||||
ident: ident,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: span,
|
||||
imported_from: None,
|
||||
use_locally: true,
|
||||
body: marked_tts,
|
||||
export: attr::contains_name(&attrs, "macro_export"),
|
||||
allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
|
||||
attrs: attrs,
|
||||
};
|
||||
|
||||
self.cx.insert_macro(def.clone());
|
||||
|
||||
// If keep_macs is true, expands to a MacEager::items instead.
|
||||
if self.keep_macs {
|
||||
Some(placeholders::reconstructed_macro_rules(&def, &path))
|
||||
} else {
|
||||
Some(placeholders::macro_scope_placeholder())
|
||||
}
|
||||
kind.make_from(expander.expand(self.cx, span, ident, marked_tts, attrs))
|
||||
}
|
||||
|
||||
MultiDecorator(..) | MultiModifier(..) => {
|
||||
|
|
@ -726,6 +679,8 @@ pub struct ExpansionConfig<'feat> {
|
|||
pub recursion_limit: usize,
|
||||
pub trace_mac: bool,
|
||||
pub should_test: bool, // If false, strip `#[test]` nodes
|
||||
pub single_step: bool,
|
||||
pub keep_macs: bool,
|
||||
}
|
||||
|
||||
macro_rules! feature_tests {
|
||||
|
|
@ -749,6 +704,8 @@ impl<'feat> ExpansionConfig<'feat> {
|
|||
recursion_limit: 64,
|
||||
trace_mac: false,
|
||||
should_test: false,
|
||||
single_step: false,
|
||||
keep_macs: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use codemap::{DUMMY_SP, dummy_spanned};
|
|||
use ext::base::ExtCtxt;
|
||||
use ext::expand::{Expansion, ExpansionKind};
|
||||
use fold::*;
|
||||
use parse::token::keywords;
|
||||
use parse::token::{intern, keywords};
|
||||
use ptr::P;
|
||||
use util::move_map::MoveMap;
|
||||
use util::small_vector::SmallVector;
|
||||
|
|
@ -214,7 +214,7 @@ impl<'a, 'b> Folder for PlaceholderExpander<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn reconstructed_macro_rules(def: &ast::MacroDef, path: &ast::Path) -> Expansion {
|
||||
pub fn reconstructed_macro_rules(def: &ast::MacroDef) -> Expansion {
|
||||
Expansion::Items(SmallVector::one(P(ast::Item {
|
||||
ident: def.ident,
|
||||
attrs: def.attrs.clone(),
|
||||
|
|
@ -222,7 +222,14 @@ pub fn reconstructed_macro_rules(def: &ast::MacroDef, path: &ast::Path) -> Expan
|
|||
node: ast::ItemKind::Mac(ast::Mac {
|
||||
span: def.span,
|
||||
node: ast::Mac_ {
|
||||
path: path.clone(),
|
||||
path: ast::Path {
|
||||
span: DUMMY_SP,
|
||||
global: false,
|
||||
segments: vec![ast::PathSegment {
|
||||
identifier: ast::Ident::with_empty_ctxt(intern("macro_rules")),
|
||||
parameters: ast::PathParameters::none(),
|
||||
}],
|
||||
},
|
||||
tts: def.body.clone(),
|
||||
}
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -8,10 +8,11 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use ast;
|
||||
use {ast, attr};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
|
||||
use ext::base::{NormalTT, TTMacroExpander};
|
||||
use ext::base::{DummyResult, ExtCtxt, MacEager, MacResult, SyntaxExtension};
|
||||
use ext::base::{IdentMacroExpander, NormalTT, TTMacroExpander};
|
||||
use ext::placeholders;
|
||||
use ext::tt::macro_parser::{Success, Error, Failure};
|
||||
use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
|
||||
use ext::tt::macro_parser::parse;
|
||||
|
|
@ -242,6 +243,38 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
|
|||
cx.span_fatal(best_fail_spot.substitute_dummy(sp), &best_fail_msg[..]);
|
||||
}
|
||||
|
||||
pub struct MacroRulesExpander;
|
||||
impl IdentMacroExpander for MacroRulesExpander {
|
||||
fn expand(&self,
|
||||
cx: &mut ExtCtxt,
|
||||
span: Span,
|
||||
ident: ast::Ident,
|
||||
tts: Vec<tokenstream::TokenTree>,
|
||||
attrs: Vec<ast::Attribute>)
|
||||
-> Box<MacResult> {
|
||||
let def = ast::MacroDef {
|
||||
ident: ident,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
span: span,
|
||||
imported_from: None,
|
||||
use_locally: true,
|
||||
body: tts,
|
||||
export: attr::contains_name(&attrs, "macro_export"),
|
||||
allow_internal_unstable: attr::contains_name(&attrs, "allow_internal_unstable"),
|
||||
attrs: attrs,
|
||||
};
|
||||
|
||||
cx.insert_macro(def.clone());
|
||||
|
||||
// If keep_macs is true, expands to a MacEager::items instead.
|
||||
if cx.ecfg.keep_macs {
|
||||
MacEager::items(placeholders::reconstructed_macro_rules(&def).make_items())
|
||||
} else {
|
||||
MacEager::items(placeholders::macro_scope_placeholder().make_items())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note that macro-by-example's input is also matched against a token tree:
|
||||
// $( $lhs:tt => $rhs:tt );+
|
||||
//
|
||||
|
|
|
|||
|
|
@ -50,8 +50,9 @@ pub mod deriving;
|
|||
|
||||
use std::rc::Rc;
|
||||
use syntax::ast;
|
||||
use syntax::ext::base::{MacroExpanderFn, MacroRulesTT, NormalTT, MultiModifier};
|
||||
use syntax::ext::base::{MacroExpanderFn, NormalTT, IdentTT, MultiModifier};
|
||||
use syntax::ext::hygiene::Mark;
|
||||
use syntax::ext::tt::macro_rules::MacroRulesExpander;
|
||||
use syntax::parse::token::intern;
|
||||
|
||||
pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, enable_quotes: bool) {
|
||||
|
|
@ -59,7 +60,7 @@ pub fn register_builtins(resolver: &mut syntax::ext::base::Resolver, enable_quot
|
|||
resolver.add_macro(Mark::root(), ast::Ident::with_empty_ctxt(intern(name)), Rc::new(ext));
|
||||
};
|
||||
|
||||
register("macro_rules", MacroRulesTT);
|
||||
register("macro_rules", IdentTT(Box::new(MacroRulesExpander), None, false));
|
||||
|
||||
macro_rules! register {
|
||||
($( $name:ident: $f:expr, )*) => { $(
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
// Copyright 2014 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.
|
||||
|
||||
// force-host
|
||||
|
||||
#![feature(plugin_registrar, rustc_private)]
|
||||
|
||||
extern crate syntax;
|
||||
extern crate rustc;
|
||||
extern crate rustc_plugin;
|
||||
|
||||
use syntax::parse::token;
|
||||
use syntax::ext::base::MacroRulesTT;
|
||||
use rustc_plugin::Registry;
|
||||
|
||||
#[plugin_registrar]
|
||||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
reg.register_syntax_extension(token::intern("bogus"), MacroRulesTT);
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright 2014 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:macro_crate_MacroRulesTT.rs
|
||||
// ignore-stage1
|
||||
// error-pattern: plugin tried to register a new MacroRulesTT
|
||||
|
||||
#![feature(plugin)]
|
||||
#![plugin(macro_crate_MacroRulesTT)]
|
||||
|
||||
fn main() { }
|
||||
Loading…
Add table
Add a link
Reference in a new issue