Conditionally skip two passes if their related attributes were not found
This commit is contained in:
parent
ec504def36
commit
1bdd2f699b
6 changed files with 44 additions and 19 deletions
|
@ -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",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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" }
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue