diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 065c261c19473..0fb4282b268be 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 { @@ -1628,8 +1632,8 @@ impl<'a> CrateMetadataRef<'a> { path.filter(|_| { // Only spend time on further checks if we have what to translate *to*. real_source_base_dir.is_some() - // Some tests need the translation to be always skipped. - && sess.opts.unstable_opts.translate_remapped_path_to_local_path + // Some tests need the translation to be always skipped. + && sess.opts.unstable_opts.translate_remapped_path_to_local_path }) .filter(|virtual_dir| { // Don't translate away `/rustc/$hash` if we're still remapping to it, @@ -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..add3f489d41d2 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. @@ -436,7 +440,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { assert!( last_pos <= position, "make sure that the calls to `lazy*` \ - are in the same order as the metadata fields", + are in the same order as the metadata fields", ); position.get() - last_pos.get() } @@ -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), @@ -1706,7 +1722,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record_array!(self.tables.module_children_non_reexports[def_id] <- module_children.iter().filter(|child| child.reexport_chain.is_empty()) - .map(|child| child.res.def_id().index)); + .map(|child| child.res.def_id().index)); record_defaulted_array!(self.tables.module_children_reexports[def_id] <- module_children.iter().filter(|child| !child.reexport_chain.is_empty())); @@ -1755,7 +1771,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if matches!(rpitit_info, ty::ImplTraitInTraitData::Trait { .. }) { record_array!( self.tables.assumed_wf_types_for_rpitit[def_id] - <- self.tcx.assumed_wf_types_for_rpitit(def_id) + <- self.tcx.assumed_wf_types_for_rpitit(def_id) ); self.encode_precise_capturing_args(def_id); } @@ -1838,7 +1854,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for &local_def_id in tcx.mir_keys(()) { if let DefKind::AssocFn | DefKind::Fn = tcx.def_kind(local_def_id) { record_array!(self.tables.deduced_param_attrs[local_def_id.to_def_id()] <- - self.tcx.deduced_param_attrs(local_def_id.to_def_id())); + self.tcx.deduced_param_attrs(local_def_id.to_def_id())); } } } 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/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..974962fcfc178 --- /dev/null +++ b/tests/run-make/rdr-ignores-comments/rmake.rs @@ -0,0 +1,26 @@ +// 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_eq!(before, after); +} + +fn check_and_hash

(filename: P) -> u64 +where + P: AsRef, +{ + rfs::rename(filename, "foo.rs"); + 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(); + bytes.hash(&mut hasher); + hasher.finish() +}