about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src
diff options
context:
space:
mode:
authorTrevor Gross <tmgross@umich.edu>2025-01-29 23:54:15 +0000
committerTrevor Gross <tmgross@umich.edu>2025-02-21 17:37:03 +0000
commit1412cfc987b2b6691367c2e7428c083bb207d722 (patch)
treeb0aeede5a9d9e35ce96464876a36acf2e589ddb4 /compiler/rustc_builtin_macros/src
parent83d70c029860e619f8cb91f15bfc34f7f2d7965f (diff)
downloadrust-1412cfc987b2b6691367c2e7428c083bb207d722.tar.gz
rust-1412cfc987b2b6691367c2e7428c083bb207d722.zip
Inject `compiler_builtins` during postprocessing rather than via AST
`compiler_builtins` is currently injected as `extern crate
compiler_builtins as _`. This has made gating via diagnostics difficult
because it appears in the crate graph as a non-private dependency, and
there isn't an easy way to differentiate between the injected AST and
user-specified `extern crate compiler_builtins`.

Resolve this by injecting `compiler_builtins` during postprocessing
rather than early in the AST. Most of the time this isn't even needed
because it shows up in `std` or `core`'s crate graph, but injection is
still needed to ensure `#![no_core]` works correctly.

A similar change was attempted at [1] but this encountered errors
building `proc_macro` and `rustc-std-workspace-std`. Similar failures
showed up while working on this patch, which were traced back to
`compiler_builtins` showing up in the graph twice (once via dependency
and once via injection). This is resolved by not injecting if a
`#![compiler_builtins]` crate already exists.

[1]: https://github.com/rust-lang/rust/pull/113634
Diffstat (limited to 'compiler/rustc_builtin_macros/src')
-rw-r--r--compiler/rustc_builtin_macros/src/standard_library_imports.rs49
1 files changed, 13 insertions, 36 deletions
diff --git a/compiler/rustc_builtin_macros/src/standard_library_imports.rs b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
index 1a3f4d2d449..6933ca09349 100644
--- a/compiler/rustc_builtin_macros/src/standard_library_imports.rs
+++ b/compiler/rustc_builtin_macros/src/standard_library_imports.rs
@@ -19,16 +19,12 @@ pub fn inject(
     let edition = sess.psess.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: Symbol = 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(
@@ -43,36 +39,16 @@ pub fn inject(
     let ecfg = ExpansionConfig::default("std_lib_injection".to_string(), features);
     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_span = if edition >= Edition2018 { span } else { call_site };
-        let item = if name == sym::compiler_builtins {
-            // compiler_builtins is a private implementation detail. We only
-            // need to insert it into the crate graph for linking and should not
-            // expose any of its public API.
-            //
-            // FIXME(#113634) We should inject this during post-processing like
-            // we do for the panic runtime, profiler runtime, etc.
-            cx.item(
-                span,
-                Ident::new(kw::Underscore, ident_span),
-                thin_vec![],
-                ast::ItemKind::ExternCrate(Some(name)),
-            )
-        } else {
-            cx.item(
-                span,
-                Ident::new(name, ident_span),
-                thin_vec![cx.attr_word(sym::macro_use, span)],
-                ast::ItemKind::ExternCrate(None),
-            )
-        };
-        krate.items.insert(0, item);
-    }
+    let ident_span = if edition >= Edition2018 { span } else { call_site };
 
-    // The crates have been injected, the assumption is that the first one is
-    // the one with the prelude.
-    let name = names[0];
+    let item = cx.item(
+        span,
+        Ident::new(name, ident_span),
+        thin_vec![cx.attr_word(sym::macro_use, span)],
+        ast::ItemKind::ExternCrate(None),
+    );
+
+    krate.items.insert(0, item);
 
     let root = (edition == Edition2015).then_some(kw::PathRoot);
 
@@ -88,6 +64,7 @@ pub fn inject(
         .map(|&symbol| Ident::new(symbol, span))
         .collect();
 
+    // Inject the relevant crate's prelude.
     let use_item = cx.item(
         span,
         Ident::empty(),