Skip to content

Commit

Permalink
Pass crate editions to macro expansions, update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
petrochenkov committed May 17, 2018
1 parent 76bf345 commit f4cbc23
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 65 deletions.
24 changes: 15 additions & 9 deletions src/librustc_metadata/creader.rs
Expand Up @@ -35,6 +35,7 @@ use std::{cmp, fs};

use syntax::ast;
use syntax::attr;
use syntax::edition::Edition;
use syntax::ext::base::SyntaxExtension;
use syntax::symbol::Symbol;
use syntax::visit;
Expand Down Expand Up @@ -535,7 +536,10 @@ impl<'a> CrateLoader<'a> {
mem::transmute::<*mut u8, fn(&mut Registry)>(sym)
};

struct MyRegistrar(Vec<(ast::Name, Lrc<SyntaxExtension>)>);
struct MyRegistrar {
extensions: Vec<(ast::Name, Lrc<SyntaxExtension>)>,
edition: Edition,
}

impl Registry for MyRegistrar {
fn register_custom_derive(&mut self,
Expand All @@ -544,36 +548,38 @@ impl<'a> CrateLoader<'a> {
attributes: &[&'static str]) {
let attrs = attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
let derive = ProcMacroDerive::new(expand, attrs.clone());
let derive = SyntaxExtension::ProcMacroDerive(Box::new(derive), attrs);
self.0.push((Symbol::intern(trait_name), Lrc::new(derive)));
let derive = SyntaxExtension::ProcMacroDerive(
Box::new(derive), attrs, self.edition
);
self.extensions.push((Symbol::intern(trait_name), Lrc::new(derive)));
}

fn register_attr_proc_macro(&mut self,
name: &str,
expand: fn(TokenStream, TokenStream) -> TokenStream) {
let expand = SyntaxExtension::AttrProcMacro(
Box::new(AttrProcMacro { inner: expand })
Box::new(AttrProcMacro { inner: expand }), self.edition
);
self.0.push((Symbol::intern(name), Lrc::new(expand)));
self.extensions.push((Symbol::intern(name), Lrc::new(expand)));
}

fn register_bang_proc_macro(&mut self,
name: &str,
expand: fn(TokenStream) -> TokenStream) {
let expand = SyntaxExtension::ProcMacro(
Box::new(BangProcMacro { inner: expand })
Box::new(BangProcMacro { inner: expand }), self.edition
);
self.0.push((Symbol::intern(name), Lrc::new(expand)));
self.extensions.push((Symbol::intern(name), Lrc::new(expand)));
}
}

let mut my_registrar = MyRegistrar(Vec::new());
let mut my_registrar = MyRegistrar { extensions: Vec::new(), edition: root.edition };
registrar(&mut my_registrar);

// Intentionally leak the dynamic library. We can't ever unload it
// since the library can make things that will live arbitrarily long.
mem::forget(lib);
my_registrar.0
my_registrar.extensions
}

/// Look for a plugin registrar. Returns library path, crate
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_metadata/cstore_impl.rs
Expand Up @@ -518,7 +518,8 @@ impl CrateStore for cstore::CStore {
return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone());
} else if data.name == "proc_macro" &&
self.get_crate_data(id.krate).item_name(id.index) == "quote" {
let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::__internal::Quoter));
let ext = SyntaxExtension::ProcMacro(Box::new(::proc_macro::__internal::Quoter),
data.edition());
return LoadedMacro::ProcMacro(Lrc::new(ext));
}

Expand Down
8 changes: 6 additions & 2 deletions src/librustc_plugin/registry.rs
Expand Up @@ -15,6 +15,7 @@ use rustc::session::Session;

use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT};
use syntax::ext::base::MacroExpanderFn;
use syntax::ext::hygiene;
use syntax::symbol::Symbol;
use syntax::ast;
use syntax::feature_gate::AttributeType;
Expand Down Expand Up @@ -107,15 +108,17 @@ impl<'a> Registry<'a> {
def_info: _,
allow_internal_unstable,
allow_internal_unsafe,
unstable_feature
unstable_feature,
edition,
} => {
let nid = ast::CRATE_NODE_ID;
NormalTT {
expander,
def_info: Some((nid, self.krate_span)),
allow_internal_unstable,
allow_internal_unsafe,
unstable_feature
unstable_feature,
edition,
}
}
IdentTT(ext, _, allow_internal_unstable) => {
Expand Down Expand Up @@ -150,6 +153,7 @@ impl<'a> Registry<'a> {
allow_internal_unstable: false,
allow_internal_unsafe: false,
unstable_feature: None,
edition: hygiene::default_edition(),
});
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_resolve/build_reduced_graph.rs
Expand Up @@ -588,7 +588,8 @@ impl<'a> Resolver<'a> {

let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess,
&self.session.features_untracked(),
&macro_def));
&macro_def,
self.cstore.crate_edition_untracked(def_id.krate)));
self.macro_map.insert(def_id, ext.clone());
ext
}
Expand Down
17 changes: 9 additions & 8 deletions src/librustc_resolve/macros.rs
Expand Up @@ -24,7 +24,7 @@ use syntax::errors::DiagnosticBuilder;
use syntax::ext::base::{self, Annotatable, Determinacy, MultiModifier, MultiDecorator};
use syntax::ext::base::{MacroKind, SyntaxExtension, Resolver as SyntaxResolver};
use syntax::ext::expand::{Expansion, ExpansionKind, Invocation, InvocationKind, find_attr_invoc};
use syntax::ext::hygiene::{Mark, MarkKind};
use syntax::ext::hygiene::{self, Mark, MarkKind};
use syntax::ext::placeholders::placeholder;
use syntax::ext::tt::macro_rules;
use syntax::feature_gate::{self, emit_feature_err, GateIssue};
Expand Down Expand Up @@ -328,7 +328,7 @@ impl<'a> base::Resolver for Resolver<'a> {
for did in self.unused_macros.iter() {
let id_span = match *self.macro_map[did] {
SyntaxExtension::NormalTT { def_info, .. } => def_info,
SyntaxExtension::DeclMacro(.., osp) => osp,
SyntaxExtension::DeclMacro(.., osp, _) => osp,
_ => None,
};
if let Some((id, span)) = id_span {
Expand Down Expand Up @@ -371,7 +371,7 @@ impl<'a> Resolver<'a> {
};
for path in traits {
match self.resolve_macro(scope, path, MacroKind::Derive, force) {
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs) = *ext {
Ok(ext) => if let SyntaxExtension::ProcMacroDerive(_, ref inert_attrs, _) = *ext {
if inert_attrs.contains(&attr_name) {
// FIXME(jseyfried) Avoid `mem::replace` here.
let dummy_item = placeholder(ExpansionKind::Items, ast::DUMMY_NODE_ID)
Expand Down Expand Up @@ -755,7 +755,7 @@ impl<'a> Resolver<'a> {
let def_id = self.definitions.local_def_id(item.id);
let ext = Lrc::new(macro_rules::compile(&self.session.parse_sess,
&self.session.features_untracked(),
item));
item, hygiene::default_edition()));
self.macro_map.insert(def_id, ext);

let def = match item.node { ast::ItemKind::MacroDef(ref def) => def, _ => unreachable!() };
Expand Down Expand Up @@ -803,14 +803,15 @@ impl<'a> Resolver<'a> {

match *ext {
// If `ext` is a procedural macro, check if we've already warned about it
AttrProcMacro(_) | ProcMacro(_) => if !self.warned_proc_macros.insert(name) { return; },
AttrProcMacro(..) | ProcMacro(..) =>
if !self.warned_proc_macros.insert(name) { return; },
_ => return,
}

let warn_msg = match *ext {
AttrProcMacro(_) => "attribute procedural macros cannot be \
imported with `#[macro_use]`",
ProcMacro(_) => "procedural macros cannot be imported with `#[macro_use]`",
AttrProcMacro(..) => "attribute procedural macros cannot be \
imported with `#[macro_use]`",
ProcMacro(..) => "procedural macros cannot be imported with `#[macro_use]`",
_ => return,
};

Expand Down
31 changes: 24 additions & 7 deletions src/libsyntax/ext/base.rs
Expand Up @@ -14,9 +14,10 @@ use ast::{self, Attribute, Name, PatKind, MetaItem};
use attr::HasAttrs;
use codemap::{self, CodeMap, Spanned, respan};
use syntax_pos::{Span, MultiSpan, DUMMY_SP};
use edition::Edition;
use errors::{DiagnosticBuilder, DiagnosticId};
use ext::expand::{self, Expansion, Invocation};
use ext::hygiene::{Mark, SyntaxContext};
use ext::hygiene::{self, Mark, SyntaxContext};
use fold::{self, Folder};
use parse::{self, parser, DirectoryOwnership};
use parse::token;
Expand Down Expand Up @@ -586,13 +587,13 @@ pub enum SyntaxExtension {
MultiModifier(Box<MultiItemModifier + sync::Sync + sync::Send>),

/// A function-like procedural macro. TokenStream -> TokenStream.
ProcMacro(Box<ProcMacro + sync::Sync + sync::Send>),
ProcMacro(Box<ProcMacro + sync::Sync + sync::Send>, Edition),

/// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream.
/// The first TokenSteam is the attribute, the second is the annotated item.
/// Allows modification of the input items and adding new items, similar to
/// MultiModifier, but uses TokenStreams, rather than AST nodes.
AttrProcMacro(Box<AttrProcMacro + sync::Sync + sync::Send>),
AttrProcMacro(Box<AttrProcMacro + sync::Sync + sync::Send>, Edition),

/// A normal, function-like syntax extension.
///
Expand All @@ -608,6 +609,8 @@ pub enum SyntaxExtension {
allow_internal_unsafe: bool,
/// The macro's feature name if it is unstable, and the stability feature
unstable_feature: Option<(Symbol, u32)>,
/// Edition of the crate in which the macro is defined
edition: Edition,
},

/// A function-like syntax extension that has an extra ident before
Expand All @@ -619,17 +622,16 @@ pub enum SyntaxExtension {
/// The input is the annotated item.
/// Allows generating code to implement a Trait for a given struct
/// or enum item.
ProcMacroDerive(Box<MultiItemModifier +
sync::Sync +
sync::Send>, Vec<Symbol> /* inert attribute names */),
ProcMacroDerive(Box<MultiItemModifier + sync::Sync + sync::Send>,
Vec<Symbol> /* inert attribute names */, Edition),

/// An attribute-like procedural macro that derives a builtin trait.
BuiltinDerive(BuiltinDeriveFn),

/// A declarative macro, e.g. `macro m() {}`.
///
/// The second element is the definition site span.
DeclMacro(Box<TTMacroExpander + sync::Sync + sync::Send>, Option<(ast::NodeId, Span)>),
DeclMacro(Box<TTMacroExpander + sync::Sync + sync::Send>, Option<(ast::NodeId, Span)>, Edition),
}

impl SyntaxExtension {
Expand Down Expand Up @@ -660,6 +662,21 @@ impl SyntaxExtension {
_ => false,
}
}

pub fn edition(&self) -> Edition {
match *self {
SyntaxExtension::NormalTT { edition, .. } |
SyntaxExtension::DeclMacro(.., edition) |
SyntaxExtension::ProcMacro(.., edition) |
SyntaxExtension::AttrProcMacro(.., edition) |
SyntaxExtension::ProcMacroDerive(.., edition) => edition,
// Unstable legacy stuff
SyntaxExtension::IdentTT(..) |
SyntaxExtension::MultiDecorator(..) |
SyntaxExtension::MultiModifier(..) |
SyntaxExtension::BuiltinDerive(..) => hygiene::default_edition(),
}
}
}

pub type NamedSyntaxExtension = (Name, SyntaxExtension);
Expand Down
26 changes: 15 additions & 11 deletions src/libsyntax/ext/expand.rs
Expand Up @@ -502,7 +502,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
span: None,
allow_internal_unstable: false,
allow_internal_unsafe: false,
edition: hygiene::default_edition(),
edition: ext.edition(),
}
});

Expand All @@ -521,7 +521,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
items.push(item);
Some(kind.expect_from_annotatables(items))
}
AttrProcMacro(ref mac) => {
AttrProcMacro(ref mac, ..) => {
self.gate_proc_macro_attr_item(attr.span, &item);
let item_tok = TokenTree::Token(DUMMY_SP, Token::interpolated(match item {
Annotatable::Item(item) => token::NtItem(item),
Expand Down Expand Up @@ -610,7 +610,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
allow_internal_unstable,
allow_internal_unsafe,
// can't infer this type
unstable_feature: Option<(Symbol, u32)>| {
unstable_feature: Option<(Symbol, u32)>,
edition| {

// feature-gate the macro invocation
if let Some((feature, issue)) = unstable_feature {
Expand Down Expand Up @@ -643,16 +644,17 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
span: def_site_span,
allow_internal_unstable,
allow_internal_unsafe,
edition: hygiene::default_edition(),
edition,
},
});
Ok(())
};

let opt_expanded = match *ext {
DeclMacro(ref expand, def_span) => {
DeclMacro(ref expand, def_span, edition) => {
if let Err(dummy_span) = validate_and_set_expn_info(self, def_span.map(|(_, s)| s),
false, false, None) {
false, false, None,
edition) {
dummy_span
} else {
kind.make_from(expand.expand(self.cx, span, mac.node.stream()))
Expand All @@ -665,11 +667,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
allow_internal_unstable,
allow_internal_unsafe,
unstable_feature,
edition,
} => {
if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s),
allow_internal_unstable,
allow_internal_unsafe,
unstable_feature) {
unstable_feature,
edition) {
dummy_span
} else {
kind.make_from(expander.expand(self.cx, span, mac.node.stream()))
Expand Down Expand Up @@ -712,7 +716,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
kind.dummy(span)
}

ProcMacro(ref expandfun) => {
ProcMacro(ref expandfun, edition) => {
if ident.name != keywords::Invalid.name() {
let msg =
format!("macro {}! expects no ident argument, given '{}'", path, ident);
Expand All @@ -731,7 +735,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
// FIXME probably want to follow macro_rules macros here.
allow_internal_unstable: false,
allow_internal_unsafe: false,
edition: hygiene::default_edition(),
edition,
},
});

Expand Down Expand Up @@ -806,12 +810,12 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
span: None,
allow_internal_unstable: false,
allow_internal_unsafe: false,
edition: hygiene::default_edition(),
edition: ext.edition(),
}
};

match *ext {
ProcMacroDerive(ref ext, _) => {
ProcMacroDerive(ref ext, ..) => {
invoc.expansion_data.mark.set_expn_info(expn_info);
let span = span.with_ctxt(self.cx.backtrace());
let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this
Expand Down
9 changes: 6 additions & 3 deletions src/libsyntax/ext/tt/macro_rules.rs
Expand Up @@ -10,6 +10,7 @@

use {ast, attr};
use syntax_pos::{Span, DUMMY_SP};
use edition::Edition;
use ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
use ext::base::{NormalTT, TTMacroExpander};
use ext::expand::{Expansion, ExpansionKind};
Expand Down Expand Up @@ -183,7 +184,8 @@ fn generic_extension<'cx>(cx: &'cx mut ExtCtxt,
// Holy self-referential!

/// Converts a `macro_rules!` invocation into a syntax extension.
pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item) -> SyntaxExtension {
pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item, edition: Edition)
-> SyntaxExtension {
let lhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("lhs"));
let rhs_nm = ast::Ident::with_empty_ctxt(Symbol::gensym("rhs"));

Expand Down Expand Up @@ -298,10 +300,11 @@ pub fn compile(sess: &ParseSess, features: &Features, def: &ast::Item) -> Syntax
def_info: Some((def.id, def.span)),
allow_internal_unstable,
allow_internal_unsafe,
unstable_feature
unstable_feature,
edition,
}
} else {
SyntaxExtension::DeclMacro(expander, Some((def.id, def.span)))
SyntaxExtension::DeclMacro(expander, Some((def.id, def.span)), edition)
}
}

Expand Down

0 comments on commit f4cbc23

Please sign in to comment.