Conditionally skip two passes if their related attributes were not found

This commit is contained in:
John Kåre Alsaker 2019-01-17 07:28:39 +01:00
parent ec504def36
commit 1bdd2f699b
6 changed files with 44 additions and 19 deletions

View file

@ -2722,6 +2722,7 @@ dependencies = [
"rustc_errors 0.0.0", "rustc_errors 0.0.0",
"rustc_mir 0.0.0", "rustc_mir 0.0.0",
"syntax 0.0.0", "syntax 0.0.0",
"syntax_ext 0.0.0",
"syntax_pos 0.0.0", "syntax_pos 0.0.0",
] ]

View file

@ -1017,6 +1017,10 @@ where
krate = ReplaceBodyWithLoop::new(sess).fold_crate(krate); 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 // 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 // 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. // step entirely if we're rustdoc as it's not too useful anyway.
@ -1031,6 +1035,7 @@ where
&mut resolver, &mut resolver,
krate, krate,
is_proc_macro_crate, is_proc_macro_crate,
has_proc_macro_decls,
is_test_crate, is_test_crate,
num_crate_types, num_crate_types,
sess.diagnostic(), sess.diagnostic(),
@ -1038,16 +1043,18 @@ where
}); });
} }
// Expand global allocators, which are treated as an in-tree proc macro if has_global_allocator {
krate = time(sess, "creating allocators", || { // Expand global allocators, which are treated as an in-tree proc macro
allocator::expand::modify( krate = time(sess, "creating allocators", || {
&sess.parse_sess, allocator::expand::modify(
&mut resolver, &sess.parse_sess,
krate, &mut resolver,
crate_name.to_string(), krate,
sess.diagnostic(), crate_name.to_string(),
) sess.diagnostic(),
}); )
});
}
// Done with macro expansion! // Done with macro expansion!
@ -1065,10 +1072,6 @@ where
println!("{}", json::as_json(&krate)); println!("{}", json::as_json(&krate));
} }
time(sess, "AST validation", || {
ast_validation::check_crate(sess, &krate)
});
time(sess, "name resolution", || { time(sess, "name resolution", || {
resolver.resolve_crate(&krate); resolver.resolve_crate(&krate);
}); });

View file

@ -14,5 +14,6 @@ rustc = { path = "../librustc" }
rustc_mir = { path = "../librustc_mir"} rustc_mir = { path = "../librustc_mir"}
rustc_data_structures = { path = "../librustc_data_structures" } rustc_data_structures = { path = "../librustc_data_structures" }
syntax = { path = "../libsyntax" } syntax = { path = "../libsyntax" }
syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" } syntax_pos = { path = "../libsyntax_pos" }
rustc_errors = { path = "../librustc_errors" } rustc_errors = { path = "../librustc_errors" }

View file

@ -15,12 +15,15 @@ use syntax::source_map::Spanned;
use syntax::symbol::keywords; use syntax::symbol::keywords;
use syntax::ptr::P; use syntax::ptr::P;
use syntax::visit::{self, Visitor}; use syntax::visit::{self, Visitor};
use syntax_ext::proc_macro_decls::is_proc_macro_attr;
use syntax_pos::Span; use syntax_pos::Span;
use errors; use errors;
use errors::Applicability; use errors::Applicability;
struct AstValidator<'a> { struct AstValidator<'a> {
session: &'a Session, session: &'a Session,
has_proc_macro_decls: bool,
has_global_allocator: bool,
// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`. // Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
// Nested `impl Trait` _is_ allowed in associated type position, // 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) { 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 { match item.node {
ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => {
self.invalid_visibility(&item.vis, None); 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) { pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) {
visit::walk_crate(&mut AstValidator { let mut validator = AstValidator {
session, session,
has_proc_macro_decls: false,
has_global_allocator: false,
outer_impl_trait: None, outer_impl_trait: None,
is_impl_trait_banned: false, is_impl_trait_banned: false,
}, krate) };
visit::walk_crate(&mut validator, krate);
(validator.has_proc_macro_decls, validator.has_global_allocator)
} }

View file

@ -22,6 +22,7 @@ extern crate rustc_data_structures;
extern crate log; extern crate log;
#[macro_use] #[macro_use]
extern crate syntax; extern crate syntax;
extern crate syntax_ext;
extern crate syntax_pos; extern crate syntax_pos;
extern crate rustc_errors as errors; extern crate rustc_errors as errors;

View file

@ -48,6 +48,7 @@ pub fn modify(sess: &ParseSess,
resolver: &mut dyn (::syntax::ext::base::Resolver), resolver: &mut dyn (::syntax::ext::base::Resolver),
mut krate: ast::Crate, mut krate: ast::Crate,
is_proc_macro_crate: bool, is_proc_macro_crate: bool,
has_proc_macro_decls: bool,
is_test_crate: bool, is_test_crate: bool,
num_crate_types: usize, num_crate_types: usize,
handler: &errors::Handler) -> ast::Crate { handler: &errors::Handler) -> ast::Crate {
@ -64,7 +65,9 @@ pub fn modify(sess: &ParseSess,
is_proc_macro_crate, is_proc_macro_crate,
is_test_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) (collect.derives, collect.attr_macros, collect.bang_macros)
}; };
@ -85,7 +88,7 @@ pub fn modify(sess: &ParseSess,
krate 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)) PROC_MACRO_KINDS.iter().any(|kind| attr.check_name(kind))
} }