about summary refs log tree commit diff
path: root/src/librustc_metadata
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-10-17 07:46:25 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-10-24 00:43:12 +0000
commite4baeaa30da3736d9a85f24509319d7148c2feea (patch)
tree1b17a11b3a47a93413e1578d76512e4fd73718df /src/librustc_metadata
parent4845adde360c306624faa3305ea95f95cd11e2b4 (diff)
downloadrust-e4baeaa30da3736d9a85f24509319d7148c2feea.tar.gz
rust-e4baeaa30da3736d9a85f24509319d7148c2feea.zip
Import macros in `resolve` instead of in `metadata::macro_import`.
Diffstat (limited to 'src/librustc_metadata')
-rw-r--r--src/librustc_metadata/creader.rs77
-rw-r--r--src/librustc_metadata/diagnostics.rs179
-rw-r--r--src/librustc_metadata/lib.rs1
-rw-r--r--src/librustc_metadata/macro_import.rs235
4 files changed, 69 insertions, 423 deletions
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 7ae3f6f8107..ad2a7afbc8b 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -12,12 +12,11 @@
 
 use cstore::{self, CStore, CrateSource, MetadataBlob};
 use locator::{self, CratePaths};
-use macro_import;
 use schema::CrateRoot;
 
 use rustc::hir::def_id::{CrateNum, DefIndex};
 use rustc::hir::svh::Svh;
-use rustc::middle::cstore::LoadedMacro;
+use rustc::middle::cstore::LoadedMacros;
 use rustc::session::{config, Session};
 use rustc_back::PanicStrategy;
 use rustc::session::search_paths::PathKind;
@@ -36,7 +35,8 @@ use syntax::ast;
 use syntax::abi::Abi;
 use syntax::parse;
 use syntax::attr;
-use syntax::parse::token::InternedString;
+use syntax::ext::base::SyntaxExtension;
+use syntax::parse::token::{InternedString, intern};
 use syntax_pos::{self, Span, mk_sp};
 use log;
 
@@ -591,15 +591,14 @@ impl<'a> CrateLoader<'a> {
 
             ret.macro_rules.push(ast::MacroDef {
                 ident: ast::Ident::with_empty_ctxt(def.name),
-                attrs: def.attrs,
                 id: ast::DUMMY_NODE_ID,
                 span: local_span,
                 imported_from: Some(item.ident),
                 // overridden in plugin/load.rs
                 export: false,
                 use_locally: false,
-                allow_internal_unstable: false,
-
+                allow_internal_unstable: attr::contains_name(&def.attrs, "allow_internal_unstable"),
+                attrs: def.attrs,
                 body: body,
             });
             self.sess.imported_macro_spans.borrow_mut()
@@ -639,6 +638,58 @@ impl<'a> CrateLoader<'a> {
         return ret
     }
 
+    /// Load custom derive macros.
+    ///
+    /// Note that this is intentionally similar to how we load plugins today,
+    /// but also intentionally separate. Plugins are likely always going to be
+    /// implemented as dynamic libraries, but we have a possible future where
+    /// custom derive (and other macro-1.1 style features) are implemented via
+    /// executables and custom IPC.
+    fn load_derive_macros(&mut self, span: Span, macros: &Macros, index: DefIndex)
+                          -> Vec<(ast::Name, SyntaxExtension)> {
+        use std::{env, mem};
+        use proc_macro::TokenStream;
+        use proc_macro::__internal::Registry;
+        use rustc_back::dynamic_lib::DynamicLibrary;
+        use syntax_ext::deriving::custom::CustomDerive;
+
+        // Make sure the path contains a / or the linker will search for it.
+        let path = macros.dylib.as_ref().unwrap();
+        let path = env::current_dir().unwrap().join(path);
+        let lib = match DynamicLibrary::open(Some(&path)) {
+            Ok(lib) => lib,
+            Err(err) => self.sess.span_fatal(span, &err),
+        };
+
+        let sym = self.sess.generate_derive_registrar_symbol(&macros.svh, index);
+        let registrar = unsafe {
+            let sym = match lib.symbol(&sym) {
+                Ok(f) => f,
+                Err(err) => self.sess.span_fatal(span, &err),
+            };
+            mem::transmute::<*mut u8, fn(&mut Registry)>(sym)
+        };
+
+        struct MyRegistrar(Vec<(ast::Name, SyntaxExtension)>);
+
+        impl Registry for MyRegistrar {
+            fn register_custom_derive(&mut self,
+                                      trait_name: &str,
+                                      expand: fn(TokenStream) -> TokenStream) {
+                let derive = SyntaxExtension::CustomDerive(Box::new(CustomDerive::new(expand)));
+                self.0.push((intern(trait_name), derive));
+            }
+        }
+
+        let mut my_registrar = MyRegistrar(Vec::new());
+        registrar(&mut my_registrar);
+
+        // Intentionally leak the dynamic library. We can't ever unload it
+        // since the library can make things that will live arbitrarily long.
+        mem::forget(lib);
+        my_registrar.0
+    }
+
     /// Look for a plugin registrar. Returns library path, crate
     /// SVH and DefIndex of the registrar function.
     pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
@@ -1030,7 +1081,17 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> {
         }
     }
 
-    fn load_macros(&mut self, extern_crate: &ast::Item, allows_macros: bool) -> Vec<LoadedMacro> {
-        macro_import::load_macros(self, extern_crate, allows_macros)
+    fn load_macros(&mut self, extern_crate: &ast::Item) -> LoadedMacros {
+        let macros = self.read_macros(extern_crate);
+
+        if let Some(index) = macros.custom_derive_registrar {
+            // custom derive crates currently should not have any macro_rules!
+            // exported macros, enforced elsewhere
+            assert_eq!(macros.macro_rules.len(), 0);
+            let custom_derives = self.load_derive_macros(extern_crate.span, &macros, index);
+            LoadedMacros::ProcMacros(custom_derives)
+        } else {
+            LoadedMacros::MacroRules(macros.macro_rules)
+        }
     }
 }
diff --git a/src/librustc_metadata/diagnostics.rs b/src/librustc_metadata/diagnostics.rs
index c03375bf825..b2f4760727a 100644
--- a/src/librustc_metadata/diagnostics.rs
+++ b/src/librustc_metadata/diagnostics.rs
@@ -91,185 +91,6 @@ You need to link your code to the relevant crate in order to be able to use it
 well, and you link to them the same way.
 "##,
 
-E0466: r##"
-Macro import declarations were malformed.
-
-Erroneous code examples:
-
-```compile_fail,E0466
-#[macro_use(a_macro(another_macro))] // error: invalid import declaration
-extern crate core as some_crate;
-
-#[macro_use(i_want = "some_macros")] // error: invalid import declaration
-extern crate core as another_crate;
-```
-
-This is a syntax error at the level of attribute declarations. The proper
-syntax for macro imports is the following:
-
-```ignore
-// In some_crate:
-#[macro_export]
-macro_rules! get_tacos {
-    ...
-}
-
-#[macro_export]
-macro_rules! get_pimientos {
-    ...
-}
-
-// In your crate:
-#[macro_use(get_tacos, get_pimientos)] // It imports `get_tacos` and
-extern crate some_crate;               // `get_pimientos` macros from some_crate
-```
-
-If you would like to import all exported macros, write `macro_use` with no
-arguments.
-"##,
-
-E0467: r##"
-Macro reexport declarations were empty or malformed.
-
-Erroneous code examples:
-
-```compile_fail,E0467
-#[macro_reexport]                    // error: no macros listed for export
-extern crate core as macros_for_good;
-
-#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
-extern crate core as other_macros_for_good;
-```
-
-This is a syntax error at the level of attribute declarations.
-
-Currently, `macro_reexport` requires at least one macro name to be listed.
-Unlike `macro_use`, listing no names does not reexport all macros from the
-given crate.
-
-Decide which macros you would like to export and list them properly.
-
-These are proper reexport declarations:
-
-```ignore
-#[macro_reexport(some_macro, another_macro)]
-extern crate macros_for_good;
-```
-"##,
-
-E0468: r##"
-A non-root module attempts to import macros from another crate.
-
-Example of erroneous code:
-
-```compile_fail,E0468
-mod foo {
-    #[macro_use(helpful_macro)] // error: must be at crate root to import
-    extern crate core;          //        macros from another crate
-    helpful_macro!(...);
-}
-```
-
-Only `extern crate` imports at the crate root level are allowed to import
-macros.
-
-Either move the macro import to crate root or do without the foreign macros.
-This will work:
-
-```ignore
-#[macro_use(helpful_macro)]
-extern crate some_crate;
-
-mod foo {
-    helpful_macro!(...)
-}
-```
-"##,
-
-E0469: r##"
-A macro listed for import was not found.
-
-Erroneous code example:
-
-```compile_fail,E0469
-#[macro_use(drink, be_merry)] // error: imported macro not found
-extern crate collections;
-
-fn main() {
-    // ...
-}
-```
-
-Either the listed macro is not contained in the imported crate, or it is not
-exported from the given crate.
-
-This could be caused by a typo. Did you misspell the macro's name?
-
-Double-check the names of the macros listed for import, and that the crate
-in question exports them.
-
-A working version would be:
-
-```ignore
-// In some_crate crate:
-#[macro_export]
-macro_rules! eat {
-    ...
-}
-
-#[macro_export]
-macro_rules! drink {
-    ...
-}
-
-// In your crate:
-#[macro_use(eat, drink)]
-extern crate some_crate; //ok!
-```
-"##,
-
-E0470: r##"
-A macro listed for reexport was not found.
-
-Erroneous code example:
-
-```compile_fail,E0470
-#[macro_reexport(drink, be_merry)]
-extern crate collections;
-
-fn main() {
-    // ...
-}
-```
-
-Either the listed macro is not contained in the imported crate, or it is not
-exported from the given crate.
-
-This could be caused by a typo. Did you misspell the macro's name?
-
-Double-check the names of the macros listed for reexport, and that the crate
-in question exports them.
-
-A working version:
-
-```ignore
-// In some_crate crate:
-#[macro_export]
-macro_rules! eat {
-    ...
-}
-
-#[macro_export]
-macro_rules! drink {
-    ...
-}
-
-// In your_crate:
-#[macro_reexport(eat, drink)]
-extern crate some_crate;
-```
-"##,
-
 }
 
 register_diagnostics! {
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index c0fc1a7065c..300c5f0dec7 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -59,6 +59,5 @@ mod schema;
 pub mod creader;
 pub mod cstore;
 pub mod locator;
-pub mod macro_import;
 
 __build_diagnostic_array! { librustc_metadata, DIAGNOSTICS }
diff --git a/src/librustc_metadata/macro_import.rs b/src/librustc_metadata/macro_import.rs
deleted file mode 100644
index ddc254a16d9..00000000000
--- a/src/librustc_metadata/macro_import.rs
+++ /dev/null
@@ -1,235 +0,0 @@
-// Copyright 2012-2015 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.
-
-//! Used by `rustc` when loading a crate with exported macros.
-
-use std::collections::HashSet;
-use std::env;
-use std::mem;
-
-use creader::{CrateLoader, Macros};
-
-use proc_macro::TokenStream;
-use proc_macro::__internal::Registry;
-use rustc::hir::def_id::DefIndex;
-use rustc::middle::cstore::{LoadedMacro, LoadedMacroKind};
-use rustc::session::Session;
-use rustc::util::nodemap::FnvHashMap;
-use rustc_back::dynamic_lib::DynamicLibrary;
-use syntax::ast;
-use syntax::attr;
-use syntax::parse::token;
-use syntax_ext::deriving::custom::CustomDerive;
-use syntax_pos::{Span, DUMMY_SP};
-
-pub fn call_bad_macro_reexport(a: &Session, b: Span) {
-    span_err!(a, b, E0467, "bad macro reexport");
-}
-
-pub type MacroSelection = FnvHashMap<token::InternedString, Span>;
-
-enum ImportSelection {
-    All(Span),
-    Some(MacroSelection),
-}
-
-pub fn load_macros(loader: &mut CrateLoader, extern_crate: &ast::Item, allows_macros: bool)
-                   -> Vec<LoadedMacro> {
-    loader.load_crate(extern_crate, allows_macros)
-}
-
-impl<'a> CrateLoader<'a> {
-    fn load_crate(&mut self,
-                  extern_crate: &ast::Item,
-                  allows_macros: bool) -> Vec<LoadedMacro> {
-        // Parse the attributes relating to macros.
-        let mut import = ImportSelection::Some(FnvHashMap());
-        let mut reexport = FnvHashMap();
-        let mut no_link = false;
-
-        for attr in &extern_crate.attrs {
-            let mut used = true;
-            match &attr.name()[..] {
-                "macro_use" => {
-                    let names = attr.meta_item_list();
-                    if names.is_none() {
-                        import = ImportSelection::All(attr.span);
-                    } else if let ImportSelection::Some(ref mut sel) = import {
-                        for attr in names.unwrap() {
-                            if let Some(word) = attr.word() {
-                                sel.insert(word.name().clone(), attr.span());
-                            } else {
-                                span_err!(self.sess, attr.span(), E0466, "bad macro import");
-                            }
-                        }
-                    }
-                }
-                "macro_reexport" => {
-                    let names = match attr.meta_item_list() {
-                        Some(names) => names,
-                        None => {
-                            call_bad_macro_reexport(self.sess, attr.span);
-                            continue;
-                        }
-                    };
-
-                    for attr in names {
-                        if let Some(word) = attr.word() {
-                            reexport.insert(word.name().clone(), attr.span());
-                        } else {
-                            call_bad_macro_reexport(self.sess, attr.span());
-                        }
-                    }
-                }
-                "no_link" => no_link = true,
-                _ => used = false,
-            }
-            if used {
-                attr::mark_used(attr);
-            }
-        }
-
-        self.load_macros(extern_crate, allows_macros, import, reexport, no_link)
-    }
-
-    fn load_macros<'b>(&mut self,
-                       vi: &ast::Item,
-                       allows_macros: bool,
-                       import: ImportSelection,
-                       reexport: MacroSelection,
-                       no_link: bool)
-                       -> Vec<LoadedMacro> {
-        if let ImportSelection::Some(ref sel) = import {
-            if sel.is_empty() && reexport.is_empty() {
-                // Make sure we can read macros from `#[no_link]` crates.
-                if no_link {
-                    self.read_macros(vi);
-                }
-                return Vec::new();
-            }
-        }
-
-        if !allows_macros {
-            span_err!(self.sess, vi.span, E0468,
-                      "an `extern crate` loading macros must be at the crate root");
-            return Vec::new();
-        }
-
-        let mut macros = self.read_macros(vi);
-        let mut ret = Vec::new();
-        let mut seen = HashSet::new();
-
-        for mut def in macros.macro_rules.drain(..) {
-            let name = def.ident.name.as_str();
-
-            let import_site = match import {
-                ImportSelection::All(span) => Some(span),
-                ImportSelection::Some(ref sel) => sel.get(&name).cloned()
-            };
-            def.use_locally = import_site.is_some();
-            def.export = reexport.contains_key(&name);
-            def.allow_internal_unstable = attr::contains_name(&def.attrs,
-                                                              "allow_internal_unstable");
-            debug!("load_macros: loaded: {:?}", def);
-            ret.push(LoadedMacro {
-                kind: LoadedMacroKind::Def(def),
-                import_site: import_site.unwrap_or(DUMMY_SP),
-            });
-            seen.insert(name);
-        }
-
-        if let Some(index) = macros.custom_derive_registrar {
-            // custom derive crates currently should not have any macro_rules!
-            // exported macros, enforced elsewhere
-            assert_eq!(ret.len(), 0);
-
-            if let ImportSelection::Some(..) = import {
-                self.sess.span_err(vi.span, "`proc-macro` crates cannot be \
-                                             selectively imported from, must \
-                                             use `#[macro_use]`");
-            }
-
-            if reexport.len() > 0 {
-                self.sess.span_err(vi.span, "`proc-macro` crates cannot be \
-                                             reexported from");
-            }
-
-            self.load_derive_macros(vi.span, &macros, index, &mut ret);
-        }
-
-        if let ImportSelection::Some(sel) = import {
-            for (name, span) in sel {
-                if !seen.contains(&name) {
-                    span_err!(self.sess, span, E0469,
-                              "imported macro not found");
-                }
-            }
-        }
-
-        for (name, span) in &reexport {
-            if !seen.contains(&name) {
-                span_err!(self.sess, *span, E0470,
-                          "reexported macro not found");
-            }
-        }
-
-        return ret
-    }
-
-    /// Load the custom derive macros into the list of macros we're loading.
-    ///
-    /// Note that this is intentionally similar to how we load plugins today,
-    /// but also intentionally separate. Plugins are likely always going to be
-    /// implemented as dynamic libraries, but we have a possible future where
-    /// custom derive (and other macro-1.1 style features) are implemented via
-    /// executables and custom IPC.
-    fn load_derive_macros(&mut self,
-                          span: Span,
-                          macros: &Macros,
-                          index: DefIndex,
-                          ret: &mut Vec<LoadedMacro>) {
-        // Make sure the path contains a / or the linker will search for it.
-        let path = macros.dylib.as_ref().unwrap();
-        let path = env::current_dir().unwrap().join(path);
-        let lib = match DynamicLibrary::open(Some(&path)) {
-            Ok(lib) => lib,
-            Err(err) => self.sess.span_fatal(span, &err),
-        };
-
-        let sym = self.sess.generate_derive_registrar_symbol(&macros.svh, index);
-        let registrar = unsafe {
-            let sym = match lib.symbol(&sym) {
-                Ok(f) => f,
-                Err(err) => self.sess.span_fatal(span, &err),
-            };
-            mem::transmute::<*mut u8, fn(&mut Registry)>(sym)
-        };
-
-        struct MyRegistrar<'a>(&'a mut Vec<LoadedMacro>, Span);
-
-        impl<'a> Registry for MyRegistrar<'a> {
-            fn register_custom_derive(&mut self,
-                                      trait_name: &str,
-                                      expand: fn(TokenStream) -> TokenStream) {
-                let derive = Box::new(CustomDerive::new(expand));
-                self.0.push(LoadedMacro {
-                    kind: LoadedMacroKind::CustomDerive(trait_name.to_string(), derive),
-                    import_site: self.1,
-                });
-            }
-        }
-
-        registrar(&mut MyRegistrar(ret, span));
-
-        // Intentionally leak the dynamic library. We can't ever unload it
-        // since the library can make things that will live arbitrarily long.
-        mem::forget(lib);
-    }
-}