Skip to content

Commit b4906a9

Browse files
committed
Load macros from #[macro_use] extern crates in resolve.
1 parent 1599461 commit b4906a9

File tree

11 files changed

+86
-86
lines changed

11 files changed

+86
-86
lines changed

src/librustc/middle/cstore.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ use session::config::PanicStrategy;
3636
use session::search_paths::PathKind;
3737
use util::nodemap::{NodeSet, DefIdMap};
3838
use std::path::PathBuf;
39+
use std::rc::Rc;
3940
use syntax::ast;
4041
use syntax::attr;
41-
use syntax::ext::base::LoadedMacro;
42+
use syntax::ext::base::MultiItemModifier;
4243
use syntax::ptr::P;
4344
use syntax::parse::token::InternedString;
4445
use syntax_pos::Span;
@@ -422,6 +423,11 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
422423
fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
423424
}
424425

426+
pub enum LoadedMacro {
427+
Def(ast::MacroDef),
428+
CustomDerive(String, Rc<MultiItemModifier>),
429+
}
430+
425431
pub trait CrateLoader {
426432
fn load_macros(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro>;
427433
fn process_item(&mut self, item: &ast::Item, defs: &Definitions);

src/librustc_driver/driver.rs

+3
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use super::Compilation;
4343
use serialize::json;
4444

4545
use std::env;
46+
use std::mem;
4647
use std::ffi::{OsString, OsStr};
4748
use std::fs;
4849
use std::io::{self, Write};
@@ -686,6 +687,8 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
686687
ret
687688
});
688689

690+
krate.exported_macros = mem::replace(&mut resolver.exported_macros, Vec::new());
691+
689692
krate = time(time_passes, "maybe building test harness", || {
690693
syntax::test::modify_for_testing(&sess.parse_sess,
691694
&mut resolver,

src/librustc_metadata/creader.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use schema::CrateRoot;
1717

1818
use rustc::hir::def_id::{CrateNum, DefIndex};
1919
use rustc::hir::svh::Svh;
20+
use rustc::middle::cstore::LoadedMacro;
2021
use rustc::session::{config, Session};
2122
use rustc::session::config::PanicStrategy;
2223
use rustc::session::search_paths::PathKind;
@@ -32,7 +33,6 @@ use std::rc::Rc;
3233
use std::fs;
3334

3435
use syntax::ast;
35-
use syntax::ext::base::LoadedMacro;
3636
use syntax::abi::Abi;
3737
use syntax::parse;
3838
use syntax::attr;

src/librustc_metadata/macro_import.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,21 @@
1111
//! Used by `rustc` when loading a crate with exported macros.
1212
1313
use std::collections::HashSet;
14+
use std::rc::Rc;
1415
use std::env;
1516
use std::mem;
1617

1718
use creader::{CrateLoader, Macros};
1819

1920
use rustc::hir::def_id::DefIndex;
21+
use rustc::middle::cstore::LoadedMacro;
2022
use rustc::session::Session;
2123
use rustc::util::nodemap::FnvHashMap;
2224
use rustc_back::dynamic_lib::DynamicLibrary;
2325
use rustc_macro::TokenStream;
2426
use rustc_macro::__internal::Registry;
2527
use syntax::ast;
2628
use syntax::attr;
27-
use syntax::ext::base::LoadedMacro;
2829
use syntax::parse::token;
2930
use syntax_ext::deriving::custom::CustomDerive;
3031
use syntax_pos::Span;
@@ -204,9 +205,8 @@ impl<'a> CrateLoader<'a> {
204205
fn register_custom_derive(&mut self,
205206
trait_name: &str,
206207
expand: fn(TokenStream) -> TokenStream) {
207-
let derive = Box::new(CustomDerive::new(expand));
208-
self.0.push(LoadedMacro::CustomDerive(trait_name.to_string(),
209-
derive));
208+
let derive = Rc::new(CustomDerive::new(expand));
209+
self.0.push(LoadedMacro::CustomDerive(trait_name.to_string(), derive));
210210
}
211211
}
212212

src/librustc_resolve/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use rustc::ty;
5353
use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap};
5454
use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet};
5555

56+
use syntax::ext::base::MultiItemModifier;
5657
use syntax::ext::hygiene::Mark;
5758
use syntax::ast::{self, FloatTy};
5859
use syntax::ast::{CRATE_NODE_ID, Name, NodeId, IntTy, UintTy};
@@ -71,6 +72,7 @@ use syntax_pos::{Span, DUMMY_SP};
7172
use errors::DiagnosticBuilder;
7273

7374
use std::cell::{Cell, RefCell};
75+
use std::rc::Rc;
7476
use std::fmt;
7577
use std::mem::replace;
7678

@@ -1066,6 +1068,8 @@ pub struct Resolver<'a> {
10661068
dummy_binding: &'a NameBinding<'a>,
10671069
new_import_semantics: bool, // true if `#![feature(item_like_imports)]`
10681070

1071+
pub exported_macros: Vec<ast::MacroDef>,
1072+
pub derive_modes: FnvHashMap<Name, Rc<MultiItemModifier>>,
10691073
crate_loader: &'a mut CrateLoader,
10701074
macro_names: FnvHashSet<Name>,
10711075

@@ -1240,6 +1244,8 @@ impl<'a> Resolver<'a> {
12401244
}),
12411245
new_import_semantics: session.features.borrow().item_like_imports,
12421246

1247+
exported_macros: Vec::new(),
1248+
derive_modes: FnvHashMap(),
12431249
crate_loader: crate_loader,
12441250
macro_names: FnvHashSet(),
12451251
expansion_data: expansion_data,

src/librustc_resolve/macros.rs

+49-8
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,23 @@
99
// except according to those terms.
1010

1111
use Resolver;
12+
use rustc::middle::cstore::LoadedMacro;
1213
use rustc::util::nodemap::FnvHashMap;
1314
use std::cell::RefCell;
1415
use std::mem;
1516
use std::rc::Rc;
1617
use syntax::ast::{self, Name};
1718
use syntax::errors::DiagnosticBuilder;
18-
use syntax::ext::base::{self, LoadedMacro, MultiModifier, MultiDecorator};
19-
use syntax::ext::base::{NormalTT, SyntaxExtension};
19+
use syntax::ext::base::{self, MultiModifier, MultiDecorator, MultiItemModifier};
20+
use syntax::ext::base::{NormalTT, Resolver as SyntaxResolver, SyntaxExtension};
2021
use syntax::ext::expand::{Expansion, Invocation, InvocationKind};
2122
use syntax::ext::hygiene::Mark;
22-
use syntax::parse::token::intern;
23+
use syntax::ext::tt::macro_rules;
24+
use syntax::feature_gate::{self, emit_feature_err};
25+
use syntax::parse::token::{self, intern};
2326
use syntax::util::lev_distance::find_best_match_for_name;
2427
use syntax::visit::{self, Visitor};
28+
use syntax_pos::Span;
2529

2630
#[derive(Clone, Default)]
2731
pub struct ExpansionData {
@@ -37,10 +41,6 @@ struct ModuleData {
3741
}
3842

3943
impl<'a> base::Resolver for Resolver<'a> {
40-
fn load_crate(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro> {
41-
self.crate_loader.load_macros(extern_crate, allows_macros)
42-
}
43-
4444
fn next_node_id(&mut self) -> ast::NodeId {
4545
self.session.next_node_id()
4646
}
@@ -52,7 +52,18 @@ impl<'a> base::Resolver for Resolver<'a> {
5252
});
5353
}
5454

55-
fn add_macro(&mut self, scope: Mark, ident: ast::Ident, ext: Rc<SyntaxExtension>) {
55+
fn add_macro(&mut self, scope: Mark, mut def: ast::MacroDef) {
56+
if def.use_locally {
57+
let ext = macro_rules::compile(&self.session.parse_sess, &def);
58+
self.add_ext(scope, def.ident, Rc::new(ext));
59+
}
60+
if def.export {
61+
def.id = self.next_node_id();
62+
self.exported_macros.push(def);
63+
}
64+
}
65+
66+
fn add_ext(&mut self, scope: Mark, ident: ast::Ident, ext: Rc<SyntaxExtension>) {
5667
if let NormalTT(..) = *ext {
5768
self.macro_names.insert(ident.name);
5869
}
@@ -116,6 +127,10 @@ impl<'a> base::Resolver for Resolver<'a> {
116127
err.emit();
117128
None
118129
}
130+
131+
fn resolve_derive_mode(&mut self, ident: ast::Ident) -> Option<Rc<MultiItemModifier>> {
132+
self.derive_modes.get(&ident.name).cloned()
133+
}
119134
}
120135

121136
impl<'a> Resolver<'a> {
@@ -128,6 +143,17 @@ impl<'a> Resolver<'a> {
128143
}
129144
}
130145
}
146+
147+
fn insert_custom_derive(&mut self, name: &str, ext: Rc<MultiItemModifier>, sp: Span) {
148+
if !self.session.features.borrow().rustc_macro {
149+
let diagnostic = &self.session.parse_sess.span_diagnostic;
150+
let msg = "loading custom derive macro crates is experimentally supported";
151+
emit_feature_err(diagnostic, "rustc_macro", sp, feature_gate::GateIssue::Language, msg);
152+
}
153+
if self.derive_modes.insert(token::intern(name), ext).is_some() {
154+
self.session.span_err(sp, &format!("cannot shadow existing derive mode `{}`", name));
155+
}
156+
}
131157
}
132158

133159
struct ExpansionVisitor<'b, 'a: 'b> {
@@ -201,6 +227,21 @@ impl<'a, 'b> Visitor for ExpansionVisitor<'a, 'b> {
201227
visit::walk_item(self, item);
202228
self.current_module = orig_module;
203229
}
230+
ast::ItemKind::ExternCrate(..) => {
231+
// We need to error on `#[macro_use] extern crate` when it isn't at the
232+
// crate root, because `$crate` won't work properly.
233+
// FIXME(jseyfried): This will be nicer once `ModuleData` is merged with `ModuleS`.
234+
let is_crate_root = self.current_module.parent.as_ref().unwrap().parent.is_none();
235+
for def in self.resolver.crate_loader.load_macros(item, is_crate_root) {
236+
match def {
237+
LoadedMacro::Def(def) => self.resolver.add_macro(Mark::root(), def),
238+
LoadedMacro::CustomDerive(name, ext) => {
239+
self.resolver.insert_custom_derive(&name, ext, item.span);
240+
}
241+
}
242+
}
243+
visit::walk_item(self, item);
244+
}
204245
_ => visit::walk_item(self, item),
205246
}
206247
}

src/libsyntax/ext/base.rs

+8-46
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,15 @@ use syntax_pos::{Span, ExpnId, NO_EXPANSION};
1717
use errors::DiagnosticBuilder;
1818
use ext::expand::{self, Invocation, Expansion};
1919
use ext::hygiene::Mark;
20-
use ext::tt::macro_rules;
21-
use fold;
20+
use fold::{self, Folder};
2221
use parse;
2322
use parse::parser::{self, Parser};
2423
use parse::token;
2524
use parse::token::{InternedString, str_to_ident};
2625
use ptr::P;
2726
use std_inject;
2827
use util::small_vector::SmallVector;
29-
use fold::Folder;
30-
use feature_gate;
3128

32-
use std::collections::HashMap;
3329
use std::path::PathBuf;
3430
use std::rc::Rc;
3531
use std::default::Default;
@@ -659,35 +655,30 @@ pub enum SyntaxExtension {
659655
pub type NamedSyntaxExtension = (Name, SyntaxExtension);
660656

661657
pub trait Resolver {
662-
fn load_crate(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro>;
663658
fn next_node_id(&mut self) -> ast::NodeId;
664659

665660
fn visit_expansion(&mut self, mark: Mark, expansion: &Expansion);
666-
fn add_macro(&mut self, scope: Mark, ident: ast::Ident, ext: Rc<SyntaxExtension>);
661+
fn add_macro(&mut self, scope: Mark, def: ast::MacroDef);
662+
fn add_ext(&mut self, scope: Mark, ident: ast::Ident, ext: Rc<SyntaxExtension>);
667663
fn add_expansions_at_stmt(&mut self, id: ast::NodeId, macros: Vec<Mark>);
668664

669665
fn find_attr_invoc(&mut self, attrs: &mut Vec<Attribute>) -> Option<Attribute>;
670666
fn resolve_invoc(&mut self, scope: Mark, invoc: &Invocation) -> Option<Rc<SyntaxExtension>>;
671-
}
672-
673-
pub enum LoadedMacro {
674-
Def(ast::MacroDef),
675-
CustomDerive(String, Box<MultiItemModifier>),
667+
fn resolve_derive_mode(&mut self, ident: ast::Ident) -> Option<Rc<MultiItemModifier>>;
676668
}
677669

678670
pub struct DummyResolver;
679671

680672
impl Resolver for DummyResolver {
681-
fn load_crate(&mut self, _extern_crate: &ast::Item, _allows_macros: bool) -> Vec<LoadedMacro> {
682-
Vec::new()
683-
}
684673
fn next_node_id(&mut self) -> ast::NodeId { ast::DUMMY_NODE_ID }
685674

686675
fn visit_expansion(&mut self, _invoc: Mark, _expansion: &Expansion) {}
687-
fn add_macro(&mut self, _scope: Mark, _ident: ast::Ident, _ext: Rc<SyntaxExtension>) {}
676+
fn add_macro(&mut self, _scope: Mark, _def: ast::MacroDef) {}
677+
fn add_ext(&mut self, _scope: Mark, _ident: ast::Ident, _ext: Rc<SyntaxExtension>) {}
688678
fn add_expansions_at_stmt(&mut self, _id: ast::NodeId, _macros: Vec<Mark>) {}
689679

690680
fn find_attr_invoc(&mut self, _attrs: &mut Vec<Attribute>) -> Option<Attribute> { None }
681+
fn resolve_derive_mode(&mut self, _ident: ast::Ident) -> Option<Rc<MultiItemModifier>> { None }
691682
fn resolve_invoc(&mut self, _scope: Mark, _invoc: &Invocation) -> Option<Rc<SyntaxExtension>> {
692683
None
693684
}
@@ -717,8 +708,6 @@ pub struct ExtCtxt<'a> {
717708
pub ecfg: expand::ExpansionConfig<'a>,
718709
pub crate_root: Option<&'static str>,
719710
pub resolver: &'a mut Resolver,
720-
pub exported_macros: Vec<ast::MacroDef>,
721-
pub derive_modes: HashMap<InternedString, Box<MultiItemModifier>>,
722711
pub current_expansion: ExpansionData,
723712
}
724713

@@ -732,9 +721,7 @@ impl<'a> ExtCtxt<'a> {
732721
cfg: cfg,
733722
ecfg: ecfg,
734723
crate_root: None,
735-
exported_macros: Vec::new(),
736724
resolver: resolver,
737-
derive_modes: HashMap::new(),
738725
current_expansion: ExpansionData {
739726
mark: Mark::root(),
740727
depth: 0,
@@ -811,31 +798,6 @@ impl<'a> ExtCtxt<'a> {
811798
}
812799
pub fn bt_pop(&mut self) {}
813800

814-
pub fn insert_macro(&mut self, def: ast::MacroDef) {
815-
if def.export {
816-
self.exported_macros.push(def.clone());
817-
}
818-
if def.use_locally {
819-
let ext = macro_rules::compile(self.parse_sess, &def);
820-
self.resolver.add_macro(self.current_expansion.mark, def.ident, Rc::new(ext));
821-
}
822-
}
823-
824-
pub fn insert_custom_derive(&mut self, name: &str, ext: Box<MultiItemModifier>, sp: Span) {
825-
if !self.ecfg.enable_rustc_macro() {
826-
feature_gate::emit_feature_err(&self.parse_sess.span_diagnostic,
827-
"rustc_macro",
828-
sp,
829-
feature_gate::GateIssue::Language,
830-
"loading custom derive macro crates \
831-
is experimentally supported");
832-
}
833-
let name = token::intern_and_get_ident(name);
834-
if self.derive_modes.insert(name.clone(), ext).is_some() {
835-
self.span_err(sp, &format!("cannot shadow existing derive mode `{}`", name));
836-
}
837-
}
838-
839801
pub fn struct_span_warn(&self,
840802
sp: Span,
841803
msg: &str)
@@ -922,7 +884,7 @@ impl<'a> ExtCtxt<'a> {
922884

923885
for (name, extension) in user_exts {
924886
let ident = ast::Ident::with_empty_ctxt(name);
925-
self.resolver.add_macro(Mark::root(), ident, Rc::new(extension));
887+
self.resolver.add_ext(Mark::root(), ident, Rc::new(extension));
926888
}
927889

928890
let mut module = ModuleData {

src/libsyntax/ext/expand.rs

-19
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
199199
},
200200
_ => unreachable!(),
201201
};
202-
krate.exported_macros = mem::replace(&mut self.cx.exported_macros, Vec::new());
203-
204-
for def in &mut krate.exported_macros {
205-
def.id = self.cx.resolver.next_node_id()
206-
}
207202

208203
if self.cx.parse_sess.span_diagnostic.err_count() > err_count {
209204
self.cx.parse_sess.span_diagnostic.abort_if_errors();
@@ -672,20 +667,6 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
672667
self.cx.current_expansion.module = orig_module;
673668
return result;
674669
}
675-
ast::ItemKind::ExternCrate(..) => {
676-
// We need to error on `#[macro_use] extern crate` when it isn't at the
677-
// crate root, because `$crate` won't work properly.
678-
let is_crate_root = self.cx.current_expansion.module.mod_path.len() == 1;
679-
for def in self.cx.resolver.load_crate(&*item, is_crate_root) {
680-
match def {
681-
LoadedMacro::Def(def) => self.cx.insert_macro(def),
682-
LoadedMacro::CustomDerive(name, ext) => {
683-
self.cx.insert_custom_derive(&name, ext, item.span);
684-
}
685-
}
686-
}
687-
noop_fold_item(item, self)
688-
},
689670
_ => noop_fold_item(item, self),
690671
}
691672
}

0 commit comments

Comments
 (0)