expand: Pass ast::Crate
by reference to AST transforming passes
Also some more attributes are passed by reference.
This commit is contained in:
parent
84dd6dfd9d
commit
6cc33b7691
@ -6,7 +6,7 @@ use rustc_ast::{self as ast, AttrItem, AttrStyle};
|
||||
use rustc_session::parse::ParseSess;
|
||||
use rustc_span::FileName;
|
||||
|
||||
pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
|
||||
pub fn inject(krate: &mut ast::Crate, parse_sess: &ParseSess, attrs: &[String]) {
|
||||
for raw_attr in attrs {
|
||||
let mut parser = rustc_parse::new_parser_from_source_str(
|
||||
parse_sess,
|
||||
@ -36,6 +36,4 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
|
||||
start_span.to(end_span),
|
||||
));
|
||||
}
|
||||
|
||||
krate
|
||||
}
|
||||
|
@ -43,14 +43,14 @@ struct CollectProcMacros<'a> {
|
||||
}
|
||||
|
||||
pub fn inject(
|
||||
krate: &mut ast::Crate,
|
||||
sess: &Session,
|
||||
resolver: &mut dyn ResolverExpand,
|
||||
mut krate: ast::Crate,
|
||||
is_proc_macro_crate: bool,
|
||||
has_proc_macro_decls: bool,
|
||||
is_test_crate: bool,
|
||||
handler: &rustc_errors::Handler,
|
||||
) -> ast::Crate {
|
||||
) {
|
||||
let ecfg = ExpansionConfig::default("proc_macro".to_string());
|
||||
let mut cx = ExtCtxt::new(sess, ecfg, resolver, None);
|
||||
|
||||
@ -64,22 +64,20 @@ pub fn inject(
|
||||
};
|
||||
|
||||
if has_proc_macro_decls || is_proc_macro_crate {
|
||||
visit::walk_crate(&mut collect, &krate);
|
||||
visit::walk_crate(&mut collect, krate);
|
||||
}
|
||||
let macros = collect.macros;
|
||||
|
||||
if !is_proc_macro_crate {
|
||||
return krate;
|
||||
return;
|
||||
}
|
||||
|
||||
if is_test_crate {
|
||||
return krate;
|
||||
return;
|
||||
}
|
||||
|
||||
let decls = mk_decls(&mut cx, ¯os);
|
||||
krate.items.push(decls);
|
||||
|
||||
krate
|
||||
}
|
||||
|
||||
impl<'a> CollectProcMacros<'a> {
|
||||
|
@ -8,16 +8,12 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use thin_vec::thin_vec;
|
||||
|
||||
pub fn inject(
|
||||
mut krate: ast::Crate,
|
||||
resolver: &mut dyn ResolverExpand,
|
||||
sess: &Session,
|
||||
) -> ast::Crate {
|
||||
pub fn inject(krate: &mut ast::Crate, resolver: &mut dyn ResolverExpand, sess: &Session) {
|
||||
let edition = sess.parse_sess.edition;
|
||||
|
||||
// the first name in this list is the crate name of the crate with the prelude
|
||||
let names: &[Symbol] = if attr::contains_name(&krate.attrs, sym::no_core) {
|
||||
return krate;
|
||||
return;
|
||||
} else if attr::contains_name(&krate.attrs, sym::no_std) {
|
||||
if attr::contains_name(&krate.attrs, sym::compiler_builtins) {
|
||||
&[sym::core]
|
||||
@ -88,6 +84,4 @@ pub fn inject(
|
||||
);
|
||||
|
||||
krate.items.insert(0, use_item);
|
||||
|
||||
krate
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ struct TestCtxt<'a> {
|
||||
|
||||
/// Traverse the crate, collecting all the test functions, eliding any
|
||||
/// existing main functions, and synthesizing a main test harness
|
||||
pub fn inject(sess: &Session, resolver: &mut dyn ResolverExpand, krate: &mut ast::Crate) {
|
||||
pub fn inject(krate: &mut ast::Crate, sess: &Session, resolver: &mut dyn ResolverExpand) {
|
||||
let span_diagnostic = sess.diagnostic();
|
||||
let panic_strategy = sess.panic_strategy();
|
||||
let platform_panic_strategy = sess.target.panic_strategy;
|
||||
|
@ -192,38 +192,32 @@ fn get_features(sess: &Session, krate_attrs: &[ast::Attribute]) -> Features {
|
||||
}
|
||||
|
||||
/// `cfg_attr`-process the crate's attributes and compute the crate's features.
|
||||
pub fn features(
|
||||
sess: &Session,
|
||||
mut krate: ast::Crate,
|
||||
lint_node_id: NodeId,
|
||||
) -> (ast::Crate, Features) {
|
||||
pub fn features(sess: &Session, krate: &mut ast::Crate, lint_node_id: NodeId) -> Features {
|
||||
let mut strip_unconfigured =
|
||||
StripUnconfigured { sess, features: None, config_tokens: false, lint_node_id };
|
||||
|
||||
let unconfigured_attrs = krate.attrs.clone();
|
||||
let mut unconfigured_attrs = krate.attrs.clone();
|
||||
let diag = &sess.parse_sess.span_diagnostic;
|
||||
let err_count = diag.err_count();
|
||||
let features = match strip_unconfigured.configure_krate_attrs(krate.attrs) {
|
||||
None => {
|
||||
// The entire crate is unconfigured.
|
||||
krate.attrs = ast::AttrVec::new();
|
||||
krate.items = ThinVec::new();
|
||||
Features::default()
|
||||
|
||||
krate.attrs.flat_map_in_place(|attr| strip_unconfigured.process_cfg_attr(&attr));
|
||||
if !strip_unconfigured.in_cfg(&krate.attrs) {
|
||||
// The entire crate is unconfigured.
|
||||
krate.attrs = ast::AttrVec::new();
|
||||
krate.items = ThinVec::new();
|
||||
Features::default()
|
||||
} else {
|
||||
let features = get_features(sess, &krate.attrs);
|
||||
if err_count == diag.err_count() {
|
||||
// Avoid reconfiguring malformed `cfg_attr`s.
|
||||
strip_unconfigured.features = Some(&features);
|
||||
// Run configuration again, this time with features available
|
||||
// so that we can perform feature-gating.
|
||||
unconfigured_attrs.flat_map_in_place(|attr| strip_unconfigured.process_cfg_attr(&attr));
|
||||
strip_unconfigured.in_cfg(&unconfigured_attrs);
|
||||
}
|
||||
Some(attrs) => {
|
||||
krate.attrs = attrs;
|
||||
let features = get_features(sess, &krate.attrs);
|
||||
if err_count == diag.err_count() {
|
||||
// Avoid reconfiguring malformed `cfg_attr`s.
|
||||
strip_unconfigured.features = Some(&features);
|
||||
// Run configuration again, this time with features available
|
||||
// so that we can perform feature-gating.
|
||||
strip_unconfigured.configure_krate_attrs(unconfigured_attrs);
|
||||
}
|
||||
features
|
||||
}
|
||||
};
|
||||
(krate, features)
|
||||
features
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
@ -254,11 +248,6 @@ impl<'a> StripUnconfigured<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn configure_krate_attrs(&self, mut attrs: ast::AttrVec) -> Option<ast::AttrVec> {
|
||||
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
|
||||
self.in_cfg(&attrs).then_some(attrs)
|
||||
}
|
||||
|
||||
/// Performs cfg-expansion on `stream`, producing a new `AttrTokenStream`.
|
||||
/// This is only used during the invocation of `derive` proc-macros,
|
||||
/// which require that we cfg-expand their entire input.
|
||||
@ -281,7 +270,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
.iter()
|
||||
.flat_map(|tree| match tree.clone() {
|
||||
AttrTokenTree::Attributes(mut data) => {
|
||||
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
|
||||
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));
|
||||
|
||||
if self.in_cfg(&data.attrs) {
|
||||
data.tokens = LazyAttrTokenStream::new(
|
||||
@ -319,12 +308,16 @@ impl<'a> StripUnconfigured<'a> {
|
||||
/// the syntax of any `cfg_attr` is incorrect.
|
||||
fn process_cfg_attrs<T: HasAttrs>(&self, node: &mut T) {
|
||||
node.visit_attrs(|attrs| {
|
||||
attrs.flat_map_in_place(|attr| self.process_cfg_attr(attr));
|
||||
attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));
|
||||
});
|
||||
}
|
||||
|
||||
fn process_cfg_attr(&self, attr: Attribute) -> Vec<Attribute> {
|
||||
if attr.has_name(sym::cfg_attr) { self.expand_cfg_attr(attr, true) } else { vec![attr] }
|
||||
fn process_cfg_attr(&self, attr: &Attribute) -> Vec<Attribute> {
|
||||
if attr.has_name(sym::cfg_attr) {
|
||||
self.expand_cfg_attr(attr, true)
|
||||
} else {
|
||||
vec![attr.clone()]
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse and expand a single `cfg_attr` attribute into a list of attributes
|
||||
@ -334,9 +327,9 @@ impl<'a> StripUnconfigured<'a> {
|
||||
/// Gives a compiler warning when the `cfg_attr` contains no attributes and
|
||||
/// is in the original source file. Gives a compiler error if the syntax of
|
||||
/// the attribute is incorrect.
|
||||
pub(crate) fn expand_cfg_attr(&self, attr: Attribute, recursive: bool) -> Vec<Attribute> {
|
||||
pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec<Attribute> {
|
||||
let Some((cfg_predicate, expanded_attrs)) =
|
||||
rustc_parse::parse_cfg_attr(&attr, &self.sess.parse_sess) else {
|
||||
rustc_parse::parse_cfg_attr(attr, &self.sess.parse_sess) else {
|
||||
return vec![];
|
||||
};
|
||||
|
||||
@ -365,10 +358,10 @@ impl<'a> StripUnconfigured<'a> {
|
||||
// `#[cfg_attr(false, cfg_attr(true, some_attr))]`.
|
||||
expanded_attrs
|
||||
.into_iter()
|
||||
.flat_map(|item| self.process_cfg_attr(self.expand_cfg_attr_item(&attr, item)))
|
||||
.flat_map(|item| self.process_cfg_attr(&self.expand_cfg_attr_item(attr, item)))
|
||||
.collect()
|
||||
} else {
|
||||
expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(&attr, item)).collect()
|
||||
expanded_attrs.into_iter().map(|item| self.expand_cfg_attr_item(attr, item)).collect()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1688,7 +1688,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
res
|
||||
}
|
||||
|
||||
fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: ast::Attribute, pos: usize) {
|
||||
fn expand_cfg_attr(&self, node: &mut impl HasAttrs, attr: &ast::Attribute, pos: usize) {
|
||||
node.visit_attrs(|attrs| {
|
||||
// Repeated `insert` calls is inefficient, but the number of
|
||||
// insertions is almost always 0 or 1 in practice.
|
||||
@ -1712,7 +1712,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
Default::default()
|
||||
}
|
||||
sym::cfg_attr => {
|
||||
self.expand_cfg_attr(&mut node, attr, pos);
|
||||
self.expand_cfg_attr(&mut node, &attr, pos);
|
||||
continue;
|
||||
}
|
||||
_ => {
|
||||
@ -1760,7 +1760,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
|
||||
continue;
|
||||
}
|
||||
sym::cfg_attr => {
|
||||
self.expand_cfg_attr(node, attr, pos);
|
||||
self.expand_cfg_attr(node, &attr, pos);
|
||||
continue;
|
||||
}
|
||||
_ => visit_clobber(node, |node| {
|
||||
|
@ -76,10 +76,10 @@ pub fn register_plugins<'a>(
|
||||
sess: &'a Session,
|
||||
metadata_loader: &'a dyn MetadataLoader,
|
||||
register_lints: impl Fn(&Session, &mut LintStore),
|
||||
mut krate: ast::Crate,
|
||||
krate: &mut ast::Crate,
|
||||
crate_name: Symbol,
|
||||
) -> Result<(ast::Crate, LintStore)> {
|
||||
krate = sess.time("attributes_injection", || {
|
||||
) -> Result<LintStore> {
|
||||
sess.time("attributes_injection", || {
|
||||
rustc_builtin_macros::cmdline_attrs::inject(
|
||||
krate,
|
||||
&sess.parse_sess,
|
||||
@ -87,7 +87,7 @@ pub fn register_plugins<'a>(
|
||||
)
|
||||
});
|
||||
|
||||
let (krate, features) = rustc_expand::config::features(sess, krate, CRATE_NODE_ID);
|
||||
let features = rustc_expand::config::features(sess, krate, CRATE_NODE_ID);
|
||||
// these need to be set "early" so that expansion sees `quote` if enabled.
|
||||
sess.init_features(features);
|
||||
|
||||
@ -117,8 +117,8 @@ pub fn register_plugins<'a>(
|
||||
let mut lint_store = rustc_lint::new_lint_store(sess.enable_internal_lints());
|
||||
register_lints(sess, &mut lint_store);
|
||||
|
||||
let registrars =
|
||||
sess.time("plugin_loading", || plugin::load::load_plugins(sess, metadata_loader, &krate));
|
||||
let registrars = sess
|
||||
.time("plugin_loading", || plugin::load::load_plugins(sess, metadata_loader, &krate.attrs));
|
||||
sess.time("plugin_registration", || {
|
||||
let mut registry = plugin::Registry { lint_store: &mut lint_store };
|
||||
for registrar in registrars {
|
||||
@ -126,7 +126,7 @@ pub fn register_plugins<'a>(
|
||||
}
|
||||
});
|
||||
|
||||
Ok((krate, lint_store))
|
||||
Ok(lint_store)
|
||||
}
|
||||
|
||||
fn pre_expansion_lint<'a>(
|
||||
@ -181,8 +181,8 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>)
|
||||
pre_expansion_lint(sess, lint_store, tcx.registered_tools(()), &krate, crate_name);
|
||||
rustc_builtin_macros::register_builtin_macros(resolver);
|
||||
|
||||
krate = sess.time("crate_injection", || {
|
||||
rustc_builtin_macros::standard_library_imports::inject(krate, resolver, sess)
|
||||
sess.time("crate_injection", || {
|
||||
rustc_builtin_macros::standard_library_imports::inject(&mut krate, resolver, sess)
|
||||
});
|
||||
|
||||
util::check_attr_crate_type(sess, &krate.attrs, &mut resolver.lint_buffer());
|
||||
@ -263,7 +263,7 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>)
|
||||
});
|
||||
|
||||
sess.time("maybe_building_test_harness", || {
|
||||
rustc_builtin_macros::test_harness::inject(sess, resolver, &mut krate)
|
||||
rustc_builtin_macros::test_harness::inject(&mut krate, sess, resolver)
|
||||
});
|
||||
|
||||
let has_proc_macro_decls = sess.time("AST_validation", || {
|
||||
@ -287,12 +287,12 @@ fn configure_and_expand(mut krate: ast::Crate, resolver: &mut Resolver<'_, '_>)
|
||||
sess.emit_warning(errors::ProcMacroCratePanicAbort);
|
||||
}
|
||||
|
||||
krate = sess.time("maybe_create_a_macro_crate", || {
|
||||
sess.time("maybe_create_a_macro_crate", || {
|
||||
let is_test_crate = sess.opts.test;
|
||||
rustc_builtin_macros::proc_macro_harness::inject(
|
||||
&mut krate,
|
||||
sess,
|
||||
resolver,
|
||||
krate,
|
||||
is_proc_macro_crate,
|
||||
has_proc_macro_decls,
|
||||
is_test_crate,
|
||||
|
@ -136,14 +136,14 @@ impl<'tcx> Queries<'tcx> {
|
||||
pub fn register_plugins(&self) -> Result<QueryResult<'_, (ast::Crate, Lrc<LintStore>)>> {
|
||||
self.register_plugins.compute(|| {
|
||||
let crate_name = *self.crate_name()?.borrow();
|
||||
let krate = self.parse()?.steal();
|
||||
let mut krate = self.parse()?.steal();
|
||||
|
||||
let empty: &(dyn Fn(&Session, &mut LintStore) + Sync + Send) = &|_, _| {};
|
||||
let (krate, lint_store) = passes::register_plugins(
|
||||
let lint_store = passes::register_plugins(
|
||||
self.session(),
|
||||
&*self.codegen_backend().metadata_loader(),
|
||||
self.compiler.register_lints.as_deref().unwrap_or_else(|| empty),
|
||||
krate,
|
||||
&mut krate,
|
||||
crate_name,
|
||||
)?;
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
use crate::errors::{LoadPluginError, MalformedPluginAttribute};
|
||||
use crate::Registry;
|
||||
use libloading::Library;
|
||||
use rustc_ast::Crate;
|
||||
use rustc_ast::Attribute;
|
||||
use rustc_metadata::locator;
|
||||
use rustc_session::cstore::MetadataLoader;
|
||||
use rustc_session::Session;
|
||||
@ -20,11 +20,11 @@ type PluginRegistrarFn = fn(&mut Registry<'_>);
|
||||
pub fn load_plugins(
|
||||
sess: &Session,
|
||||
metadata_loader: &dyn MetadataLoader,
|
||||
krate: &Crate,
|
||||
attrs: &[Attribute],
|
||||
) -> Vec<PluginRegistrarFn> {
|
||||
let mut plugins = Vec::new();
|
||||
|
||||
for attr in &krate.attrs {
|
||||
for attr in attrs {
|
||||
if !attr.has_name(sym::plugin) {
|
||||
continue;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user