diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs index fd94e80f6312e..f5d2d5c686d8f 100644 --- a/compiler/rustc_codegen_cranelift/build_system/tests.rs +++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs @@ -433,6 +433,7 @@ impl<'a> TestRunner<'a> { cmd.arg(&self.target_compiler.triple); cmd.arg("-Cpanic=abort"); cmd.arg("--check-cfg=cfg(jit)"); + cmd.arg("--emit=metadata,link"); cmd.args(args); cmd } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 197ea956374d1..c0cb5fbc9bdb8 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -33,7 +33,7 @@ use rustc_span::{ }; use tracing::{debug, instrument, trace}; -use crate::errors::{FailCreateFileEncoder, FailWriteFile}; +use crate::errors::{FailCreateFileEncoder, FailWriteFile, FailedCreateFile}; use crate::rmeta::*; pub(super) struct EncodeContext<'a, 'tcx> { @@ -2312,6 +2312,10 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: &Path) { }); header.position.get() }); + } else { + std::fs::File::create(&ref_path).unwrap_or_else(|err| { + tcx.dcx().emit_fatal(FailedCreateFile { filename: &ref_path, err }); + }); } } diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 88595ff7e5198..9704b1867e07b 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -127,6 +127,12 @@ fn main() { } } + if orig_args.iter().any(|arg| arg == "-Zsplit-metadata") + && orig_args.windows(2).any(|args| args[0] == "--crate-type" && args[1] == "dylib") + { + cmd.arg("--emit").arg("metadata"); + } + // Print backtrace in case of ICE if env::var("RUSTC_BACKTRACE_ON_ICE").is_ok() && env::var("RUST_BACKTRACE").is_err() { cmd.env("RUST_BACKTRACE", "1"); diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 4ab4e60773f1e..f2f28bb7d9135 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -2070,14 +2070,12 @@ pub fn run_cargo( || filename.ends_with(".a") || is_debug_info(&filename) || is_dylib(&filename) + || filename.ends_with(".rmeta") { - // Always keep native libraries, rust dylibs and debuginfo + // Always keep native libraries, rust dylibs, debuginfo and crate metadata keep = true; } - if is_check && filename.ends_with(".rmeta") { - // During check builds we need to keep crate metadata - keep = true; - } else if rlib_only_metadata { + if !is_check && rlib_only_metadata { if filename.contains("jemalloc_sys") || filename.contains("rustc_smir") || filename.contains("stable_mir") @@ -2089,7 +2087,6 @@ pub fn run_cargo( // Distribute the rest of the rustc crates as rmeta files only to reduce // the tarball sizes by about 50%. The object files are linked into // librustc_driver.so, so it is still possible to link against them. - keep |= filename.ends_with(".rmeta"); } } else { // In all other cases keep all rlibs @@ -2135,7 +2132,12 @@ pub fn run_cargo( let file_stem = parts.next().unwrap().to_owned(); let extension = parts.next().unwrap().to_owned(); - toplevel.push((file_stem, extension, expected_len)); + if extension == "so" || extension == "dylib" { + // FIXME workaround for the fact that cargo doesn't understand `-Zsplit-metadata` + toplevel.push((file_stem.clone(), "rmeta".to_owned(), None)); + } + + toplevel.push((file_stem, extension, Some(expected_len))); } }); @@ -2156,7 +2158,7 @@ pub fn run_cargo( .collect::>(); for (prefix, extension, expected_len) in toplevel { let candidates = contents.iter().filter(|&(_, filename, meta)| { - meta.len() == expected_len + expected_len.map_or(true, |expected_len| meta.len() == expected_len) && filename .strip_prefix(&prefix[..]) .map(|s| s.starts_with('-') && s.ends_with(&extension[..])) @@ -2167,6 +2169,7 @@ pub fn run_cargo( }); let path_to_add = match max { Some(triple) => triple.0.to_str().unwrap(), + None if extension == "rmeta" => continue, // cfg(not(bootstrap)) remove this once -Zsplit-metadata is passed for all stages None => panic!("no output generated for {prefix:?} {extension:?}"), }; if is_dylib(path_to_add) { diff --git a/src/bootstrap/src/core/builder/cargo.rs b/src/bootstrap/src/core/builder/cargo.rs index c3d0994f16410..220b1330f1f03 100644 --- a/src/bootstrap/src/core/builder/cargo.rs +++ b/src/bootstrap/src/core/builder/cargo.rs @@ -625,6 +625,18 @@ impl Builder<'_> { hostflags.arg("-Zunstable-options"); hostflags.arg("--check-cfg=cfg(bootstrap)"); + match mode { + Mode::Std | Mode::Rustc | Mode::Codegen => { + // cfg(bootstrap) unconditionally pass this once the bootstrap compiler understands it + if stage != 0 { + // FIXME remove once cargo enables this by default + rustflags.arg("-Zsplit-metadata"); + } + } + // Tools may not expect to be compiled with -Zsplit-metadata + Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => {} + } + // FIXME: It might be better to use the same value for both `RUSTFLAGS` and `RUSTDOCFLAGS`, // but this breaks CI. At the very least, stage0 `rustdoc` needs `--cfg bootstrap`. See // #71458. diff --git a/tests/ui/duplicate_entry_error.rs b/tests/ui/duplicate_entry_error.rs index e8b905a65f60d..c7b30ca44ba45 100644 --- a/tests/ui/duplicate_entry_error.rs +++ b/tests/ui/duplicate_entry_error.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr-test: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta" // note-pattern: first defined in crate `std`. // Test for issue #31788 and E0152 @@ -11,7 +11,7 @@ use core::panic::PanicInfo; #[lang = "panic_impl"] fn panic_impl(info: &PanicInfo) -> ! { -//~^ ERROR: found duplicate lang item `panic_impl` + //~^ ERROR: found duplicate lang item `panic_impl` loop {} } diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/duplicate_entry_error.stderr index 958e9c7527d8c..73436153e6677 100644 --- a/tests/ui/duplicate_entry_error.stderr +++ b/tests/ui/duplicate_entry_error.stderr @@ -8,7 +8,7 @@ LL | | } | |_^ | = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on) - = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib + = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta = note: second definition in the local crate (`duplicate_entry_error`) error: aborting due to 1 previous error diff --git a/tests/ui/error-codes/E0152.rs b/tests/ui/error-codes/E0152.rs index 44d462c27e68f..41e60135b05b5 100644 --- a/tests/ui/error-codes/E0152.rs +++ b/tests/ui/error-codes/E0152.rs @@ -1,8 +1,7 @@ -//@ normalize-stderr-test: "loaded from .*liballoc-.*.rlib" -> "loaded from SYSROOT/liballoc-*.rlib" +//@ normalize-stderr-test: "loaded from .*liballoc-.*.rmeta" -> "loaded from SYSROOT/liballoc-*.rmeta" #![feature(lang_items)] #[lang = "owned_box"] struct Foo(T); //~ ERROR E0152 -fn main() { -} +fn main() {} diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr index dbea7e6d27fbe..73df5803e839a 100644 --- a/tests/ui/error-codes/E0152.stderr +++ b/tests/ui/error-codes/E0152.stderr @@ -5,7 +5,7 @@ LL | struct Foo(T); | ^^^^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `alloc` (which `std` depends on) - = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib + = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rmeta = note: second definition in the local crate (`E0152`) error: aborting due to 1 previous error diff --git a/tests/ui/lang-items/duplicate.rs b/tests/ui/lang-items/duplicate.rs index 3aa7dd2b0bee1..d1c344acefe29 100644 --- a/tests/ui/lang-items/duplicate.rs +++ b/tests/ui/lang-items/duplicate.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib" +//@ normalize-stderr-test: "loaded from .*libcore-.*.rmeta" -> "loaded from SYSROOT/libcore-*.rmeta" #![feature(lang_items)] #[lang = "sized"] diff --git a/tests/ui/lang-items/duplicate.stderr b/tests/ui/lang-items/duplicate.stderr index aaa8f5e605afa..5639bcc838d81 100644 --- a/tests/ui/lang-items/duplicate.stderr +++ b/tests/ui/lang-items/duplicate.stderr @@ -5,7 +5,7 @@ LL | trait Sized {} | ^^^^^^^^^^^^^^ | = note: the lang item is first defined in crate `core` (which `std` depends on) - = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib + = note: first definition in `core` loaded from SYSROOT/libcore-*.rmeta = note: second definition in the local crate (`duplicate`) error: aborting due to 1 previous error diff --git a/tests/ui/panic-handler/panic-handler-std.rs b/tests/ui/panic-handler/panic-handler-std.rs index 82e6de43a2ec7..93a2e810b431d 100644 --- a/tests/ui/panic-handler/panic-handler-std.rs +++ b/tests/ui/panic-handler/panic-handler-std.rs @@ -1,4 +1,4 @@ -//@ normalize-stderr-test: "loaded from .*libstd-.*.rlib" -> "loaded from SYSROOT/libstd-*.rlib" +//@ normalize-stderr-test: "loaded from .*libstd-.*.rmeta" -> "loaded from SYSROOT/libstd-*.rmeta" //@ error-pattern: found duplicate lang item `panic_impl` extern crate core; diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr index caae16118ef7f..de71b675211e9 100644 --- a/tests/ui/panic-handler/panic-handler-std.stderr +++ b/tests/ui/panic-handler/panic-handler-std.stderr @@ -7,7 +7,7 @@ LL | | } | |_^ | = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on) - = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib + = note: first definition in `std` loaded from SYSROOT/libstd-*.rmeta = note: second definition in the local crate (`panic_handler_std`) error: aborting due to 1 previous error