about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2019-01-17 07:28:39 +0100
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2019-01-28 05:46:53 +0100
commit1bdd2f699beb6249a97aac3e2007401b37b6f273 (patch)
tree588467272c41fde89c39948b50cf1c78bf99c9ef /src
parentec504def3665b0bc2ec80bede6dba2c603928315 (diff)
downloadrust-1bdd2f699beb6249a97aac3e2007401b37b6f273.tar.gz
rust-1bdd2f699beb6249a97aac3e2007401b37b6f273.zip
Conditionally skip two passes if their related attributes were not found
Diffstat (limited to 'src')
-rw-r--r--src/librustc_driver/driver.rs31
-rw-r--r--src/librustc_passes/Cargo.toml1
-rw-r--r--src/librustc_passes/ast_validation.rs22
-rw-r--r--src/librustc_passes/lib.rs1
-rw-r--r--src/libsyntax_ext/proc_macro_decls.rs7
5 files changed, 43 insertions, 19 deletions
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 88dac42997f..f5e5f1f5c0b 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -1017,6 +1017,10 @@ where
         krate = ReplaceBodyWithLoop::new(sess).fold_crate(krate);
     }
 
+    let (has_proc_macro_decls, has_global_allocator) = time(sess, "AST validation", || {
+        ast_validation::check_crate(sess, &krate)
+    });
+
     // If we're in rustdoc we're always compiling as an rlib, but that'll trip a
     // bunch of checks in the `modify` function below. For now just skip this
     // step entirely if we're rustdoc as it's not too useful anyway.
@@ -1031,6 +1035,7 @@ where
                 &mut resolver,
                 krate,
                 is_proc_macro_crate,
+                has_proc_macro_decls,
                 is_test_crate,
                 num_crate_types,
                 sess.diagnostic(),
@@ -1038,16 +1043,18 @@ where
         });
     }
 
-    // Expand global allocators, which are treated as an in-tree proc macro
-    krate = time(sess, "creating allocators", || {
-        allocator::expand::modify(
-            &sess.parse_sess,
-            &mut resolver,
-            krate,
-            crate_name.to_string(),
-            sess.diagnostic(),
-        )
-    });
+    if has_global_allocator {
+        // Expand global allocators, which are treated as an in-tree proc macro
+        krate = time(sess, "creating allocators", || {
+            allocator::expand::modify(
+                &sess.parse_sess,
+                &mut resolver,
+                krate,
+                crate_name.to_string(),
+                sess.diagnostic(),
+            )
+        });
+    }
 
     // Done with macro expansion!
 
@@ -1065,10 +1072,6 @@ where
         println!("{}", json::as_json(&krate));
     }
 
-    time(sess, "AST validation", || {
-        ast_validation::check_crate(sess, &krate)
-    });
-
     time(sess, "name resolution", || {
         resolver.resolve_crate(&krate);
     });
diff --git a/src/librustc_passes/Cargo.toml b/src/librustc_passes/Cargo.toml
index 2babb93eedb..f5154a033af 100644
--- a/src/librustc_passes/Cargo.toml
+++ b/src/librustc_passes/Cargo.toml
@@ -14,5 +14,6 @@ rustc = { path = "../librustc" }
 rustc_mir = { path = "../librustc_mir"}
 rustc_data_structures = { path = "../librustc_data_structures" }
 syntax = { path = "../libsyntax" }
+syntax_ext = { path = "../libsyntax_ext" }
 syntax_pos = { path = "../libsyntax_pos" }
 rustc_errors = { path = "../librustc_errors" }
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 3b6328f320f..3deb2ff8d8a 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -15,12 +15,15 @@ use syntax::source_map::Spanned;
 use syntax::symbol::keywords;
 use syntax::ptr::P;
 use syntax::visit::{self, Visitor};
+use syntax_ext::proc_macro_decls::is_proc_macro_attr;
 use syntax_pos::Span;
 use errors;
 use errors::Applicability;
 
 struct AstValidator<'a> {
     session: &'a Session,
+    has_proc_macro_decls: bool,
+    has_global_allocator: bool,
 
     // Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
     // Nested `impl Trait` _is_ allowed in associated type position,
@@ -367,6 +370,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     }
 
     fn visit_item(&mut self, item: &'a Item) {
+        if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)  ) {
+            self.has_proc_macro_decls = true;
+        }
+
+        if attr::contains_name(&item.attrs, "global_allocator") {
+            self.has_global_allocator = true;
+        }
+
         match item.node {
             ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => {
                 self.invalid_visibility(&item.vis, None);
@@ -590,10 +601,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
     }
 }
 
-pub fn check_crate(session: &Session, krate: &Crate) {
-    visit::walk_crate(&mut AstValidator {
+pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) {
+    let mut validator = AstValidator {
         session,
+        has_proc_macro_decls: false,
+        has_global_allocator: false,
         outer_impl_trait: None,
         is_impl_trait_banned: false,
-    }, krate)
+    };
+    visit::walk_crate(&mut validator, krate);
+
+    (validator.has_proc_macro_decls, validator.has_global_allocator)
 }
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index a181bc7e9b4..76605c58a78 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -22,6 +22,7 @@ extern crate rustc_data_structures;
 extern crate log;
 #[macro_use]
 extern crate syntax;
+extern crate syntax_ext;
 extern crate syntax_pos;
 extern crate rustc_errors as errors;
 
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index 1d272712cac..46c502965ee 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -48,6 +48,7 @@ pub fn modify(sess: &ParseSess,
               resolver: &mut dyn (::syntax::ext::base::Resolver),
               mut krate: ast::Crate,
               is_proc_macro_crate: bool,
+              has_proc_macro_decls: bool,
               is_test_crate: bool,
               num_crate_types: usize,
               handler: &errors::Handler) -> ast::Crate {
@@ -64,7 +65,9 @@ pub fn modify(sess: &ParseSess,
             is_proc_macro_crate,
             is_test_crate,
         };
-        visit::walk_crate(&mut collect, &krate);
+        if has_proc_macro_decls || is_proc_macro_crate {
+            visit::walk_crate(&mut collect, &krate);
+        }
         (collect.derives, collect.attr_macros, collect.bang_macros)
     };
 
@@ -85,7 +88,7 @@ pub fn modify(sess: &ParseSess,
     krate
 }
 
-fn is_proc_macro_attr(attr: &ast::Attribute) -> bool {
+pub fn is_proc_macro_attr(attr: &ast::Attribute) -> bool {
     PROC_MACRO_KINDS.iter().any(|kind| attr.check_name(kind))
 }