diff --git a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs index db05c00d211..2b6fcc169be 100644 --- a/compiler/rustc_builtin_macros/src/cmdline_attrs.rs +++ b/compiler/rustc_builtin_macros/src/cmdline_attrs.rs @@ -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 } diff --git a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs index a73fed6ccb2..378d5f39f4a 100644 --- a/compiler/rustc_builtin_macros/src/proc_macro_harness.rs +++ b/compiler/rustc_builtin_macros/src/proc_macro_harness.rs @@ -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> { diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index caed40d9fa8..f87e454ef7f 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -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 } diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 2d491b2dac8..43ab6c04428 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -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; diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index d6cb173ba9b..9ef185e9497 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -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 { - 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(&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 { - if attr.has_name(sym::cfg_attr) { self.expand_cfg_attr(attr, true) } else { vec![attr] } + fn process_cfg_attr(&self, attr: &Attribute) -> Vec { + 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 { + pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec { 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() } } diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 4092a192e0c..6408ccf7c43 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -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| { diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 71bdd4df95b..7c1f6d8c9b8 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -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 { + 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, diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs index 58ad044b399..c618297bdc0 100644 --- a/compiler/rustc_interface/src/queries.rs +++ b/compiler/rustc_interface/src/queries.rs @@ -136,14 +136,14 @@ impl<'tcx> Queries<'tcx> { pub fn register_plugins(&self) -> Result)>> { 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, )?; diff --git a/compiler/rustc_plugin_impl/src/load.rs b/compiler/rustc_plugin_impl/src/load.rs index 8e75e969ae0..27e5cb9f0d0 100644 --- a/compiler/rustc_plugin_impl/src/load.rs +++ b/compiler/rustc_plugin_impl/src/load.rs @@ -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 { let mut plugins = Vec::new(); - for attr in &krate.attrs { + for attr in attrs { if !attr.has_name(sym::plugin) { continue; }