From 6d15c6749c30d9077c6e12af3be64c5f68fafcff Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Sat, 24 May 2014 16:16:10 -0700 Subject: [PATCH 1/9] Implement #[plugin_registrar] See RFC 22. [breaking-change] --- src/librustc/driver/driver.rs | 66 +++++--- src/librustc/driver/session.rs | 4 +- src/librustc/front/feature_gate.rs | 9 +- src/librustc/front/std_inject.rs | 2 +- src/librustc/front/test.rs | 3 - src/librustc/lib.rs | 8 + src/librustc/metadata/common.rs | 2 +- src/librustc/metadata/creader.rs | 24 ++- src/librustc/metadata/cstore.rs | 3 - src/librustc/metadata/decoder.rs | 4 +- src/librustc/metadata/encoder.rs | 40 ++--- .../registrar.rs => librustc/plugin/build.rs} | 36 +++-- src/librustc/plugin/load.rs | 131 +++++++++++++++ src/librustc/plugin/registry.rs | 55 +++++++ src/librustdoc/core.rs | 5 +- src/librustdoc/test.rs | 3 +- src/libsyntax/ext/base.rs | 19 +-- src/libsyntax/ext/expand.rs | 152 ++++-------------- src/libsyntax/lib.rs | 1 - 19 files changed, 331 insertions(+), 236 deletions(-) rename src/{libsyntax/ext/registrar.rs => librustc/plugin/build.rs} (56%) create mode 100644 src/librustc/plugin/load.rs create mode 100644 src/librustc/plugin/registry.rs diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 89c0a381cf9..45e9c7b562d 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -18,12 +18,14 @@ use front; use lib::llvm::{ContextRef, ModuleRef}; use metadata::common::LinkMeta; use metadata::creader; -use metadata::creader::Loader; use middle::cfg; use middle::cfg::graphviz::LabelledCFG; use middle::{trans, freevars, kind, ty, typeck, lint, reachable}; use middle::dependency_format; use middle; +use plugin::load::Plugins; +use plugin::registry::Registry; +use plugin; use util::common::time; use util::ppaux; use util::nodemap::{NodeSet}; @@ -39,7 +41,6 @@ use syntax::ast; use syntax::attr; use syntax::attr::{AttrMetaMethods}; use syntax::crateid::CrateId; -use syntax::ext::base::CrateLoader; use syntax::parse; use syntax::parse::token; use syntax::print::{pp, pprust}; @@ -75,11 +76,10 @@ pub fn compile_input(sess: Session, output, krate.attrs.as_slice(), &sess); - let loader = &mut Loader::new(&sess); let id = link::find_crate_id(krate.attrs.as_slice(), outputs.out_filestem.as_slice()); let (expanded_crate, ast_map) = - phase_2_configure_and_expand(&sess, loader, krate, &id); + phase_2_configure_and_expand(&sess, krate, &id); (outputs, expanded_crate, ast_map) }; write_out_deps(&sess, input, &outputs, &expanded_crate); @@ -172,7 +172,6 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input) /// harness if one is to be provided and injection of a dependency on the /// standard library and prelude. pub fn phase_2_configure_and_expand(sess: &Session, - loader: &mut CrateLoader, mut krate: ast::Crate, crate_id: &CrateId) -> (ast::Crate, syntax::ast_map::Map) { @@ -197,25 +196,42 @@ pub fn phase_2_configure_and_expand(sess: &Session, krate = time(time_passes, "configuration 1", krate, |krate| front::config::strip_unconfigured_items(krate)); - krate = time(time_passes, "expansion", krate, |krate| { - // Windows dlls do not have rpaths, so they don't know how to find their - // dependencies. It's up to us to tell the system where to find all the - // dependent dlls. Note that this uses cfg!(windows) as opposed to - // targ_cfg because syntax extensions are always loaded for the host - // compiler, not for the target. - if cfg!(windows) { - sess.host_filesearch().add_dylib_search_paths(); + let Plugins { macros, registrars } + = time(time_passes, "plugin loading", (), |_| + plugin::load::load_plugins(sess, &krate)); + + let mut registry = Registry::new(&krate); + + time(time_passes, "plugin registration", (), |_| { + for ®istrar in registrars.iter() { + registrar(&mut registry); } - let cfg = syntax::ext::expand::ExpansionConfig { - loader: loader, - deriving_hash_type_parameter: sess.features.default_type_params.get(), - crate_id: crate_id.clone(), - }; - syntax::ext::expand::expand_crate(&sess.parse_sess, - cfg, - krate) }); + let Registry { syntax_exts, .. } = registry; + + krate = time(time_passes, "expansion", (krate, macros, syntax_exts), + |(krate, macros, syntax_exts)| { + // Windows dlls do not have rpaths, so they don't know how to find their + // dependencies. It's up to us to tell the system where to find all the + // dependent dlls. Note that this uses cfg!(windows) as opposed to + // targ_cfg because syntax extensions are always loaded for the host + // compiler, not for the target. + if cfg!(windows) { + sess.host_filesearch().add_dylib_search_paths(); + } + let cfg = syntax::ext::expand::ExpansionConfig { + deriving_hash_type_parameter: sess.features.default_type_params.get(), + crate_id: crate_id.clone(), + }; + syntax::ext::expand::expand_crate(&sess.parse_sess, + cfg, + macros, + syntax_exts, + krate) + } + ); + // strip again, in case expansion added anything with a #[cfg]. krate = time(time_passes, "configuration 2", krate, |krate| front::config::strip_unconfigured_items(krate)); @@ -281,9 +297,9 @@ pub fn phase_3_run_analysis_passes(sess: Session, time(time_passes, "looking for entry point", (), |_| middle::entry::find_entry_point(&sess, krate, &ast_map)); - sess.macro_registrar_fn.set( - time(time_passes, "looking for macro registrar", (), |_| - syntax::ext::registrar::find_macro_registrar( + sess.plugin_registrar_fn.set( + time(time_passes, "looking for plugin registrar", (), |_| + plugin::build::find_plugin_registrar( sess.diagnostic(), krate))); let freevars = time(time_passes, "freevar finding", (), |_| @@ -596,9 +612,7 @@ pub fn pretty_print_input(sess: Session, let (krate, ast_map, is_expanded) = match ppm { PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => { - let loader = &mut Loader::new(&sess); let (krate, ast_map) = phase_2_configure_and_expand(&sess, - loader, krate, &id); (krate, Some(ast_map), true) diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs index 109622b6627..773b9e6e0aa 100644 --- a/src/librustc/driver/session.rs +++ b/src/librustc/driver/session.rs @@ -36,7 +36,7 @@ pub struct Session { // For a library crate, this is always none pub entry_fn: RefCell>, pub entry_type: Cell>, - pub macro_registrar_fn: Cell>, + pub plugin_registrar_fn: Cell>, pub default_sysroot: Option, // The name of the root source file of the crate, in the local file system. The path is always // expected to be absolute. `None` means that there is no source file. @@ -232,7 +232,7 @@ pub fn build_session_(sopts: config::Options, // For a library crate, this is always none entry_fn: RefCell::new(None), entry_type: Cell::new(None), - macro_registrar_fn: Cell::new(None), + plugin_registrar_fn: Cell::new(None), default_sysroot: default_sysroot, local_crate_source_file: local_crate_source_file, working_dir: os::getcwd(), diff --git a/src/librustc/front/feature_gate.rs b/src/librustc/front/feature_gate.rs index 25f0dc808c8..11dd6a86cd8 100644 --- a/src/librustc/front/feature_gate.rs +++ b/src/librustc/front/feature_gate.rs @@ -46,7 +46,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[ ("thread_local", Active), ("link_args", Active), ("phase", Active), - ("macro_registrar", Active), + ("plugin_registrar", Active), ("log_syntax", Active), ("trace_macros", Active), ("concat_idents", Active), @@ -192,10 +192,9 @@ impl<'a> Visitor<()> for Context<'a> { } ast::ItemFn(..) => { - if attr::contains_name(i.attrs.as_slice(), "macro_registrar") { - self.gate_feature("macro_registrar", i.span, - "cross-crate macro exports are \ - experimental and possibly buggy"); + if attr::contains_name(i.attrs.as_slice(), "plugin_registrar") { + self.gate_feature("plugin_registrar", i.span, + "compiler plugins are experimental and possibly buggy"); } } diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index fe636f7b686..0514f7de505 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -81,7 +81,7 @@ impl<'a> fold::Folder for StandardLibraryInjector<'a> { attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item( InternedString::new("phase"), vec!( - attr::mk_word_item(InternedString::new("syntax")), + attr::mk_word_item(InternedString::new("plugin")), attr::mk_word_item(InternedString::new("link") ))))), vis: ast::Inherited, diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index b21f3c2a019..174bcc86d26 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -16,7 +16,6 @@ use driver::session::Session; use front::config; use front::std_inject::with_version; -use metadata::creader::Loader; use std::cell::RefCell; use std::slice; @@ -150,12 +149,10 @@ impl<'a> fold::Folder for TestHarnessGenerator<'a> { fn generate_test_harness(sess: &Session, krate: ast::Crate) -> ast::Crate { - let loader = &mut Loader::new(sess); let mut cx: TestCtxt = TestCtxt { sess: sess, ext_cx: ExtCtxt::new(&sess.parse_sess, sess.opts.cfg.clone(), ExpansionConfig { - loader: loader, deriving_hash_type_parameter: false, crate_id: from_str("test").unwrap(), }), diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 1b17cfb1bae..b82dace62ef 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -109,6 +109,14 @@ pub mod metadata; pub mod driver; +pub mod plugin { + pub use self::registry::Registry; + + pub mod registry; + pub mod load; + pub mod build; +} + pub mod util { pub mod common; pub mod ppaux; diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index 6287683c1a1..2ff656853c3 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -198,7 +198,7 @@ pub static tag_native_libraries_lib: uint = 0x88; pub static tag_native_libraries_name: uint = 0x89; pub static tag_native_libraries_kind: uint = 0x8a; -pub static tag_macro_registrar_fn: uint = 0x8b; +pub static tag_plugin_registrar_fn: uint = 0x8b; pub static tag_exported_macros: uint = 0x8c; pub static tag_macro_def: uint = 0x8d; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 38d2b7a67a0..4df21fbc974 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -21,6 +21,7 @@ use metadata::cstore::{CStore, CrateSource}; use metadata::decoder; use metadata::loader; use metadata::loader::CratePaths; +use plugin::load::PluginMetadata; use std::rc::Rc; use std::collections::HashMap; @@ -30,7 +31,6 @@ use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::codemap::{Span}; use syntax::diagnostic::SpanHandler; -use syntax::ext::base::{CrateLoader, MacroCrate}; use syntax::parse::token::InternedString; use syntax::parse::token; use syntax::crateid::CrateId; @@ -379,23 +379,21 @@ fn resolve_crate_deps(e: &mut Env, }).collect() } -pub struct Loader<'a> { +pub struct PluginMetadataReader<'a> { env: Env<'a>, } -impl<'a> Loader<'a> { - pub fn new(sess: &'a Session) -> Loader<'a> { - Loader { +impl<'a> PluginMetadataReader<'a> { + pub fn new(sess: &'a Session) -> PluginMetadataReader<'a> { + PluginMetadataReader { env: Env { sess: sess, next_crate_num: sess.cstore.next_crate_num(), } } } -} -impl<'a> CrateLoader for Loader<'a> { - fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate { + pub fn read_plugin_metadata(&mut self, krate: &ast::ViewItem) -> PluginMetadata { let info = extract_crate_info(&self.env, krate).unwrap(); let target_triple = self.env.sess.targ_cfg.target_strs.target_triple.as_slice(); let is_cross = target_triple != driver::host_triple(); @@ -425,8 +423,8 @@ impl<'a> CrateLoader for Loader<'a> { load_ctxt.os = config::cfg_os_to_meta_os(self.env.sess.targ_cfg.os); load_ctxt.filesearch = self.env.sess.target_filesearch(); let lib = load_ctxt.load_library_crate(); - if decoder::get_macro_registrar_fn(lib.metadata.as_slice()).is_some() { - let message = format!("crate `{}` contains a macro_registrar fn but \ + if decoder::get_plugin_registrar_fn(lib.metadata.as_slice()).is_some() { + let message = format!("crate `{}` contains a plugin_registrar fn but \ only a version for triple `{}` could be found (need {})", info.ident, target_triple, driver::host_triple()); self.env.sess.span_err(krate.span, message.as_slice()); @@ -441,10 +439,10 @@ impl<'a> CrateLoader for Loader<'a> { None => { load_ctxt.report_load_errs(); unreachable!() }, }; let macros = decoder::get_exported_macros(library.metadata.as_slice()); - let registrar = decoder::get_macro_registrar_fn(library.metadata.as_slice()).map(|id| { + let registrar = decoder::get_plugin_registrar_fn(library.metadata.as_slice()).map(|id| { decoder::get_symbol(library.metadata.as_slice(), id).to_string() }); - let mc = MacroCrate { + let pc = PluginMetadata { lib: library.dylib.clone(), macros: macros.move_iter().map(|x| x.to_string()).collect(), registrar_symbol: registrar, @@ -454,6 +452,6 @@ impl<'a> CrateLoader for Loader<'a> { register_crate(&mut self.env, &None, info.ident.as_slice(), &info.crate_id, krate.span, library); } - mc + pc } } diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index aa8d695465a..846f879104f 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -139,9 +139,6 @@ impl CStore { .map(|source| source.clone()) } - pub fn dump_phase_syntax_crates(&self) { - } - pub fn reset(&self) { self.metas.borrow_mut().clear(); self.extern_mod_crate_map.borrow_mut().clear(); diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index c67b5bf1a60..8a2c3c08d41 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -1255,8 +1255,8 @@ pub fn get_native_libraries(cdata: Cmd) return result; } -pub fn get_macro_registrar_fn(data: &[u8]) -> Option { - reader::maybe_get_doc(ebml::Doc::new(data), tag_macro_registrar_fn) +pub fn get_plugin_registrar_fn(data: &[u8]) -> Option { + reader::maybe_get_doc(ebml::Doc::new(data), tag_plugin_registrar_fn) .map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap()) } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 37cb75e4697..1846c9c881b 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1582,9 +1582,9 @@ fn encode_native_libraries(ecx: &EncodeContext, ebml_w: &mut Encoder) { ebml_w.end_tag(); } -fn encode_macro_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) { - match ecx.tcx.sess.macro_registrar_fn.get() { - Some(id) => { ebml_w.wr_tagged_u32(tag_macro_registrar_fn, id); } +fn encode_plugin_registrar_fn(ecx: &EncodeContext, ebml_w: &mut Encoder) { + match ecx.tcx.sess.plugin_registrar_fn.get() { + Some(id) => { ebml_w.wr_tagged_u32(tag_plugin_registrar_fn, id); } None => {} } } @@ -1791,7 +1791,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) dep_bytes: u64, lang_item_bytes: u64, native_lib_bytes: u64, - macro_registrar_fn_bytes: u64, + plugin_registrar_fn_bytes: u64, macro_defs_bytes: u64, impl_bytes: u64, misc_bytes: u64, @@ -1805,7 +1805,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) dep_bytes: 0, lang_item_bytes: 0, native_lib_bytes: 0, - macro_registrar_fn_bytes: 0, + plugin_registrar_fn_bytes: 0, macro_defs_bytes: 0, impl_bytes: 0, misc_bytes: 0, @@ -1870,10 +1870,10 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) encode_native_libraries(&ecx, &mut ebml_w); stats.native_lib_bytes = ebml_w.writer.tell().unwrap() - i; - // Encode the macro registrar function + // Encode the plugin registrar function i = ebml_w.writer.tell().unwrap(); - encode_macro_registrar_fn(&ecx, &mut ebml_w); - stats.macro_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i; + encode_plugin_registrar_fn(&ecx, &mut ebml_w); + stats.plugin_registrar_fn_bytes = ebml_w.writer.tell().unwrap() - i; // Encode macro definitions i = ebml_w.writer.tell().unwrap(); @@ -1912,18 +1912,18 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate) } println!("metadata stats:"); - println!(" attribute bytes: {}", stats.attr_bytes); - println!(" dep bytes: {}", stats.dep_bytes); - println!(" lang item bytes: {}", stats.lang_item_bytes); - println!(" native bytes: {}", stats.native_lib_bytes); - println!("macro registrar bytes: {}", stats.macro_registrar_fn_bytes); - println!(" macro def bytes: {}", stats.macro_defs_bytes); - println!(" impl bytes: {}", stats.impl_bytes); - println!(" misc bytes: {}", stats.misc_bytes); - println!(" item bytes: {}", stats.item_bytes); - println!(" index bytes: {}", stats.index_bytes); - println!(" zero bytes: {}", stats.zero_bytes); - println!(" total bytes: {}", stats.total_bytes); + println!(" attribute bytes: {}", stats.attr_bytes); + println!(" dep bytes: {}", stats.dep_bytes); + println!(" lang item bytes: {}", stats.lang_item_bytes); + println!(" native bytes: {}", stats.native_lib_bytes); + println!("plugin registrar bytes: {}", stats.plugin_registrar_fn_bytes); + println!(" macro def bytes: {}", stats.macro_defs_bytes); + println!(" impl bytes: {}", stats.impl_bytes); + println!(" misc bytes: {}", stats.misc_bytes); + println!(" item bytes: {}", stats.item_bytes); + println!(" index bytes: {}", stats.index_bytes); + println!(" zero bytes: {}", stats.zero_bytes); + println!(" total bytes: {}", stats.total_bytes); } } diff --git a/src/libsyntax/ext/registrar.rs b/src/librustc/plugin/build.rs similarity index 56% rename from src/libsyntax/ext/registrar.rs rename to src/librustc/plugin/build.rs index b76708147e1..a27632882fc 100644 --- a/src/libsyntax/ext/registrar.rs +++ b/src/librustc/plugin/build.rs @@ -8,23 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast; -use attr; -use codemap::Span; -use diagnostic; -use visit; -use visit::Visitor; +use syntax::ast; +use syntax::attr; +use syntax::codemap::Span; +use syntax::diagnostic; +use syntax::visit; +use syntax::visit::Visitor; -struct MacroRegistrarContext { +struct RegistrarFinder { registrars: Vec<(ast::NodeId, Span)> , } -impl Visitor<()> for MacroRegistrarContext { +impl Visitor<()> for RegistrarFinder { fn visit_item(&mut self, item: &ast::Item, _: ()) { match item.node { ast::ItemFn(..) => { if attr::contains_name(item.attrs.as_slice(), - "macro_registrar") { + "plugin_registrar") { self.registrars.push((item.id, item.span)); } } @@ -35,20 +35,22 @@ impl Visitor<()> for MacroRegistrarContext { } } -pub fn find_macro_registrar(diagnostic: &diagnostic::SpanHandler, - krate: &ast::Crate) -> Option { - let mut ctx = MacroRegistrarContext { registrars: Vec::new() }; - visit::walk_crate(&mut ctx, krate, ()); +/// Find the function marked with `#[plugin_registrar]`, if any. +/// Used while compiling a crate which defines a registrar. +pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler, + krate: &ast::Crate) -> Option { + let mut finder = RegistrarFinder { registrars: Vec::new() }; + visit::walk_crate(&mut finder, krate, ()); - match ctx.registrars.len() { + match finder.registrars.len() { 0 => None, 1 => { - let (node_id, _) = ctx.registrars.pop().unwrap(); + let (node_id, _) = finder.registrars.pop().unwrap(); Some(node_id) }, _ => { - diagnostic.handler().err("multiple macro registration functions found"); - for &(_, span) in ctx.registrars.iter() { + diagnostic.handler().err("multiple plugin registration functions found"); + for &(_, span) in finder.registrars.iter() { diagnostic.span_note(span, "one is here"); } diagnostic.handler().abort_if_errors(); diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs new file mode 100644 index 00000000000..c80f8f96c4b --- /dev/null +++ b/src/librustc/plugin/load.rs @@ -0,0 +1,131 @@ +// Copyright 2012-2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use plugin::registry::PluginRegistrarFun; +use driver::session::Session; +use metadata::creader::PluginMetadataReader; + +use std::mem; +use std::os; +use std::unstable::dynamic_lib::DynamicLibrary; +use syntax::ast; +use syntax::attr; +use syntax::visit; +use syntax::visit::Visitor; +use syntax::ext::expand::ExportedMacros; +use syntax::attr::AttrMetaMethods; + +pub struct PluginMetadata { + pub macros: Vec, + pub lib: Option, + pub registrar_symbol: Option, +} + +pub struct Plugins { + pub macros: Vec, + pub registrars: Vec, +} + +struct PluginLoader<'a> { + sess: &'a Session, + reader: PluginMetadataReader<'a>, + plugins: Plugins, +} + +impl<'a> PluginLoader<'a> { + fn new(sess: &'a Session) -> PluginLoader<'a> { + PluginLoader { + sess: sess, + reader: PluginMetadataReader::new(sess), + plugins: Plugins { + macros: vec!(), + registrars: vec!(), + }, + } + } +} + +pub fn load_plugins(sess: &Session, krate: &ast::Crate) -> Plugins { + let mut loader = PluginLoader::new(sess); + visit::walk_crate(&mut loader, krate, ()); + loader.plugins +} + +impl<'a> Visitor<()> for PluginLoader<'a> { + fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) { + match vi.node { + ast::ViewItemExternCrate(name, _, _) => { + let mut plugin_phase = false; + + for attr in vi.attrs.iter().filter(|a| a.check_name("phase")) { + let phases = attr.meta_item_list().unwrap_or(&[]); + if attr::contains_name(phases, "plugin") { + plugin_phase = true; + } + if attr::contains_name(phases, "syntax") { + plugin_phase = true; + self.sess.span_warn(attr.span, + "phase(syntax) is a deprecated synonym for phase(plugin)"); + } + } + + if !plugin_phase { return; } + + let PluginMetadata { macros, lib, registrar_symbol } = + self.reader.read_plugin_metadata(vi); + + self.plugins.macros.push(ExportedMacros { + crate_name: name, + macros: macros, + }); + + match (lib, registrar_symbol) { + (Some(lib), Some(symbol)) + => self.dylink_registrar(vi, lib, symbol), + _ => (), + } + } + _ => (), + } + } +} + +impl<'a> PluginLoader<'a> { + // Dynamically link a registrar function into the compiler process. + fn dylink_registrar(&mut self, vi: &ast::ViewItem, path: Path, symbol: String) { + // Make sure the path contains a / or the linker will search for it. + let path = os::make_absolute(&path); + + let lib = match DynamicLibrary::open(Some(&path)) { + Ok(lib) => lib, + // this is fatal: there are almost certainly macros we need + // inside this crate, so continue would spew "macro undefined" + // errors + Err(err) => self.sess.span_fatal(vi.span, err.as_slice()) + }; + + unsafe { + let registrar: PluginRegistrarFun = + match lib.symbol(symbol.as_slice()) { + Ok(registrar) => registrar, + // again fatal if we can't register macros + Err(err) => self.sess.span_fatal(vi.span, err.as_slice()) + }; + + self.plugins.registrars.push(registrar); + + // Intentionally leak the dynamic library. We can't ever unload it + // since the library can make things that will live arbitrarily long + // (e.g. an @-box cycle or a task). + mem::forget(lib); + + } + } +} diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs new file mode 100644 index 00000000000..6402b116536 --- /dev/null +++ b/src/librustc/plugin/registry.rs @@ -0,0 +1,55 @@ +// Copyright 2012-2013 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT}; +use syntax::ext::base::{IdentTT, ItemDecorator, ItemModifier, BasicMacroExpander}; +use syntax::ext::base::{MacroExpanderFn}; +use syntax::codemap::Span; +use syntax::parse::token; +use syntax::ast; + +pub struct Registry { + #[doc(hidden)] + pub krate_span: Span, + + #[doc(hidden)] + pub syntax_exts: Vec, +} + +pub type PluginRegistrarFun = + fn(&mut Registry); + +impl Registry { + #[doc(hidden)] + pub fn new(krate: &ast::Crate) -> Registry { + Registry { + krate_span: krate.span, + syntax_exts: vec!(), + } + } + + pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { + self.syntax_exts.push((name, match extension { + NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)), + IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)), + ItemDecorator(ext) => ItemDecorator(ext), + ItemModifier(ext) => ItemModifier(ext), + })); + } + + pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) { + self.register_syntax_extension( + token::intern(name), + NormalTT(box BasicMacroExpander { + expander: expander, + span: None, + }, None)); + } +} diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 1786e5b3fd2..f848c5224b7 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -10,7 +10,6 @@ use rustc; use rustc::{driver, middle}; -use rustc::metadata::creader::Loader; use rustc::middle::privacy; use rustc::middle::lint; @@ -100,8 +99,8 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet, cfgs: Vec) } let krate = phase_1_parse_input(&sess, cfg, &input); - let (krate, ast_map) = phase_2_configure_and_expand(&sess, &mut Loader::new(&sess), - krate, &from_str("rustdoc").unwrap()); + let (krate, ast_map) = phase_2_configure_and_expand(&sess, krate, + &from_str("rustdoc").unwrap()); let driver::driver::CrateAnalysis { exported_items, public_items, ty_cx, .. } = phase_3_run_analysis_passes(sess, &krate, ast_map); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 745e29508d2..34363058297 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -23,7 +23,6 @@ use rustc::back::link; use rustc::driver::config; use rustc::driver::driver; use rustc::driver::session; -use rustc::metadata::creader::Loader; use syntax::ast; use syntax::codemap::{CodeMap, dummy_spanned}; use syntax::diagnostic; @@ -68,7 +67,7 @@ pub fn run(input: &str, @dummy_spanned(ast::MetaWord(cfg_)) })); let krate = driver::phase_1_parse_input(&sess, cfg, &input); - let (krate, _) = driver::phase_2_configure_and_expand(&sess, &mut Loader::new(&sess), krate, + let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate, &from_str("rustdoc-test").unwrap()); let ctx = @core::DocContext { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 521b7ee0063..e81421cff04 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -95,9 +95,6 @@ impl IdentMacroExpander for BasicIdentMacroExpander { pub type IdentMacroExpanderFn = fn(&mut ExtCtxt, Span, ast::Ident, Vec) -> Box; -pub type MacroCrateRegistrationFun = - fn(|ast::Name, SyntaxExtension|); - /// The result of a macro expansion. The return values of the various /// methods are spliced into the AST at the callsite of the macro (or /// just into the compiler's internal macro table, for `make_def`). @@ -268,6 +265,8 @@ pub enum SyntaxExtension { IdentTT(Box, Option), } +pub type NamedSyntaxExtension = (Name, SyntaxExtension); + pub struct BlockInfo { // should macros escape from this scope? pub macros_escape: bool, @@ -392,16 +391,6 @@ pub fn syntax_expander_table() -> SyntaxEnv { syntax_expanders } -pub struct MacroCrate { - pub lib: Option, - pub macros: Vec, - pub registrar_symbol: Option, -} - -pub trait CrateLoader { - fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate; -} - // One of these is made during expansion and incrementally updated as we go; // when a macro expansion occurs, the resulting nodes have the backtrace() // -> expn_info of their expansion context stored into their span. @@ -409,7 +398,7 @@ pub struct ExtCtxt<'a> { pub parse_sess: &'a parse::ParseSess, pub cfg: ast::CrateConfig, pub backtrace: Option<@ExpnInfo>, - pub ecfg: expand::ExpansionConfig<'a>, + pub ecfg: expand::ExpansionConfig, pub mod_path: Vec , pub trace_mac: bool, @@ -417,7 +406,7 @@ pub struct ExtCtxt<'a> { impl<'a> ExtCtxt<'a> { pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig, - ecfg: expand::ExpansionConfig<'a>) -> ExtCtxt<'a> { + ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> { ExtCtxt { parse_sess: parse_sess, cfg: cfg, diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 03001acc5d0..bb335e7bed0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -29,10 +29,6 @@ use visit; use visit::Visitor; use util::small_vector::SmallVector; -use std::mem; -use std::os; -use std::unstable::dynamic_lib::DynamicLibrary; - pub fn expand_expr(e: @ast::Expr, fld: &mut MacroExpander) -> @ast::Expr { match e.node { // expr_mac should really be expr_ext or something; it's the @@ -497,96 +493,6 @@ pub fn expand_item_mac(it: @ast::Item, fld: &mut MacroExpander) return items; } -// load macros from syntax-phase crates -pub fn expand_view_item(vi: &ast::ViewItem, - fld: &mut MacroExpander) - -> ast::ViewItem { - match vi.node { - ast::ViewItemExternCrate(..) => { - let should_load = vi.attrs.iter().any(|attr| { - attr.check_name("phase") && - attr.meta_item_list().map_or(false, |phases| { - attr::contains_name(phases, "syntax") - }) - }); - - if should_load { - load_extern_macros(vi, fld); - } - } - ast::ViewItemUse(_) => {} - } - - noop_fold_view_item(vi, fld) -} - -fn load_extern_macros(krate: &ast::ViewItem, fld: &mut MacroExpander) { - let MacroCrate { lib, macros, registrar_symbol } = - fld.cx.ecfg.loader.load_crate(krate); - - let crate_name = match krate.node { - ast::ViewItemExternCrate(name, _, _) => name, - _ => unreachable!() - }; - let name = format!("<{} macros>", token::get_ident(crate_name)); - let name = name.to_string(); - - for source in macros.iter() { - let item = parse::parse_item_from_source_str(name.clone(), - (*source).clone(), - fld.cx.cfg(), - fld.cx.parse_sess()) - .expect("expected a serialized item"); - expand_item_mac(item, fld); - } - - let path = match lib { - Some(path) => path, - None => return - }; - // Make sure the path contains a / or the linker will search for it. - let path = os::make_absolute(&path); - - let registrar = match registrar_symbol { - Some(registrar) => registrar, - None => return - }; - - debug!("load_extern_macros: mapped crate {} to path {} and registrar {:s}", - crate_name, path.display(), registrar); - - let lib = match DynamicLibrary::open(Some(&path)) { - Ok(lib) => lib, - // this is fatal: there are almost certainly macros we need - // inside this crate, so continue would spew "macro undefined" - // errors - Err(err) => fld.cx.span_fatal(krate.span, err.as_slice()) - }; - - unsafe { - let registrar: MacroCrateRegistrationFun = - match lib.symbol(registrar.as_slice()) { - Ok(registrar) => registrar, - // again fatal if we can't register macros - Err(err) => fld.cx.span_fatal(krate.span, err.as_slice()) - }; - registrar(|name, extension| { - let extension = match extension { - NormalTT(ext, _) => NormalTT(ext, Some(krate.span)), - IdentTT(ext, _) => IdentTT(ext, Some(krate.span)), - ItemDecorator(ext) => ItemDecorator(ext), - ItemModifier(ext) => ItemModifier(ext), - }; - fld.extsbox.insert(name, extension); - }); - - // Intentionally leak the dynamic library. We can't ever unload it - // since the library can do things that will outlive the expansion - // phase (e.g. make an @-box cycle or launch a task). - mem::forget(lib); - } -} - // expand a stmt pub fn expand_stmt(s: &Stmt, fld: &mut MacroExpander) -> SmallVector<@Stmt> { // why the copying here and not in expand_expr? @@ -969,10 +875,6 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { expand_item(item, self) } - fn fold_view_item(&mut self, vi: &ast::ViewItem) -> ast::ViewItem { - expand_view_item(vi, self) - } - fn fold_stmt(&mut self, stmt: &ast::Stmt) -> SmallVector<@ast::Stmt> { expand_stmt(stmt, self) } @@ -986,14 +888,20 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> { } } -pub struct ExpansionConfig<'a> { - pub loader: &'a mut CrateLoader, +pub struct ExpansionConfig { pub deriving_hash_type_parameter: bool, pub crate_id: CrateId, } +pub struct ExportedMacros { + pub crate_name: Ident, + pub macros: Vec, +} + pub fn expand_crate(parse_sess: &parse::ParseSess, cfg: ExpansionConfig, + macros: Vec, + user_exts: Vec, c: Crate) -> Crate { let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg); let mut expander = MacroExpander { @@ -1001,6 +909,24 @@ pub fn expand_crate(parse_sess: &parse::ParseSess, cx: &mut cx, }; + for ExportedMacros { crate_name, macros } in macros.move_iter() { + let name = format!("<{} macros>", token::get_ident(crate_name)) + .into_string(); + + for source in macros.move_iter() { + let item = parse::parse_item_from_source_str(name.clone(), + source, + expander.cx.cfg(), + expander.cx.parse_sess()) + .expect("expected a serialized item"); + expand_item_mac(item, &mut expander); + } + } + + for (name, extension) in user_exts.move_iter() { + expander.extsbox.insert(name, extension); + } + let ret = expander.fold_crate(c); parse_sess.span_diagnostic.handler().abort_if_errors(); return ret; @@ -1093,7 +1019,6 @@ mod test { use attr; use codemap; use codemap::Spanned; - use ext::base::{CrateLoader, MacroCrate}; use ext::mtwt; use parse; use parse::token; @@ -1137,14 +1062,6 @@ mod test { } } - struct ErrLoader; - - impl CrateLoader for ErrLoader { - fn load_crate(&mut self, _: &ast::ViewItem) -> MacroCrate { - fail!("lolwut") - } - } - // these following tests are quite fragile, in that they don't test what // *kind* of failure occurs. @@ -1159,13 +1076,11 @@ mod test { src, Vec::new(), &sess); // should fail: - let mut loader = ErrLoader; let cfg = ::syntax::ext::expand::ExpansionConfig { - loader: &mut loader, deriving_hash_type_parameter: false, crate_id: from_str("test").unwrap(), }; - expand_crate(&sess,cfg,crate_ast); + expand_crate(&sess,cfg,vec!(),vec!(),crate_ast); } // make sure that macros can leave scope for modules @@ -1178,14 +1093,11 @@ mod test { "".to_string(), src, Vec::new(), &sess); - // should fail: - let mut loader = ErrLoader; let cfg = ::syntax::ext::expand::ExpansionConfig { - loader: &mut loader, deriving_hash_type_parameter: false, crate_id: from_str("test").unwrap(), }; - expand_crate(&sess,cfg,crate_ast); + expand_crate(&sess,cfg,vec!(),vec!(),crate_ast); } // macro_escape modules shouldn't cause macros to leave scope @@ -1198,13 +1110,11 @@ mod test { src, Vec::new(), &sess); // should fail: - let mut loader = ErrLoader; let cfg = ::syntax::ext::expand::ExpansionConfig { - loader: &mut loader, deriving_hash_type_parameter: false, crate_id: from_str("test").unwrap(), }; - expand_crate(&sess, cfg, crate_ast); + expand_crate(&sess, cfg, vec!(), vec!(), crate_ast); } #[test] fn test_contains_flatten (){ @@ -1237,13 +1147,11 @@ mod test { let ps = parse::new_parse_sess(); let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod(); // the cfg argument actually does matter, here... - let mut loader = ErrLoader; let cfg = ::syntax::ext::expand::ExpansionConfig { - loader: &mut loader, deriving_hash_type_parameter: false, crate_id: from_str("test").unwrap(), }; - expand_crate(&ps,cfg,crate_ast) + expand_crate(&ps,cfg,vec!(),vec!(),crate_ast) } //fn expand_and_resolve(crate_str: @str) -> ast::crate { diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 1ab420eb69b..7fe67ad6f87 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -74,7 +74,6 @@ pub mod ext { pub mod asm; pub mod base; pub mod expand; - pub mod registrar; pub mod quote; From ffb2f12ed89213f96561dfbece0751ac870e2c40 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Sat, 24 May 2014 21:15:16 -0700 Subject: [PATCH 2/9] Use phase(plugin) in bootstrap crates Do this to avoid warnings on post-stage0 builds. --- src/compiletest/compiletest.rs | 10 ++++++++-- src/liballoc/lib.rs | 12 ++++++++++-- src/libcollections/lib.rs | 16 +++++++++++++--- src/libflate/lib.rs | 3 ++- src/libgetopts/lib.rs | 3 ++- src/librand/lib.rs | 19 +++++++++++++++++-- src/librustc/lib.rs | 5 +++++ src/librustdoc/lib.rs | 10 ++++++++-- src/librustrt/lib.rs | 10 +++++++++- src/libserialize/lib.rs | 6 ++++++ src/libstd/lib.rs | 3 ++- src/libsync/lib.rs | 5 ++++- src/libsyntax/lib.rs | 7 +++++++ src/libterm/lib.rs | 3 ++- src/libtime/lib.rs | 4 +++- 15 files changed, 98 insertions(+), 18 deletions(-) diff --git a/src/compiletest/compiletest.rs b/src/compiletest/compiletest.rs index 8fcad94ee1c..de0ca4971f5 100644 --- a/src/compiletest/compiletest.rs +++ b/src/compiletest/compiletest.rs @@ -18,11 +18,17 @@ extern crate test; extern crate getopts; -#[phase(link, syntax)] -extern crate log; extern crate green; extern crate rustuv; +#[cfg(stage0)] +#[phase(syntax, link)] +extern crate log; + +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate log; + extern crate regex; use std::os; diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index ca7ed6f4ba0..7e2c9a75fad 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -70,8 +70,14 @@ #![no_std] #![feature(phase)] +#[cfg(stage0)] #[phase(syntax, link)] extern crate core; + +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate core; + extern crate libc; @@ -80,8 +86,10 @@ extern crate libc; #[cfg(test)] extern crate debug; #[cfg(test)] extern crate sync; #[cfg(test)] extern crate native; -#[cfg(test)] #[phase(syntax, link)] extern crate std; -#[cfg(test)] #[phase(syntax, link)] extern crate log; +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std; +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log; // Heaps provided for low-level allocation strategies diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index 602ecf39a83..a114755a0ed 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -23,14 +23,24 @@ #![feature(macro_rules, managed_boxes, default_type_params, phase, globs)] #![no_std] -#[phase(syntax, link)] extern crate core; extern crate alloc; +#[cfg(stage0)] +#[phase(syntax, link)] +extern crate core; + +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate core; + #[cfg(test)] extern crate native; #[cfg(test)] extern crate test; #[cfg(test)] extern crate debug; -#[cfg(test)] #[phase(syntax, link)] extern crate std; -#[cfg(test)] #[phase(syntax, link)] extern crate log; + +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std; +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log; use core::prelude::*; diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 8bfd2d867c1..8d8fe8ffe8c 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -28,7 +28,8 @@ Simple [DEFLATE][def]-based compression. This is a wrapper around the #![feature(phase)] #![deny(deprecated_owned_vector)] -#[cfg(test)] #[phase(syntax, link)] extern crate log; +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log; extern crate libc; diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 10584223486..dec62265516 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -91,7 +91,8 @@ #![deny(deprecated_owned_vector)] #[cfg(test)] extern crate debug; -#[cfg(test)] #[phase(syntax, link)] extern crate log; +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log; use std::cmp::PartialEq; use std::result::{Err, Ok}; diff --git a/src/librand/lib.rs b/src/librand/lib.rs index 7a12dcf9f7f..1f7216fc1a3 100644 --- a/src/librand/lib.rs +++ b/src/librand/lib.rs @@ -28,13 +28,28 @@ #![no_std] #![experimental] +#[cfg(stage0)] #[phase(syntax, link)] extern crate core; +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate core; + +#[cfg(test, stage0)] +#[phase(syntax, link)] extern crate std; + +#[cfg(test, stage0)] +#[phase(syntax, link)] extern crate log; + +#[cfg(test, not(stage0))] +#[phase(plugin, link)] extern crate std; + +#[cfg(test, not(stage0))] +#[phase(plugin, link)] extern crate log; + #[cfg(test)] extern crate native; #[cfg(test)] extern crate debug; -#[cfg(test)] #[phase(syntax, link)] extern crate std; -#[cfg(test)] #[phase(syntax, link)] extern crate log; use core::prelude::*; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index b82dace62ef..bdbb1a98ac5 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -42,9 +42,14 @@ extern crate sync; extern crate syntax; extern crate time; +#[cfg(stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate log; + pub mod middle { pub mod def; pub mod trans; diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e623d54675c..05875f59fbe 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -19,8 +19,6 @@ extern crate debug; extern crate getopts; extern crate libc; -#[phase(syntax, link)] -extern crate log; extern crate rustc; extern crate serialize; extern crate sync; @@ -28,6 +26,14 @@ extern crate syntax; extern crate testing = "test"; extern crate time; +#[cfg(stage0)] +#[phase(syntax, link)] +extern crate log; + +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate log; + use std::io; use std::io::{File, MemWriter}; use std::str; diff --git a/src/librustrt/lib.rs b/src/librustrt/lib.rs index 3158687c6ab..bb57f5c038c 100644 --- a/src/librustrt/lib.rs +++ b/src/librustrt/lib.rs @@ -19,8 +19,14 @@ #![no_std] #![experimental] +#[cfg(stage0)] #[phase(syntax, link)] extern crate core; + +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate core; + extern crate alloc; extern crate libc; extern crate collections; @@ -28,7 +34,9 @@ extern crate collections; #[cfg(test)] extern crate realrustrt = "rustrt"; #[cfg(test)] extern crate test; #[cfg(test)] extern crate native; -#[cfg(test)] #[phase(syntax, link)] extern crate std; + +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate std; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate std; pub use self::util::{Stdio, Stdout, Stderr}; pub use self::unwind::{begin_unwind, begin_unwind_fmt}; diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 08348c96333..33d20ed7bcd 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -27,9 +27,15 @@ Core encoding and decoding interfaces. // test harness access #[cfg(test)] extern crate test; + +#[cfg(stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate log; + pub use self::serialize::{Decoder, Encoder, Decodable, Encodable, DecoderHelpers, EncoderHelpers}; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index fbdbc13e1b4..85813c02d55 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -119,7 +119,8 @@ #[cfg(test)] extern crate native; #[cfg(test)] extern crate green; #[cfg(test)] extern crate debug; -#[cfg(test)] #[phase(syntax, link)] extern crate log; +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log; extern crate alloc; extern crate core; diff --git a/src/libsync/lib.rs b/src/libsync/lib.rs index fc4d5fec5f5..44d17e6fb95 100644 --- a/src/libsync/lib.rs +++ b/src/libsync/lib.rs @@ -25,9 +25,12 @@ #![deny(missing_doc)] -#[cfg(test)] +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(test, not(stage0))] +#[phase(plugin, link)] extern crate log; + extern crate alloc; pub use comm::{DuplexStream, duplex}; diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7fe67ad6f87..754518f5fea 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -32,8 +32,15 @@ This API is completely unstable and subject to change. extern crate serialize; extern crate term; + +#[cfg(stage0)] #[phase(syntax, link)] extern crate log; + +#[cfg(not(stage0))] +#[phase(plugin, link)] +extern crate log; + extern crate fmt_macros; extern crate debug; diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs index cc813262576..76118f642ab 100644 --- a/src/libterm/lib.rs +++ b/src/libterm/lib.rs @@ -52,7 +52,8 @@ #![deny(missing_doc)] -#[phase(syntax, link)] extern crate log; +#[cfg(stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(not(stage0))] #[phase(plugin, link)] extern crate log; pub use terminfo::TerminfoTerminal; #[cfg(windows)] diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs index f087b9289c3..f2af5943335 100644 --- a/src/libtime/lib.rs +++ b/src/libtime/lib.rs @@ -23,7 +23,9 @@ #![deny(deprecated_owned_vector)] #[cfg(test)] extern crate debug; -#[cfg(test)] #[phase(syntax, link)] extern crate log; + +#[cfg(test, stage0)] #[phase(syntax, link)] extern crate log; +#[cfg(test, not(stage0))] #[phase(plugin, link)] extern crate log; extern crate serialize; extern crate libc; From 84243ed6e18643c277724a868e3f11b4137fe3bc Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Sat, 24 May 2014 21:22:52 -0700 Subject: [PATCH 3/9] Use phase(plugin) in other crates --- src/doc/rust.md | 2 +- src/libfourcc/lib.rs | 2 +- src/libgreen/lib.rs | 6 +++--- src/libhexfloat/lib.rs | 2 +- src/liblog/lib.rs | 2 +- src/liblog/macros.rs | 12 ++++++------ src/libregex/lib.rs | 12 ++++++------ src/libregex/re.rs | 26 +++++++++++++------------- src/libregex/test/mod.rs | 2 +- 9 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/doc/rust.md b/src/doc/rust.md index 619e24af360..38883118114 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -4098,7 +4098,7 @@ that demonstrates all four of them: ~~~~ #![feature(phase)] -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; fn main() { error!("This is an error log") diff --git a/src/libfourcc/lib.rs b/src/libfourcc/lib.rs index 194de7b2f4a..9cd62fcdd23 100644 --- a/src/libfourcc/lib.rs +++ b/src/libfourcc/lib.rs @@ -22,7 +22,7 @@ to be `big`, i.e. left-to-right order. It returns a u32. To load the extension and use it: ```rust,ignore -#[phase(syntax)] +#[phase(plugin)] extern crate fourcc; fn main() { diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index 333ac80907f..9748dfbae33 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -148,7 +148,7 @@ //! //! ``` //! #![feature(phase)] -//! #[phase(syntax)] extern crate green; +//! #[phase(plugin)] extern crate green; //! //! green_start!(main) //! @@ -211,7 +211,7 @@ #![allow(visible_private_types)] #![deny(deprecated_owned_vector)] -#[cfg(test)] #[phase(syntax, link)] extern crate log; +#[cfg(test)] #[phase(plugin, link)] extern crate log; #[cfg(test)] extern crate rustuv; extern crate libc; extern crate alloc; @@ -249,7 +249,7 @@ pub mod task; /// /// ``` /// #![feature(phase)] -/// #[phase(syntax)] extern crate green; +/// #[phase(plugin)] extern crate green; /// /// green_start!(main) /// diff --git a/src/libhexfloat/lib.rs b/src/libhexfloat/lib.rs index ee14f1aaea9..448f23eaedb 100644 --- a/src/libhexfloat/lib.rs +++ b/src/libhexfloat/lib.rs @@ -21,7 +21,7 @@ literal. To load the extension and use it: ```rust,ignore -#[phase(syntax)] +#[phase(plugin)] extern crate hexfloat; fn main() { diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs index daacf8b3c47..254f9aaf55e 100644 --- a/src/liblog/lib.rs +++ b/src/liblog/lib.rs @@ -16,7 +16,7 @@ Utilities for program-wide and customizable logging ``` #![feature(phase)] -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; fn main() { debug!("this is a debug {}", "message"); diff --git a/src/liblog/macros.rs b/src/liblog/macros.rs index 3bb49c237f1..dba34c42a7e 100644 --- a/src/liblog/macros.rs +++ b/src/liblog/macros.rs @@ -22,7 +22,7 @@ /// /// ``` /// #![feature(phase)] -/// #[phase(syntax, link)] extern crate log; +/// #[phase(plugin, link)] extern crate log; /// /// # fn main() { /// log!(log::DEBUG, "this is a debug message"); @@ -51,7 +51,7 @@ macro_rules! log( /// /// ``` /// #![feature(phase)] -/// #[phase(syntax, link)] extern crate log; +/// #[phase(plugin, link)] extern crate log; /// /// # fn main() { /// # let error = 3; @@ -69,7 +69,7 @@ macro_rules! error( /// /// ``` /// #![feature(phase)] -/// #[phase(syntax, link)] extern crate log; +/// #[phase(plugin, link)] extern crate log; /// /// # fn main() { /// # let code = 3; @@ -87,7 +87,7 @@ macro_rules! warn( /// /// ``` /// #![feature(phase)] -/// #[phase(syntax, link)] extern crate log; +/// #[phase(plugin, link)] extern crate log; /// /// # fn main() { /// # let ret = 3; @@ -107,7 +107,7 @@ macro_rules! info( /// /// ``` /// #![feature(phase)] -/// #[phase(syntax, link)] extern crate log; +/// #[phase(plugin, link)] extern crate log; /// /// # fn main() { /// debug!("x = {x}, y = {y}", x=10, y=20); @@ -124,7 +124,7 @@ macro_rules! debug( /// /// ``` /// #![feature(phase)] -/// #[phase(syntax, link)] extern crate log; +/// #[phase(plugin, link)] extern crate log; /// /// # fn main() { /// # struct Point { x: int, y: int } diff --git a/src/libregex/lib.rs b/src/libregex/lib.rs index 44c206162ab..61e62a0d105 100644 --- a/src/libregex/lib.rs +++ b/src/libregex/lib.rs @@ -65,7 +65,7 @@ //! //! ```rust //! #![feature(phase)] -//! #[phase(syntax)] +//! #[phase(plugin)] //! extern crate regex_macros; //! extern crate regex; //! @@ -95,7 +95,7 @@ //! //! ```rust //! # #![feature(phase)] -//! # extern crate regex; #[phase(syntax)] extern crate regex_macros; +//! # extern crate regex; #[phase(plugin)] extern crate regex_macros; //! # fn main() { //! let re = regex!(r"(\d{4})-(\d{2})-(\d{2})"); //! let text = "2012-03-14, 2013-01-01 and 2014-07-05"; @@ -121,7 +121,7 @@ //! //! ```rust //! # #![feature(phase)] -//! # extern crate regex; #[phase(syntax)] extern crate regex_macros; +//! # extern crate regex; #[phase(plugin)] extern crate regex_macros; //! # fn main() { //! let re = regex!(r"(?P\d{4})-(?P\d{2})-(?P\d{2})"); //! let before = "2012-03-14, 2013-01-01 and 2014-07-05"; @@ -168,7 +168,7 @@ //! //! ```rust //! # #![feature(phase)] -//! # extern crate regex; #[phase(syntax)] extern crate regex_macros; +//! # extern crate regex; #[phase(plugin)] extern crate regex_macros; //! # fn main() { //! let re = regex!(r"(?i)Δ+"); //! assert_eq!(re.find("ΔδΔ"), Some((0, 6))); @@ -181,7 +181,7 @@ //! //! ```rust //! # #![feature(phase)] -//! # extern crate regex; #[phase(syntax)] extern crate regex_macros; +//! # extern crate regex; #[phase(plugin)] extern crate regex_macros; //! # fn main() { //! let re = regex!(r"[\pN\p{Greek}\p{Cherokee}]+"); //! assert_eq!(re.find("abcΔᎠβⅠᏴγδⅡxyz"), Some((3, 23))); @@ -278,7 +278,7 @@ //! //! ```rust //! # #![feature(phase)] -//! # extern crate regex; #[phase(syntax)] extern crate regex_macros; +//! # extern crate regex; #[phase(plugin)] extern crate regex_macros; //! # fn main() { //! let re = regex!(r"(?i)a+(?-i)b+"); //! let cap = re.captures("AaAaAbbBBBb").unwrap(); diff --git a/src/libregex/re.rs b/src/libregex/re.rs index a499c1e125d..054cbb0fcd6 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -87,7 +87,7 @@ pub fn is_match(regex: &str, text: &str) -> Result { /// ```rust /// #![feature(phase)] /// extern crate regex; -/// #[phase(syntax)] extern crate regex_macros; +/// #[phase(plugin)] extern crate regex_macros; /// /// fn main() { /// let re = regex!(r"\d+"); @@ -172,7 +172,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let text = "I categorically deny having triskaidekaphobia."; /// let matched = regex!(r"\b\w{13}\b").is_match(text); @@ -197,7 +197,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let text = "I categorically deny having triskaidekaphobia."; /// let pos = regex!(r"\b\w{13}\b").find(text); @@ -224,7 +224,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let text = "Retroactively relinquishing remunerations is reprehensible."; /// for pos in regex!(r"\b\w{13}\b").find_iter(text) { @@ -263,7 +263,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let re = regex!(r"'([^']+)'\s+\((\d{4})\)"); /// let text = "Not my favorite movie: 'Citizen Kane' (1941)."; @@ -281,7 +281,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let re = regex!(r"'(?P[^']+)'\s+\((?P<year>\d{4})\)"); /// let text = "Not my favorite movie: 'Citizen Kane' (1941)."; @@ -314,7 +314,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let re = regex!(r"'(?P<title>[^']+)'\s+\((?P<year>\d{4})\)"); /// let text = "'Citizen Kane' (1941), 'The Wizard of Oz' (1939), 'M' (1931)."; @@ -350,7 +350,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let re = regex!(r"[ \t]+"); /// let fields: Vec<&str> = re.split("a b \t c\td e").collect(); @@ -380,7 +380,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let re = regex!(r"\W+"); /// let fields: Vec<&str> = re.splitn("Hey! How are you?", 3).collect(); @@ -410,7 +410,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let re = regex!("[^01]+"); /// assert_eq!(re.replace("1078910", "").as_slice(), "1010"); @@ -424,7 +424,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # use regex::Captures; fn main() { /// let re = regex!(r"([^,\s]+),\s+(\S+)"); /// let result = re.replace("Springsteen, Bruce", |caps: &Captures| { @@ -441,7 +441,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// let re = regex!(r"(?P<last>[^,\s]+),\s+(?P<first>\S+)"); /// let result = re.replace("Springsteen, Bruce", "$first $last"); @@ -458,7 +458,7 @@ impl Regex { /// /// ```rust /// # #![feature(phase)] - /// # extern crate regex; #[phase(syntax)] extern crate regex_macros; + /// # extern crate regex; #[phase(plugin)] extern crate regex_macros; /// # fn main() { /// use regex::NoExpand; /// diff --git a/src/libregex/test/mod.rs b/src/libregex/test/mod.rs index c563c84fc34..96c600b0fda 100644 --- a/src/libregex/test/mod.rs +++ b/src/libregex/test/mod.rs @@ -9,7 +9,7 @@ // except according to those terms. #[cfg(not(stage1))] -#[phase(syntax)] +#[phase(plugin)] extern crate regex_macros; #[cfg(not(stage1))] From ed41b71fbe69cc920a3a021ac4e96dc4d5cc488c Mon Sep 17 00:00:00 2001 From: Keegan McAllister <kmcallister@mozilla.com> Date: Sat, 24 May 2014 21:24:35 -0700 Subject: [PATCH 4/9] Use phase(plugin) in tests --- src/test/auxiliary/issue-13560-3.rs | 4 ++-- src/test/auxiliary/logging_right_crate.rs | 2 +- src/test/auxiliary/weak-lang-items.rs | 2 +- src/test/bench/shootout-chameneos-redux.rs | 2 +- src/test/bench/shootout-meteor.rs | 2 +- src/test/bench/shootout-regex-dna.rs | 2 +- src/test/bench/shootout-spectralnorm.rs | 2 +- src/test/bench/shootout-threadring.rs | 2 +- src/test/compile-fail-fulldeps/gated-phase.rs | 2 +- .../compile-fail-fulldeps/macro-crate-unexported-macro.rs | 2 +- src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs | 2 +- src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs | 2 +- .../compile-fail-fulldeps/syntax-extension-fourcc-bad-len.rs | 2 +- .../syntax-extension-fourcc-invalid-endian.rs | 2 +- .../syntax-extension-fourcc-non-ascii-str.rs | 2 +- .../syntax-extension-fourcc-non-literal.rs | 2 +- .../syntax-extension-fourcc-unsupported-literal.rs | 2 +- .../syntax-extension-hexfloat-bad-lits.rs | 2 +- .../syntax-extension-hexfloat-bad-types.rs | 2 +- .../compile-fail-fulldeps/syntax-extension-regex-invalid.rs | 2 +- .../syntax-extension-regex-unused-static.rs | 2 +- .../compile-fail-fulldeps/syntax-extension-regex-unused.rs | 2 +- src/test/run-fail/rt-set-exit-status-fail.rs | 2 +- src/test/run-fail/rt-set-exit-status-fail2.rs | 2 +- src/test/run-fail/rt-set-exit-status.rs | 2 +- src/test/run-make/lto-syntax-extension/main.rs | 2 +- .../run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs | 2 +- src/test/run-pass-fulldeps/macro-crate.rs | 2 +- src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs | 2 +- src/test/run-pass-fulldeps/syntax-extension-fourcc.rs | 2 +- src/test/run-pass-fulldeps/syntax-extension-hexfloat.rs | 2 +- src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs | 2 +- src/test/run-pass/capturing-logging.rs | 2 +- src/test/run-pass/conditional-debug-macro-off.rs | 2 +- src/test/run-pass/issue-14456.rs | 2 +- src/test/run-pass/logging-enabled-debug.rs | 2 +- src/test/run-pass/logging-enabled.rs | 2 +- src/test/run-pass/logging-separate-lines.rs | 2 +- src/test/run-pass/macro-crate-def-only.rs | 2 +- src/test/run-pass/macro-export-inner-module.rs | 2 +- src/test/run-pass/phase-use-ignored.rs | 2 +- src/test/run-pass/tcp-stress.rs | 2 +- 42 files changed, 43 insertions(+), 43 deletions(-) diff --git a/src/test/auxiliary/issue-13560-3.rs b/src/test/auxiliary/issue-13560-3.rs index 3b77b244ce8..dfd13851774 100644 --- a/src/test/auxiliary/issue-13560-3.rs +++ b/src/test/auxiliary/issue-13560-3.rs @@ -13,6 +13,6 @@ #![crate_type = "rlib"] #![feature(phase)] -#[phase(syntax)] extern crate t1 = "issue-13560-1"; -#[phase(syntax, link)] extern crate t2 = "issue-13560-2"; +#[phase(plugin)] extern crate t1 = "issue-13560-1"; +#[phase(plugin, link)] extern crate t2 = "issue-13560-2"; diff --git a/src/test/auxiliary/logging_right_crate.rs b/src/test/auxiliary/logging_right_crate.rs index 3f0da3e344a..0c4af97b410 100644 --- a/src/test/auxiliary/logging_right_crate.rs +++ b/src/test/auxiliary/logging_right_crate.rs @@ -9,7 +9,7 @@ // except according to those terms. #![feature(phase)] -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; extern crate debug; pub fn foo<T>() { diff --git a/src/test/auxiliary/weak-lang-items.rs b/src/test/auxiliary/weak-lang-items.rs index 68a2ae24b85..c998e362d7e 100644 --- a/src/test/auxiliary/weak-lang-items.rs +++ b/src/test/auxiliary/weak-lang-items.rs @@ -17,7 +17,7 @@ #![feature(phase)] #![crate_type = "rlib"] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate core; struct A; diff --git a/src/test/bench/shootout-chameneos-redux.rs b/src/test/bench/shootout-chameneos-redux.rs index baf02feb5b8..28786f1e163 100644 --- a/src/test/bench/shootout-chameneos-redux.rs +++ b/src/test/bench/shootout-chameneos-redux.rs @@ -11,7 +11,7 @@ // no-pretty-expanded #![feature(phase)] -#[phase(syntax)] extern crate green; +#[phase(plugin)] extern crate green; use std::string::String; use std::fmt; diff --git a/src/test/bench/shootout-meteor.rs b/src/test/bench/shootout-meteor.rs index 6f4aef27b63..afefaf2b535 100644 --- a/src/test/bench/shootout-meteor.rs +++ b/src/test/bench/shootout-meteor.rs @@ -39,7 +39,7 @@ // OF THE POSSIBILITY OF SUCH DAMAGE. #![feature(phase)] -#[phase(syntax)] extern crate green; +#[phase(plugin)] extern crate green; extern crate sync; use sync::Arc; diff --git a/src/test/bench/shootout-regex-dna.rs b/src/test/bench/shootout-regex-dna.rs index c2f0a58a288..ca0248bcf5d 100644 --- a/src/test/bench/shootout-regex-dna.rs +++ b/src/test/bench/shootout-regex-dna.rs @@ -46,7 +46,7 @@ #![feature(macro_rules, phase)] extern crate regex; -#[phase(syntax)]extern crate regex_macros; +#[phase(plugin)]extern crate regex_macros; extern crate sync; use std::io; diff --git a/src/test/bench/shootout-spectralnorm.rs b/src/test/bench/shootout-spectralnorm.rs index c038a056569..15b7ff1e81e 100644 --- a/src/test/bench/shootout-spectralnorm.rs +++ b/src/test/bench/shootout-spectralnorm.rs @@ -10,7 +10,7 @@ #![feature(phase)] #![allow(non_snake_case_functions)] -#[phase(syntax)] extern crate green; +#[phase(plugin)] extern crate green; extern crate sync; use std::from_str::FromStr; diff --git a/src/test/bench/shootout-threadring.rs b/src/test/bench/shootout-threadring.rs index 1a6582927ca..a001ff78ba0 100644 --- a/src/test/bench/shootout-threadring.rs +++ b/src/test/bench/shootout-threadring.rs @@ -9,7 +9,7 @@ // except according to those terms. #![feature(phase)] -#[phase(syntax)] extern crate green; +#[phase(plugin)] extern crate green; green_start!(main) fn start(n_tasks: int, token: int) { diff --git a/src/test/compile-fail-fulldeps/gated-phase.rs b/src/test/compile-fail-fulldeps/gated-phase.rs index c8763899269..1f384b85633 100644 --- a/src/test/compile-fail-fulldeps/gated-phase.rs +++ b/src/test/compile-fail-fulldeps/gated-phase.rs @@ -11,7 +11,7 @@ // aux-build:macro_crate_test.rs // ignore-stage1 -#[phase(syntax)] +#[phase(plugin)] //~^ ERROR compile time crate loading is experimental and possibly buggy extern crate macro_crate_test; diff --git a/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs b/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs index f8eb9868a5b..39c2accaddf 100644 --- a/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs +++ b/src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs @@ -14,7 +14,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate macro_crate_test; fn main() { diff --git a/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs b/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs index 84c915f267e..7a7eac7b709 100644 --- a/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs +++ b/src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs @@ -10,7 +10,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate doesnt_exist; //~ ERROR can't find crate fn main() {} diff --git a/src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs b/src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs index 2053f81683d..274fbf797e1 100644 --- a/src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs +++ b/src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs @@ -14,7 +14,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate macro_crate_test; fn main() { diff --git a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-bad-len.rs b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-bad-len.rs index fbcdf55f1ac..3ad17618fc0 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-bad-len.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-bad-len.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate fourcc; fn main() { diff --git a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-invalid-endian.rs b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-invalid-endian.rs index 569b54b93fb..4d425d9a205 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-invalid-endian.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-invalid-endian.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate fourcc; fn main() { diff --git a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-ascii-str.rs b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-ascii-str.rs index c0e2304354c..1a6d747c1e8 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-ascii-str.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-ascii-str.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate fourcc; fn main() { diff --git a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-literal.rs b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-literal.rs index 536594f3063..885d8dd1ec3 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-literal.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-non-literal.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate fourcc; fn main() { diff --git a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-unsupported-literal.rs b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-unsupported-literal.rs index 8a0b0856d24..da1c0070715 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-fourcc-unsupported-literal.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-fourcc-unsupported-literal.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate fourcc; fn main() { diff --git a/src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-lits.rs b/src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-lits.rs index 1cd4f654d2e..191042f5f56 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-lits.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-lits.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate hexfloat; fn main() { diff --git a/src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-types.rs b/src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-types.rs index 4a6475cea96..f0ace43ec9e 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-types.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-hexfloat-bad-types.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate hexfloat; fn main() { diff --git a/src/test/compile-fail-fulldeps/syntax-extension-regex-invalid.rs b/src/test/compile-fail-fulldeps/syntax-extension-regex-invalid.rs index 0e072dc1c06..bccba74e05c 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-regex-invalid.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-regex-invalid.rs @@ -15,7 +15,7 @@ #![feature(phase)] extern crate regex; -#[phase(syntax)] extern crate regex_macros; +#[phase(plugin)] extern crate regex_macros; // Tests to make sure that `regex!` will produce a compile error when given // an invalid regular expression. diff --git a/src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs b/src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs index 300e7e524df..819c9e6b0fe 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-regex-unused-static.rs @@ -15,7 +15,7 @@ #![feature(phase)] extern crate regex; -#[phase(syntax)] extern crate regex_macros; +#[phase(plugin)] extern crate regex_macros; #[deny(unused_variable)] #[deny(dead_code)] diff --git a/src/test/compile-fail-fulldeps/syntax-extension-regex-unused.rs b/src/test/compile-fail-fulldeps/syntax-extension-regex-unused.rs index c77bd52d9e5..d96b3f6f224 100644 --- a/src/test/compile-fail-fulldeps/syntax-extension-regex-unused.rs +++ b/src/test/compile-fail-fulldeps/syntax-extension-regex-unused.rs @@ -15,7 +15,7 @@ #![feature(phase)] extern crate regex; -#[phase(syntax)] extern crate regex_macros; +#[phase(plugin)] extern crate regex_macros; #[deny(unused_variable)] #[deny(dead_code)] diff --git a/src/test/run-fail/rt-set-exit-status-fail.rs b/src/test/run-fail/rt-set-exit-status-fail.rs index 385bc145204..c960679a43f 100644 --- a/src/test/run-fail/rt-set-exit-status-fail.rs +++ b/src/test/run-fail/rt-set-exit-status-fail.rs @@ -11,7 +11,7 @@ // error-pattern:whatever #![feature(phase)] -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; use std::os; fn main() { diff --git a/src/test/run-fail/rt-set-exit-status-fail2.rs b/src/test/run-fail/rt-set-exit-status-fail2.rs index 3b5e27027b4..22985d57936 100644 --- a/src/test/run-fail/rt-set-exit-status-fail2.rs +++ b/src/test/run-fail/rt-set-exit-status-fail2.rs @@ -11,7 +11,7 @@ // error-pattern:whatever #![feature(phase)] -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; use std::os; use std::task; diff --git a/src/test/run-fail/rt-set-exit-status.rs b/src/test/run-fail/rt-set-exit-status.rs index b94045e5d12..d08cb198802 100644 --- a/src/test/run-fail/rt-set-exit-status.rs +++ b/src/test/run-fail/rt-set-exit-status.rs @@ -11,7 +11,7 @@ // error-pattern:whatever #![feature(phase)] -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; use std::os; fn main() { diff --git a/src/test/run-make/lto-syntax-extension/main.rs b/src/test/run-make/lto-syntax-extension/main.rs index 0c55d5fd314..ec4fbca48f8 100644 --- a/src/test/run-make/lto-syntax-extension/main.rs +++ b/src/test/run-make/lto-syntax-extension/main.rs @@ -11,7 +11,7 @@ #![feature(phase)] extern crate lib; -#[phase(syntax)] extern crate fourcc; +#[phase(plugin)] extern crate fourcc; fn main() { fourcc!("1234"); diff --git a/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs index 58663bb44c7..15f5e84b2a7 100644 --- a/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs +++ b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate macro_crate_outlive_expansion_phase; pub fn main() {} diff --git a/src/test/run-pass-fulldeps/macro-crate.rs b/src/test/run-pass-fulldeps/macro-crate.rs index 3c620c5e572..1e796d9d724 100644 --- a/src/test/run-pass-fulldeps/macro-crate.rs +++ b/src/test/run-pass-fulldeps/macro-crate.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate macro_crate_test; #[into_foo] diff --git a/src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs b/src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs index b8d3ab23831..47ff7d31df5 100644 --- a/src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs +++ b/src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs @@ -17,7 +17,7 @@ #![feature(phase)] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate macro_crate_test; fn main() { diff --git a/src/test/run-pass-fulldeps/syntax-extension-fourcc.rs b/src/test/run-pass-fulldeps/syntax-extension-fourcc.rs index 0681ec63b9e..b16975fe6ee 100644 --- a/src/test/run-pass-fulldeps/syntax-extension-fourcc.rs +++ b/src/test/run-pass-fulldeps/syntax-extension-fourcc.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate fourcc; static static_val: u32 = fourcc!("foo "); diff --git a/src/test/run-pass-fulldeps/syntax-extension-hexfloat.rs b/src/test/run-pass-fulldeps/syntax-extension-hexfloat.rs index 3601b610115..496b0111363 100644 --- a/src/test/run-pass-fulldeps/syntax-extension-hexfloat.rs +++ b/src/test/run-pass-fulldeps/syntax-extension-hexfloat.rs @@ -12,7 +12,7 @@ // ignore-pretty #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate hexfloat; pub fn main() { diff --git a/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs b/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs index efae04ea4fc..275463f5d7f 100644 --- a/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs +++ b/src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs @@ -14,7 +14,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate extension = "syntax-extension-with-dll-deps-2"; fn main() { diff --git a/src/test/run-pass/capturing-logging.rs b/src/test/run-pass/capturing-logging.rs index 636e879fe32..3402db7c355 100644 --- a/src/test/run-pass/capturing-logging.rs +++ b/src/test/run-pass/capturing-logging.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate log; extern crate native; diff --git a/src/test/run-pass/conditional-debug-macro-off.rs b/src/test/run-pass/conditional-debug-macro-off.rs index 56b38033c83..b7c4ccb3c2a 100644 --- a/src/test/run-pass/conditional-debug-macro-off.rs +++ b/src/test/run-pass/conditional-debug-macro-off.rs @@ -12,7 +12,7 @@ // exec-env:RUST_LOG=conditional-debug-macro-off=4 #![feature(phase)] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate log; extern crate debug; diff --git a/src/test/run-pass/issue-14456.rs b/src/test/run-pass/issue-14456.rs index 79203503373..96290386ccc 100644 --- a/src/test/run-pass/issue-14456.rs +++ b/src/test/run-pass/issue-14456.rs @@ -10,7 +10,7 @@ #![feature(phase)] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate green; extern crate native; diff --git a/src/test/run-pass/logging-enabled-debug.rs b/src/test/run-pass/logging-enabled-debug.rs index 9320c77a285..7975af434d2 100644 --- a/src/test/run-pass/logging-enabled-debug.rs +++ b/src/test/run-pass/logging-enabled-debug.rs @@ -12,7 +12,7 @@ // exec-env:RUST_LOG=logging-enabled-debug=debug #![feature(phase)] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate log; pub fn main() { diff --git a/src/test/run-pass/logging-enabled.rs b/src/test/run-pass/logging-enabled.rs index b1d24e8b9b6..184ac713c89 100644 --- a/src/test/run-pass/logging-enabled.rs +++ b/src/test/run-pass/logging-enabled.rs @@ -11,7 +11,7 @@ // exec-env:RUST_LOG=logging-enabled=info #![feature(phase)] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate log; pub fn main() { diff --git a/src/test/run-pass/logging-separate-lines.rs b/src/test/run-pass/logging-separate-lines.rs index 7f9a4593780..989a8d4bde5 100644 --- a/src/test/run-pass/logging-separate-lines.rs +++ b/src/test/run-pass/logging-separate-lines.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate log; use std::io::Command; diff --git a/src/test/run-pass/macro-crate-def-only.rs b/src/test/run-pass/macro-crate-def-only.rs index abf8edc274c..25da809babd 100644 --- a/src/test/run-pass/macro-crate-def-only.rs +++ b/src/test/run-pass/macro-crate-def-only.rs @@ -12,7 +12,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate macro_crate_def_only; pub fn main() { diff --git a/src/test/run-pass/macro-export-inner-module.rs b/src/test/run-pass/macro-export-inner-module.rs index 179c65cd046..c7911a69ce4 100644 --- a/src/test/run-pass/macro-export-inner-module.rs +++ b/src/test/run-pass/macro-export-inner-module.rs @@ -13,7 +13,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] extern crate macro_export_inner_module; pub fn main() { diff --git a/src/test/run-pass/phase-use-ignored.rs b/src/test/run-pass/phase-use-ignored.rs index 60f2619fffd..5015e43fa3f 100644 --- a/src/test/run-pass/phase-use-ignored.rs +++ b/src/test/run-pass/phase-use-ignored.rs @@ -11,7 +11,7 @@ #![feature(phase)] -#[phase(syntax)] +#[phase(plugin)] use std::mem; fn main() {} diff --git a/src/test/run-pass/tcp-stress.rs b/src/test/run-pass/tcp-stress.rs index a9a6e25adf3..9c4716e5f4d 100644 --- a/src/test/run-pass/tcp-stress.rs +++ b/src/test/run-pass/tcp-stress.rs @@ -13,7 +13,7 @@ // exec-env:RUST_LOG=debug #![feature(phase)] -#[phase(syntax, link)] +#[phase(plugin, link)] extern crate log; extern crate libc; extern crate green; From aca0bac29f7d7e86edfb5850cef1ab9b5e4797f2 Mon Sep 17 00:00:00 2001 From: Keegan McAllister <kmcallister@mozilla.com> Date: Sat, 24 May 2014 21:31:50 -0700 Subject: [PATCH 5/9] Convert libraries to use #[plugin_registrar] --- src/doc/rust.md | 5 ++--- src/libfourcc/lib.rs | 18 +++++++----------- src/libhexfloat/lib.rs | 18 +++++++----------- src/libregex_macros/lib.rs | 17 ++++++++--------- 4 files changed, 24 insertions(+), 34 deletions(-) diff --git a/src/doc/rust.md b/src/doc/rust.md index 38883118114..35d356bb1b5 100644 --- a/src/doc/rust.md +++ b/src/doc/rust.md @@ -1819,9 +1819,8 @@ type int8_t = i8; ### Function-only attributes -- `macro_registrar` - when using loadable syntax extensions, mark this - function as the registration point for the current crate's syntax - extensions. +- `plugin_registrar` - mark this function as the registration point for + compiler plugins, such as loadable syntax extensions. - `main` - indicates that this function should be passed to the entry point, rather than the function in the crate root named `main`. - `start` - indicates that this function should be used as the entry point, diff --git a/src/libfourcc/lib.rs b/src/libfourcc/lib.rs index 9cd62fcdd23..694fe7d0f48 100644 --- a/src/libfourcc/lib.rs +++ b/src/libfourcc/lib.rs @@ -48,29 +48,25 @@ fn main() { html_root_url = "http://doc.rust-lang.org/")] #![deny(deprecated_owned_vector)] -#![feature(macro_registrar, managed_boxes)] +#![feature(plugin_registrar, managed_boxes)] extern crate syntax; +extern crate rustc; use syntax::ast; -use syntax::ast::Name; use syntax::attr::contains; use syntax::codemap::{Span, mk_sp}; use syntax::ext::base; -use syntax::ext::base::{SyntaxExtension, BasicMacroExpander, NormalTT, ExtCtxt, MacExpr}; +use syntax::ext::base::{ExtCtxt, MacExpr}; use syntax::ext::build::AstBuilder; use syntax::parse; use syntax::parse::token; use syntax::parse::token::InternedString; +use rustc::plugin::Registry; -#[macro_registrar] -pub fn macro_registrar(register: |Name, SyntaxExtension|) { - register(token::intern("fourcc"), - NormalTT(box BasicMacroExpander { - expander: expand_syntax_ext, - span: None, - }, - None)); +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("fourcc", expand_syntax_ext); } pub fn expand_syntax_ext(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) diff --git a/src/libhexfloat/lib.rs b/src/libhexfloat/lib.rs index 448f23eaedb..54bc2802b09 100644 --- a/src/libhexfloat/lib.rs +++ b/src/libhexfloat/lib.rs @@ -45,27 +45,23 @@ fn main() { html_root_url = "http://doc.rust-lang.org/")] #![deny(deprecated_owned_vector)] -#![feature(macro_registrar, managed_boxes)] +#![feature(plugin_registrar, managed_boxes)] extern crate syntax; +extern crate rustc; use syntax::ast; -use syntax::ast::Name; use syntax::codemap::{Span, mk_sp}; use syntax::ext::base; -use syntax::ext::base::{SyntaxExtension, BasicMacroExpander, NormalTT, ExtCtxt, MacExpr}; +use syntax::ext::base::{ExtCtxt, MacExpr}; use syntax::ext::build::AstBuilder; use syntax::parse; use syntax::parse::token; +use rustc::plugin::Registry; -#[macro_registrar] -pub fn macro_registrar(register: |Name, SyntaxExtension|) { - register(token::intern("hexfloat"), - NormalTT(box BasicMacroExpander { - expander: expand_syntax_ext, - span: None, - }, - None)); +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("hexfloat", expand_syntax_ext); } //Check if the literal is valid (as LLVM expects), diff --git a/src/libregex_macros/lib.rs b/src/libregex_macros/lib.rs index fb7e4211d49..bbee09d0f38 100644 --- a/src/libregex_macros/lib.rs +++ b/src/libregex_macros/lib.rs @@ -19,24 +19,24 @@ html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_root_url = "http://doc.rust-lang.org/")] -#![feature(macro_registrar, managed_boxes, quote)] +#![feature(plugin_registrar, managed_boxes, quote)] extern crate regex; extern crate syntax; +extern crate rustc; use std::rc::Rc; use syntax::ast; use syntax::codemap; use syntax::ext::build::AstBuilder; -use syntax::ext::base::{ - SyntaxExtension, ExtCtxt, MacResult, MacExpr, DummyResult, - NormalTT, BasicMacroExpander, -}; +use syntax::ext::base::{ExtCtxt, MacResult, MacExpr, DummyResult}; use syntax::parse; use syntax::parse::token; use syntax::print::pprust; +use rustc::plugin::Registry; + use regex::Regex; use regex::native::{ OneChar, CharClass, Any, Save, Jump, Split, @@ -46,11 +46,10 @@ use regex::native::{ }; /// For the `regex!` syntax extension. Do not use. -#[macro_registrar] +#[plugin_registrar] #[doc(hidden)] -pub fn macro_registrar(register: |ast::Name, SyntaxExtension|) { - let expander = box BasicMacroExpander { expander: native, span: None }; - register(token::intern("regex"), NormalTT(expander, None)) +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("regex", native); } /// Generates specialized code for the Pike VM for a particular regular From 5084de3aafa4b8e014a1b8698fdd2e5e62b97fa7 Mon Sep 17 00:00:00 2001 From: Keegan McAllister <kmcallister@mozilla.com> Date: Sat, 24 May 2014 21:38:16 -0700 Subject: [PATCH 6/9] Convert tests to use #[plugin_registrar] --- src/test/auxiliary/macro_crate_test.rs | 21 +++++++++---------- ...> plugin_crate_outlive_expansion_phase.rs} | 11 +++++----- .../syntax-extension-with-dll-deps-2.rs | 18 +++++++--------- ...registrar.rs => gated-plugin_registrar.rs} | 4 ++-- ...trars.rs => multiple-plugin-registrars.rs} | 8 +++---- .../macro-crate-outlive-expansion-phase.rs | 4 ++-- 6 files changed, 30 insertions(+), 36 deletions(-) rename src/test/auxiliary/{macro_crate_outlive_expansion_phase.rs => plugin_crate_outlive_expansion_phase.rs} (79%) rename src/test/compile-fail/{gated-macro_registrar.rs => gated-plugin_registrar.rs} (84%) rename src/test/compile-fail/{multiple-macro-registrars.rs => multiple-plugin-registrars.rs} (81%) diff --git a/src/test/auxiliary/macro_crate_test.rs b/src/test/auxiliary/macro_crate_test.rs index 95f2a8c1ca1..805b8a894cb 100644 --- a/src/test/auxiliary/macro_crate_test.rs +++ b/src/test/auxiliary/macro_crate_test.rs @@ -10,29 +10,28 @@ // force-host -#![feature(globs, macro_registrar, macro_rules, quote, managed_boxes)] +#![feature(globs, plugin_registrar, macro_rules, quote, managed_boxes)] extern crate syntax; +extern crate rustc; -use syntax::ast::{Name, TokenTree, Item, MetaItem}; +use syntax::ast::{TokenTree, Item, MetaItem}; use syntax::codemap::Span; use syntax::ext::base::*; use syntax::parse::token; +use rustc::plugin::Registry; #[macro_export] macro_rules! exported_macro (() => (2)) macro_rules! unexported_macro (() => (3)) -#[macro_registrar] -pub fn macro_registrar(register: |Name, SyntaxExtension|) { - register(token::intern("make_a_1"), - NormalTT(box BasicMacroExpander { - expander: expand_make_a_1, - span: None, - }, - None)); - register(token::intern("into_foo"), ItemModifier(expand_into_foo)); +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("make_a_1", expand_make_a_1); + reg.register_syntax_extension( + token::intern("into_foo"), + ItemModifier(expand_into_foo)); } fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) diff --git a/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs b/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs similarity index 79% rename from src/test/auxiliary/macro_crate_outlive_expansion_phase.rs rename to src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs index 670673fe047..213fdd6b74a 100644 --- a/src/test/auxiliary/macro_crate_outlive_expansion_phase.rs +++ b/src/test/auxiliary/plugin_crate_outlive_expansion_phase.rs @@ -10,13 +10,12 @@ // force-host -#![feature(macro_registrar)] +#![feature(plugin_registrar)] -extern crate syntax; +extern crate rustc; use std::any::Any; -use syntax::ast::Name; -use syntax::ext::base::SyntaxExtension; +use rustc::plugin::Registry; struct Foo { foo: int @@ -26,8 +25,8 @@ impl Drop for Foo { fn drop(&mut self) {} } -#[macro_registrar] -pub fn registrar(_: |Name, SyntaxExtension|) { +#[plugin_registrar] +pub fn registrar(_: &mut Registry) { local_data_key!(foo: Box<Any:Send>); foo.replace(Some(box Foo { foo: 10 } as Box<Any:Send>)); } diff --git a/src/test/auxiliary/syntax-extension-with-dll-deps-2.rs b/src/test/auxiliary/syntax-extension-with-dll-deps-2.rs index 93b56a7600d..04318fcae27 100644 --- a/src/test/auxiliary/syntax-extension-with-dll-deps-2.rs +++ b/src/test/auxiliary/syntax-extension-with-dll-deps-2.rs @@ -12,24 +12,20 @@ // no-prefer-dynamic #![crate_type = "dylib"] -#![feature(macro_registrar, quote, globs)] +#![feature(plugin_registrar, quote, globs)] extern crate other = "syntax-extension-with-dll-deps-1"; extern crate syntax; +extern crate rustc; -use syntax::ast::{Name, TokenTree, Item, MetaItem}; +use syntax::ast::{TokenTree, Item, MetaItem}; use syntax::codemap::Span; use syntax::ext::base::*; -use syntax::parse::token; +use rustc::plugin::Registry; -#[macro_registrar] -pub fn macro_registrar(register: |Name, SyntaxExtension|) { - register(token::intern("foo"), - NormalTT(box BasicMacroExpander { - expander: expand_foo, - span: None, - }, - None)); +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_macro("foo", expand_foo); } fn expand_foo(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) diff --git a/src/test/compile-fail/gated-macro_registrar.rs b/src/test/compile-fail/gated-plugin_registrar.rs similarity index 84% rename from src/test/compile-fail/gated-macro_registrar.rs rename to src/test/compile-fail/gated-plugin_registrar.rs index 54274ccb847..f6e11ffd9e5 100644 --- a/src/test/compile-fail/gated-macro_registrar.rs +++ b/src/test/compile-fail/gated-plugin_registrar.rs @@ -9,7 +9,7 @@ // except according to those terms. // the registration function isn't typechecked yet -#[macro_registrar] -pub fn registrar() {} //~ ERROR cross-crate macro exports are experimental +#[plugin_registrar] +pub fn registrar() {} //~ ERROR compiler plugins are experimental fn main() {} diff --git a/src/test/compile-fail/multiple-macro-registrars.rs b/src/test/compile-fail/multiple-plugin-registrars.rs similarity index 81% rename from src/test/compile-fail/multiple-macro-registrars.rs rename to src/test/compile-fail/multiple-plugin-registrars.rs index 321c0ff0193..f5ebf84b8e0 100644 --- a/src/test/compile-fail/multiple-macro-registrars.rs +++ b/src/test/compile-fail/multiple-plugin-registrars.rs @@ -8,15 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// error-pattern: multiple macro registration functions found +// error-pattern: multiple plugin registration functions found -#![feature(macro_registrar)] +#![feature(plugin_registrar)] // the registration function isn't typechecked yet -#[macro_registrar] +#[plugin_registrar] pub fn one() {} -#[macro_registrar] +#[plugin_registrar] pub fn two() {} fn main() {} diff --git a/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs index 15f5e84b2a7..dd585ea9794 100644 --- a/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs +++ b/src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs @@ -8,12 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// aux-build:macro_crate_outlive_expansion_phase.rs +// aux-build:plugin_crate_outlive_expansion_phase.rs // ignore-stage1 #![feature(phase)] #[phase(plugin)] -extern crate macro_crate_outlive_expansion_phase; +extern crate plugin_crate_outlive_expansion_phase; pub fn main() {} From 7c674aceeb60da7e8aca60512c79329186127e5b Mon Sep 17 00:00:00 2001 From: Keegan McAllister <kmcallister@mozilla.com> Date: Sat, 24 May 2014 22:22:24 -0700 Subject: [PATCH 7/9] Add a test for deprecated phase(syntax) --- src/test/run-pass/deprecated-phase-syntax.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/run-pass/deprecated-phase-syntax.rs diff --git a/src/test/run-pass/deprecated-phase-syntax.rs b/src/test/run-pass/deprecated-phase-syntax.rs new file mode 100644 index 00000000000..df835dab4d4 --- /dev/null +++ b/src/test/run-pass/deprecated-phase-syntax.rs @@ -0,0 +1,19 @@ +// Copyright 2013-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. + +#![feature(phase)] + +//~ WARNING phase(syntax) is a deprecated synonym for phase(plugin) +#[phase(syntax, link)] +extern crate log; + +fn main() { + debug!("foo"); +} From d43a948bb1f1bc92ee8771bc425d77eb886e7d52 Mon Sep 17 00:00:00 2001 From: Keegan McAllister <kmcallister@mozilla.com> Date: Mon, 26 May 2014 14:48:54 -0700 Subject: [PATCH 8/9] Document rustc::plugin --- src/librustc/lib.rs | 8 +---- src/librustc/plugin/build.rs | 3 +- src/librustc/plugin/load.rs | 16 ++++++++- src/librustc/plugin/mod.rs | 64 +++++++++++++++++++++++++++++++++ src/librustc/plugin/registry.rs | 21 +++++++++-- 5 files changed, 100 insertions(+), 12 deletions(-) create mode 100644 src/librustc/plugin/mod.rs diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index bdbb1a98ac5..4ac4e3a5a9f 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -114,13 +114,7 @@ pub mod metadata; pub mod driver; -pub mod plugin { - pub use self::registry::Registry; - - pub mod registry; - pub mod load; - pub mod build; -} +pub mod plugin; pub mod util { pub mod common; diff --git a/src/librustc/plugin/build.rs b/src/librustc/plugin/build.rs index a27632882fc..ad35c4efe11 100644 --- a/src/librustc/plugin/build.rs +++ b/src/librustc/plugin/build.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Used by `rustc` when compiling a plugin crate. + use syntax::ast; use syntax::attr; use syntax::codemap::Span; @@ -36,7 +38,6 @@ impl Visitor<()> for RegistrarFinder { } /// Find the function marked with `#[plugin_registrar]`, if any. -/// Used while compiling a crate which defines a registrar. pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler, krate: &ast::Crate) -> Option<ast::NodeId> { let mut finder = RegistrarFinder { registrars: Vec::new() }; diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index c80f8f96c4b..ba50a15a82b 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -8,9 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use plugin::registry::PluginRegistrarFun; +//! Used by `rustc` when loading a plugin. + use driver::session::Session; use metadata::creader::PluginMetadataReader; +use plugin::registry::Registry; use std::mem; use std::os; @@ -22,14 +24,25 @@ use syntax::visit::Visitor; use syntax::ext::expand::ExportedMacros; use syntax::attr::AttrMetaMethods; +/// Plugin-related crate metadata. pub struct PluginMetadata { + /// Source code of macros exported by the crate. pub macros: Vec<String>, + /// Path to the shared library file. pub lib: Option<Path>, + /// Symbol name of the plugin registrar function. pub registrar_symbol: Option<String>, } +/// Pointer to a registrar function. +pub type PluginRegistrarFun = + fn(&mut Registry); + +/// Information about loaded plugins. pub struct Plugins { + /// Source code of exported macros. pub macros: Vec<ExportedMacros>, + /// Registrars, as function pointers. pub registrars: Vec<PluginRegistrarFun>, } @@ -52,6 +65,7 @@ impl<'a> PluginLoader<'a> { } } +/// Read plugin metadata and dynamically load registrar functions. pub fn load_plugins(sess: &Session, krate: &ast::Crate) -> Plugins { let mut loader = PluginLoader::new(sess); visit::walk_crate(&mut loader, krate, ()); diff --git a/src/librustc/plugin/mod.rs b/src/librustc/plugin/mod.rs new file mode 100644 index 00000000000..fa70ffc7392 --- /dev/null +++ b/src/librustc/plugin/mod.rs @@ -0,0 +1,64 @@ +// Copyright 2012-2013 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. + +/*! + * Infrastructure for compiler plugins. + * + * Plugins are Rust libraries which extend the behavior of `rustc` + * in various ways. + * + * Plugin authors will use the `Registry` type re-exported by + * this module, along with its methods. The rest of the module + * is for use by `rustc` itself. + * + * To define a plugin, build a dylib crate with a + * `#[plugin_registrar]` function: + * + * ```rust,ignore + * #![crate_id = "myplugin"] + * #![crate_type = "dylib"] + * #![feature(plugin_registrar)] + * + * extern crate rustc; + * + * use rustc::plugin::Registry; + * + * #[plugin_registrar] + * pub fn plugin_registrar(reg: &mut Registry) { + * reg.register_macro("mymacro", expand_mymacro); + * } + * + * fn expand_mymacro(...) { // details elided + * ``` + * + * WARNING: We currently don't check that the registrar function + * has the appropriate type! + * + * To use a plugin while compiling another crate: + * + * ```rust + * #![feature(phase)] + * + * #[phase(plugin)] + * extern crate myplugin; + * ``` + * + * If you also need the plugin crate available at runtime, use + * `phase(plugin, link)`. + * + * See `src/test/auxiliary/macro_crate_test.rs` and `src/libfourcc` + * for examples of syntax extension plugins. + */ + +pub use self::registry::Registry; + +pub mod registry; +pub mod load; +pub mod build; diff --git a/src/librustc/plugin/registry.rs b/src/librustc/plugin/registry.rs index 6402b116536..f6e37822325 100644 --- a/src/librustc/plugin/registry.rs +++ b/src/librustc/plugin/registry.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +//! Used by plugin crates to tell `rustc` about the plugins they provide. + use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT}; use syntax::ext::base::{IdentTT, ItemDecorator, ItemModifier, BasicMacroExpander}; use syntax::ext::base::{MacroExpanderFn}; @@ -15,6 +17,14 @@ use syntax::codemap::Span; use syntax::parse::token; use syntax::ast; +/// Structure used to register plugins. +/// +/// A plugin registrar function takes an `&mut Registry` and should call +/// methods to register its plugins. +/// +/// This struct has public fields and other methods for use by `rustc` +/// itself. They are not documented here, and plugin authors should +/// not use them. pub struct Registry { #[doc(hidden)] pub krate_span: Span, @@ -23,9 +33,6 @@ pub struct Registry { pub syntax_exts: Vec<NamedSyntaxExtension>, } -pub type PluginRegistrarFun = - fn(&mut Registry); - impl Registry { #[doc(hidden)] pub fn new(krate: &ast::Crate) -> Registry { @@ -35,6 +42,9 @@ impl Registry { } } + /// Register a syntax extension of any kind. + /// + /// This is the most general hook into `libsyntax`'s expansion behavior. pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { self.syntax_exts.push((name, match extension { NormalTT(ext, _) => NormalTT(ext, Some(self.krate_span)), @@ -44,6 +54,11 @@ impl Registry { })); } + /// Register a macro of the usual kind. + /// + /// This is a convenience wrapper for `register_syntax_extension`. + /// It builds for you a `NormalTT` with a `BasicMacroExpander`, + /// and also takes care of interning the macro's name. pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) { self.register_syntax_extension( token::intern(name), From deecda6a94b31489045d420f16840a72c44af7e1 Mon Sep 17 00:00:00 2001 From: Keegan McAllister <kmcallister@mozilla.com> Date: Fri, 30 May 2014 17:55:42 -0700 Subject: [PATCH 9/9] Macro crates now depend on librustc --- mk/crates.mk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mk/crates.mk b/mk/crates.mk index 433490f6f5d..cc6532945ef 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -83,8 +83,8 @@ DEPS_uuid := std serialize DEPS_sync := std alloc DEPS_getopts := std DEPS_collections := core alloc -DEPS_fourcc := syntax std -DEPS_hexfloat := syntax std +DEPS_fourcc := rustc syntax std +DEPS_hexfloat := rustc syntax std DEPS_num := std DEPS_test := std getopts serialize term time regex native:rust_test_helpers DEPS_time := std serialize sync @@ -92,7 +92,7 @@ DEPS_rand := core DEPS_url := std DEPS_log := std sync DEPS_regex := std -DEPS_regex_macros = syntax std regex +DEPS_regex_macros = rustc syntax std regex DEPS_fmt_macros = std TOOL_DEPS_compiletest := test green rustuv getopts