Skip to content

Commit

Permalink
Auto merge of #40220 - jseyfried:ast_macro_def, r=nrc
Browse files Browse the repository at this point in the history
syntax: add `ast::ItemKind::MacroDef`, simplify hygiene info

This PR
 - adds a new variant `MacroDef` to `ast::ItemKind` for `macro_rules!` and eventually `macro` items,
 - [breaking-change] forbids macro defs without a name (`macro_rules! { () => {} }` compiles today),
 - removes `ast::MacroDef`, and
 - no longer uses `Mark` and `Invocation` to identify and characterize macro definitions.
   - We used to apply (at least) two `Mark`s to an expanded identifier's `SyntaxContext` -- the definition mark(s) and the expansion mark(s). We now only apply the latter.

r? @nrc
  • Loading branch information
bors committed Mar 11, 2017
2 parents e4eb964 + 8c98996 commit 1b19284
Show file tree
Hide file tree
Showing 25 changed files with 305 additions and 316 deletions.
51 changes: 28 additions & 23 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ pub struct LoweringContext<'a> {
trait_items: BTreeMap<hir::TraitItemId, hir::TraitItem>,
impl_items: BTreeMap<hir::ImplItemId, hir::ImplItem>,
bodies: BTreeMap<hir::BodyId, hir::Body>,
exported_macros: Vec<hir::MacroDef>,

trait_impls: BTreeMap<DefId, Vec<NodeId>>,
trait_default_impl: BTreeMap<DefId, NodeId>,
Expand Down Expand Up @@ -121,6 +122,7 @@ pub fn lower_crate(sess: &Session,
bodies: BTreeMap::new(),
trait_impls: BTreeMap::new(),
trait_default_impl: BTreeMap::new(),
exported_macros: Vec::new(),
loop_scopes: Vec::new(),
is_in_loop_condition: false,
type_def_lifetime_params: DefIdMap(),
Expand Down Expand Up @@ -170,9 +172,10 @@ impl<'a> LoweringContext<'a> {

impl<'lcx, 'interner> Visitor<'lcx> for ItemLowerer<'lcx, 'interner> {
fn visit_item(&mut self, item: &'lcx Item) {
let hir_item = self.lctx.lower_item(item);
self.lctx.items.insert(item.id, hir_item);
visit::walk_item(self, item);
if let Some(hir_item) = self.lctx.lower_item(item) {
self.lctx.items.insert(item.id, hir_item);
visit::walk_item(self, item);
}
}

fn visit_trait_item(&mut self, item: &'lcx TraitItem) {
Expand All @@ -195,14 +198,13 @@ impl<'a> LoweringContext<'a> {

let module = self.lower_mod(&c.module);
let attrs = self.lower_attrs(&c.attrs);
let exported_macros = c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect();
let body_ids = body_ids(&self.bodies);

hir::Crate {
module: module,
attrs: attrs,
span: c.span,
exported_macros: exported_macros,
exported_macros: hir::HirVec::from(self.exported_macros),
items: self.items,
trait_items: self.trait_items,
impl_items: self.impl_items,
Expand Down Expand Up @@ -1134,7 +1136,7 @@ impl<'a> LoweringContext<'a> {
bounds,
items)
}
ItemKind::Mac(_) => panic!("Shouldn't still be around"),
ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
}
}

Expand Down Expand Up @@ -1256,42 +1258,45 @@ impl<'a> LoweringContext<'a> {
}
}

fn lower_macro_def(&mut self, m: &MacroDef) -> hir::MacroDef {
hir::MacroDef {
name: m.ident.name,
attrs: self.lower_attrs(&m.attrs),
id: m.id,
span: m.span,
body: m.body.clone().into(),
}
}

fn lower_item_id(&mut self, i: &Item) -> SmallVector<hir::ItemId> {
if let ItemKind::Use(ref view_path) = i.node {
if let ViewPathList(_, ref imports) = view_path.node {
return iter::once(i.id).chain(imports.iter().map(|import| import.node.id))
.map(|id| hir::ItemId { id: id }).collect();
match i.node {
ItemKind::Use(ref view_path) => {
if let ViewPathList(_, ref imports) = view_path.node {
return iter::once(i.id).chain(imports.iter().map(|import| import.node.id))
.map(|id| hir::ItemId { id: id }).collect();
}
}
ItemKind::MacroDef(..) => return SmallVector::new(),
_ => {}
}
SmallVector::one(hir::ItemId { id: i.id })
}

pub fn lower_item(&mut self, i: &Item) -> hir::Item {
pub fn lower_item(&mut self, i: &Item) -> Option<hir::Item> {
let mut name = i.ident.name;
let attrs = self.lower_attrs(&i.attrs);
let mut vis = self.lower_visibility(&i.vis);
if let ItemKind::MacroDef(ref tts) = i.node {
if i.attrs.iter().any(|attr| attr.name() == "macro_export") {
self.exported_macros.push(hir::MacroDef {
name: name, attrs: attrs, id: i.id, span: i.span, body: tts.clone().into(),
});
}
return None;
}

let node = self.with_parent_def(i.id, |this| {
this.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node)
});

hir::Item {
Some(hir::Item {
id: i.id,
name: name,
attrs: attrs,
node: node,
vis: vis,
span: i.span,
}
})
}

fn lower_foreign_item(&mut self, i: &ForeignItem) -> hir::ForeignItem {
Expand Down
6 changes: 1 addition & 5 deletions src/librustc/hir/map/def_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
ItemKind::Mod(..) => DefPathData::Module(i.ident.name.as_str()),
ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
DefPathData::ValueNs(i.ident.name.as_str()),
ItemKind::Mac(..) if i.id == DUMMY_NODE_ID => return, // Scope placeholder
ItemKind::MacroDef(..) => DefPathData::MacroDef(i.ident.name.as_str()),
ItemKind::Mac(..) => return self.visit_macro_invoc(i.id, false),
ItemKind::Use(ref view_path) => {
match view_path.node {
Expand Down Expand Up @@ -269,10 +269,6 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name.as_str()));
}

fn visit_macro_def(&mut self, macro_def: &'a MacroDef) {
self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name.as_str()));
}

fn visit_stmt(&mut self, stmt: &'a Stmt) {
match stmt.node {
StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id, false),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ pub struct NativeLibrary {
}

pub enum LoadedMacro {
MacroRules(ast::MacroDef),
MacroDef(ast::Item),
ProcMacro(Rc<SyntaxExtension>),
}

Expand Down
3 changes: 0 additions & 3 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ use super::Compilation;
use serialize::json;

use std::env;
use std::mem;
use std::ffi::{OsString, OsStr};
use std::fs;
use std::io::{self, Write};
Expand Down Expand Up @@ -708,8 +707,6 @@ pub fn phase_2_configure_and_expand<F>(sess: &Session,
krate
});

krate.exported_macros = mem::replace(&mut resolver.exported_macros, Vec::new());

krate = time(time_passes, "maybe building test harness", || {
syntax::test::modify_for_testing(&sess.parse_sess,
&mut resolver,
Expand Down
5 changes: 3 additions & 2 deletions src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,12 +414,13 @@ impl CrateStore for cstore::CStore {
sess.imported_macro_spans.borrow_mut()
.insert(local_span, (name.to_string(), data.get_span(id.index, sess)));

LoadedMacro::MacroRules(ast::MacroDef {
LoadedMacro::MacroDef(ast::Item {
ident: ast::Ident::with_empty_ctxt(name),
id: ast::DUMMY_NODE_ID,
span: local_span,
attrs: attrs,
body: body.into(),
node: ast::ItemKind::MacroDef(body.into()),
vis: ast::Visibility::Inherited,
})
}

Expand Down
5 changes: 0 additions & 5 deletions src/librustc_passes/hir_stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,9 +375,4 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
self.record("Attribute", Id::None, attr);
}

fn visit_macro_def(&mut self, macro_def: &'v ast::MacroDef) {
self.record("MacroDef", Id::None, macro_def);
ast_visit::walk_macro_def(self, macro_def)
}
}
41 changes: 20 additions & 21 deletions src/librustc_resolve/build_reduced_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ use syntax::ast::{Mutability, StmtKind, TraitItem, TraitItemKind};
use syntax::ast::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple};
use syntax::ext::base::SyntaxExtension;
use syntax::ext::base::Determinacy::Undetermined;
use syntax::ext::expand::mark_tts;
use syntax::ext::hygiene::Mark;
use syntax::ext::tt::macro_rules;
use syntax::parse::token;
Expand Down Expand Up @@ -373,7 +372,7 @@ impl<'a> Resolver<'a> {
self.define(parent, ident, TypeNS, (module, vis, sp, expansion));
self.current_module = module;
}
ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"),
ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(),
}
}

Expand Down Expand Up @@ -493,6 +492,16 @@ impl<'a> Resolver<'a> {
})
}

pub fn macro_def_scope(&mut self, expansion: Mark) -> Module<'a> {
let def_id = self.macro_defs[&expansion];
if let Some(id) = self.definitions.as_local_node_id(def_id) {
self.local_macro_def_scopes[&id]
} else {
let module_def_id = ty::DefIdTree::parent(&*self, def_id).unwrap();
self.get_extern_crate_root(module_def_id.krate)
}
}

pub fn get_macro(&mut self, def: Def) -> Rc<SyntaxExtension> {
let def_id = match def {
Def::Macro(def_id, ..) => def_id,
Expand All @@ -502,22 +511,12 @@ impl<'a> Resolver<'a> {
return ext.clone();
}

let mut macro_rules = match self.session.cstore.load_macro(def_id, &self.session) {
LoadedMacro::MacroRules(macro_rules) => macro_rules,
let macro_def = match self.session.cstore.load_macro(def_id, &self.session) {
LoadedMacro::MacroDef(macro_def) => macro_def,
LoadedMacro::ProcMacro(ext) => return ext,
};

let mark = Mark::fresh();
let invocation = self.arenas.alloc_invocation_data(InvocationData {
module: Cell::new(self.get_extern_crate_root(def_id.krate)),
def_index: CRATE_DEF_INDEX,
const_expr: false,
legacy_scope: Cell::new(LegacyScope::Empty),
expansion: Cell::new(LegacyScope::Empty),
});
self.invocations.insert(mark, invocation);
macro_rules.body = mark_tts(macro_rules.stream(), mark).into();
let ext = Rc::new(macro_rules::compile(&self.session.parse_sess, &macro_rules));
let ext = Rc::new(macro_rules::compile(&self.session.parse_sess, &macro_def));
self.macro_map.insert(def_id, ext.clone());
ext
}
Expand Down Expand Up @@ -707,12 +706,12 @@ impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> {

fn visit_item(&mut self, item: &'a Item) {
let macro_use = match item.node {
ItemKind::Mac(ref mac) => {
if mac.node.path.segments.is_empty() {
self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id));
} else {
self.resolver.define_macro(item, &mut self.legacy_scope);
}
ItemKind::MacroDef(..) => {
self.resolver.define_macro(item, &mut self.legacy_scope);
return
}
ItemKind::Mac(..) => {
self.legacy_scope = LegacyScope::Expansion(self.visit_invoc(item.id));
return
}
ItemKind::Mod(..) => self.resolver.contains_macro_use(&item.attrs),
Expand Down
Loading

0 comments on commit 1b19284

Please sign in to comment.