From aa0082bf1f1be28afb27d50f8533a085a44d505b Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Mon, 16 Jun 2025 14:28:10 -0700 Subject: [PATCH 1/2] Add test verifying that changing comments recompiles dependents --- tests/run-make/rdr-ignores-comments/after.rs | 8 +++++++ tests/run-make/rdr-ignores-comments/before.rs | 8 +++++++ tests/run-make/rdr-ignores-comments/rmake.rs | 24 +++++++++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 tests/run-make/rdr-ignores-comments/after.rs create mode 100644 tests/run-make/rdr-ignores-comments/before.rs create mode 100644 tests/run-make/rdr-ignores-comments/rmake.rs diff --git a/tests/run-make/rdr-ignores-comments/after.rs b/tests/run-make/rdr-ignores-comments/after.rs new file mode 100644 index 0000000000000..9388c10c794c3 --- /dev/null +++ b/tests/run-make/rdr-ignores-comments/after.rs @@ -0,0 +1,8 @@ +#![crate_name = "foo"] +#![crate_type = "lib"] +// bbb +pub struct Foo; + +impl Foo { + pub fn bar(self: Foo) {} +} diff --git a/tests/run-make/rdr-ignores-comments/before.rs b/tests/run-make/rdr-ignores-comments/before.rs new file mode 100644 index 0000000000000..00b0d6478c73f --- /dev/null +++ b/tests/run-make/rdr-ignores-comments/before.rs @@ -0,0 +1,8 @@ +#![crate_name = "foo"] +#![crate_type = "lib"] +// aaa +pub struct Foo; + +impl Foo { + pub fn bar(self: Foo) {} +} diff --git a/tests/run-make/rdr-ignores-comments/rmake.rs b/tests/run-make/rdr-ignores-comments/rmake.rs new file mode 100644 index 0000000000000..ec37fdf753603 --- /dev/null +++ b/tests/run-make/rdr-ignores-comments/rmake.rs @@ -0,0 +1,24 @@ +// tests that changing the content of a comment will cause a change in the rmeta of a file +use run_make_support::{rfs, rustc}; +use std::hash::{Hash, Hasher}; +use std::path::Path; + +fn main() { + let before = check_and_hash("before.rs"); + let after = check_and_hash("after.rs"); + dbg!(before, after); + assert_neq!(before, after); +} + +fn check_and_hash

(filename: P) -> u64 +where + P: AsRef, +{ + rfs::rename(filename, "foo.rs"); + rustc().input("foo.rs").emit("metadata").run(); + // hash the output + let bytes = rfs::read("libfoo.rmeta"); + let mut hasher = std::hash::DefaultHasher::new(); + bytes.hash(&mut hasher); + hasher.finish() +} From 086f6ace76d9d3a4928048a33ea2ffff2d8bf0ad Mon Sep 17 00:00:00 2001 From: Jane Losare-Lusby Date: Tue, 1 Jul 2025 14:24:27 -0700 Subject: [PATCH 2/2] add flag to remove sourcemap and span encoding from main rmeta file --- compiler/rustc_metadata/src/rmeta/decoder.rs | 8 ++++++++ compiler/rustc_metadata/src/rmeta/encoder.rs | 18 +++++++++++++++++- compiler/rustc_metadata/src/rmeta/mod.rs | 1 + compiler/rustc_session/src/options.rs | 2 ++ compiler/rustc_session/src/session.rs | 4 ++++ tests/run-make/rdr-ignores-comments/rmake.rs | 10 ++++++---- 6 files changed, 38 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 065c261c19473..8e57c682ca01c 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -546,6 +546,10 @@ impl<'a, 'tcx> SpanDecoder for DecodeContext<'a, 'tcx> { } fn decode_span(&mut self) -> Span { + if !self.cdata().has_rmeta_extras() { + return DUMMY_SP; + } + let start = self.position(); let tag = SpanTag(self.peek_byte()); let data = if tag.kind() == SpanKind::Indirect { @@ -1999,6 +2003,10 @@ impl CrateMetadata { self.root.has_default_lib_allocator } + pub(crate) fn has_rmeta_extras(&self) -> bool { + self.root.has_rmeta_extras + } + pub(crate) fn is_proc_macro_crate(&self) -> bool { self.root.is_proc_macro_crate() } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index b2696ddc902cd..fdfbadea4e367 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -168,6 +168,10 @@ impl<'a, 'tcx> SpanEncoder for EncodeContext<'a, 'tcx> { } fn encode_span(&mut self, span: Span) { + if self.tcx.sess.is_split_rmeta_enabled() { + return; + } + match self.span_shorthands.entry(span) { Entry::Occupied(o) => { // If an offset is smaller than the absolute position, we encode with the offset. @@ -603,6 +607,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { adapted.encode(&mut self.opaque) } + fn dont_encode_source_map( + &mut self, + ) -> LazyTable>> { + let adapted = TableBuilder::default(); + adapted.encode(&mut self.opaque) + } + fn encode_crate_root(&mut self) -> LazyValue { let tcx = self.tcx; let mut stats: Vec<(&'static str, usize)> = Vec::with_capacity(32); @@ -708,7 +719,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { // Encode source_map. This needs to be done last, because encoding `Span`s tells us which // `SourceFiles` we actually need to encode. - let source_map = stat!("source-map", || self.encode_source_map()); + let source_map = if tcx.sess.is_split_rmeta_enabled() { + stat!("source-map", || self.dont_encode_source_map()) + } else { + stat!("source-map", || self.encode_source_map()) + }; let target_modifiers = stat!("target-modifiers", || self.encode_target_modifiers()); let root = stat!("final", || { @@ -733,6 +748,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { attrs, sym::default_lib_allocator, ), + has_rmeta_extras: !tcx.sess.is_split_rmeta_enabled(), proc_macro_data, debugger_visualizers, compiler_builtins: ast::attr::contains_name(attrs, sym::compiler_builtins), diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 077835283e968..663d37a145a83 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -260,6 +260,7 @@ pub(crate) struct CrateRoot { has_alloc_error_handler: bool, has_panic_handler: bool, has_default_lib_allocator: bool, + has_rmeta_extras: bool, crate_deps: LazyArray, dylib_dependency_formats: LazyArray>, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index ecd82c0cc01ab..b549c380811dc 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2537,6 +2537,8 @@ written to standard error output)"), by the linker"), split_lto_unit: Option = (None, parse_opt_bool, [TRACKED], "enable LTO unit splitting (default: no)"), + split_rmeta: Option = (None, parse_opt_bool, [TRACKED], + "split extra rmeta data that isn't relevant rlib ABI into a separate file"), src_hash_algorithm: Option = (None, parse_src_file_hash, [TRACKED], "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index bad2581ae31b9..c893d1adf89fc 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -400,6 +400,10 @@ impl Session { self.opts.unstable_opts.split_lto_unit == Some(true) } + pub fn is_split_rmeta_enabled(&self) -> bool { + self.opts.unstable_opts.split_rmeta == Some(true) + } + /// Check whether this compile session and crate type use static crt. pub fn crt_static(&self, crate_type: Option) -> bool { if !self.target.crt_static_respected { diff --git a/tests/run-make/rdr-ignores-comments/rmake.rs b/tests/run-make/rdr-ignores-comments/rmake.rs index ec37fdf753603..974962fcfc178 100644 --- a/tests/run-make/rdr-ignores-comments/rmake.rs +++ b/tests/run-make/rdr-ignores-comments/rmake.rs @@ -1,13 +1,15 @@ -// tests that changing the content of a comment will cause a change in the rmeta of a file -use run_make_support::{rfs, rustc}; +// tests that changing the content of a comment will not cause a change in the rmeta of a library if +// -Zsplit-rmeta is enabled use std::hash::{Hash, Hasher}; use std::path::Path; +use run_make_support::{rfs, rustc}; + fn main() { let before = check_and_hash("before.rs"); let after = check_and_hash("after.rs"); dbg!(before, after); - assert_neq!(before, after); + assert_eq!(before, after); } fn check_and_hash

(filename: P) -> u64 @@ -15,7 +17,7 @@ where P: AsRef, { rfs::rename(filename, "foo.rs"); - rustc().input("foo.rs").emit("metadata").run(); + rustc().input("foo.rs").emit("metadata").arg("-Zsplit-rmeta").run(); // hash the output let bytes = rfs::read("libfoo.rmeta"); let mut hasher = std::hash::DefaultHasher::new();