From 4f9fdcaa3b70a12ec0c5acc619474b11680613ee Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Wed, 12 Jul 2023 22:45:40 +0100 Subject: [PATCH] Inject compiler_builtins during crate resolution This is an alternative to #113557 which removes `compiler_builtins` from the prelude and injects it during crate resolution instead. Fixes #113533 --- .../src/standard_library_imports.rs | 45 +++++++------------ compiler/rustc_metadata/messages.ftl | 3 ++ compiler/rustc_metadata/src/creader.rs | 22 +++++++++ compiler/rustc_metadata/src/errors.rs | 6 +++ compiler/rustc_metadata/src/rmeta/decoder.rs | 4 ++ 5 files changed, 50 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs index 6493c6f13d541..09f98c577cf7c 100644 --- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs +++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs @@ -4,7 +4,7 @@ use rustc_expand::expand::ExpansionConfig; use rustc_session::Session; use rustc_span::edition::Edition::*; use rustc_span::hygiene::AstPass; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::DUMMY_SP; use thin_vec::thin_vec; @@ -17,17 +17,12 @@ pub fn inject( let orig_num_items = krate.items.len(); 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(pre_configured_attrs, sym::no_core) { + let name = if attr::contains_name(pre_configured_attrs, sym::no_core) { return 0; } else if attr::contains_name(pre_configured_attrs, sym::no_std) { - if attr::contains_name(pre_configured_attrs, sym::compiler_builtins) { - &[sym::core] - } else { - &[sym::core, sym::compiler_builtins] - } + sym::core } else { - &[sym::std] + sym::std }; let expn_id = resolver.expansion_for_ast_pass( @@ -42,27 +37,17 @@ pub fn inject( let ecfg = ExpansionConfig::default("std_lib_injection".to_string()); let cx = ExtCtxt::new(sess, ecfg, resolver, None); - // .rev() to preserve ordering above in combination with insert(0, ...) - for &name in names.iter().rev() { - let ident = if edition >= Edition2018 { - Ident::new(name, span) - } else { - Ident::new(name, call_site) - }; - krate.items.insert( - 0, - cx.item( - span, - ident, - thin_vec![cx.attr_word(sym::macro_use, span)], - ast::ItemKind::ExternCrate(None), - ), - ); - } - - // The crates have been injected, the assumption is that the first one is - // the one with the prelude. - let name = names[0]; + let ident = + if edition >= Edition2018 { Ident::new(name, span) } else { Ident::new(name, call_site) }; + krate.items.insert( + 0, + cx.item( + span, + ident, + thin_vec![cx.attr_word(sym::macro_use, span)], + ast::ItemKind::ExternCrate(None), + ), + ); let root = (edition == Edition2015).then_some(kw::PathRoot); diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 13b3dac85d109..3771bcc4fb186 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -216,6 +216,9 @@ metadata_no_transitive_needs_dep = metadata_non_ascii_name = cannot load a crate with a non-ascii name `{$crate_name}` +metadata_not_compiler_builtins = + the crate `{$crate_name}` is not the compiler builtins crate + metadata_not_profiler_runtime = the crate `{$crate_name}` is not a profiler runtime diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index b3976d756eb0f..09f16f335cbdd 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -758,6 +758,27 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { self.inject_dependency_if(cnum, "a panic runtime", &|data| data.needs_panic_runtime()); } + fn inject_compiler_builtins(&mut self, krate: &ast::Crate) { + // Don't inject compiler_builtins for core and compiler_builtins. + if attr::contains_name(&krate.attrs, sym::no_core) + || attr::contains_name(&krate.attrs, sym::compiler_builtins) + { + return; + } + + info!("loading compiler_builtins"); + + let Some(cnum) = self.resolve_crate(sym::compiler_builtins, DUMMY_SP, CrateDepKind::Implicit) else { + return; + }; + let data = self.cstore.get_crate_data(cnum); + + // Sanity check the loaded crate to ensure it is indeed compiler_builtins + if !data.is_compiler_builtins() { + self.sess.emit_err(errors::NotCompilerBuiltins { crate_name: sym::compiler_builtins }); + } + } + fn inject_profiler_runtime(&mut self, krate: &ast::Crate) { if self.sess.opts.unstable_opts.no_profiler_runtime || !(self.sess.instrument_coverage() @@ -968,6 +989,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> { pub fn postprocess(&mut self, krate: &ast::Crate) { self.inject_forced_externs(); + self.inject_compiler_builtins(krate); self.inject_profiler_runtime(krate); self.inject_allocator_crate(krate); self.inject_panic_runtime(krate); diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs index fca06c0f47c22..8fccb33c2ee86 100644 --- a/compiler/rustc_metadata/src/errors.rs +++ b/compiler/rustc_metadata/src/errors.rs @@ -332,6 +332,12 @@ pub struct NoPanicStrategy { pub strategy: PanicStrategy, } +#[derive(Diagnostic)] +#[diag(metadata_not_compiler_builtins)] +pub struct NotCompilerBuiltins { + pub crate_name: Symbol, +} + #[derive(Diagnostic)] #[diag(metadata_profiler_builtins_needs_core)] pub struct ProfilerBuiltinsNeedsCore; diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index b9318aee58131..e155fcd0d19cc 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1700,6 +1700,10 @@ impl CrateMetadata { self.root.panic_runtime } + pub(crate) fn is_compiler_builtins(&self) -> bool { + self.root.compiler_builtins + } + pub(crate) fn is_profiler_runtime(&self) -> bool { self.root.profiler_runtime }