Skip to content

RDR: avoid rebuilding dependent crates after comment changes #143249

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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()
}
Expand Down
26 changes: 21 additions & 5 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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()
}
Expand Down Expand Up @@ -603,6 +607,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
adapted.encode(&mut self.opaque)
}

fn dont_encode_source_map(
&mut self,
) -> LazyTable<u32, Option<LazyValue<rustc_span::SourceFile>>> {
let adapted = TableBuilder::default();
adapted.encode(&mut self.opaque)
}

fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
let tcx = self.tcx;
let mut stats: Vec<(&'static str, usize)> = Vec::with_capacity(32);
Expand Down Expand Up @@ -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", || {
Expand All @@ -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),
Expand Down Expand Up @@ -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()));
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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()));
}
}
}
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<CrateDep>,
dylib_dependency_formats: LazyArray<Option<LinkagePreference>>,
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2537,6 +2537,8 @@ written to standard error output)"),
by the linker"),
split_lto_unit: Option<bool> = (None, parse_opt_bool, [TRACKED],
"enable LTO unit splitting (default: no)"),
split_rmeta: Option<bool> = (None, parse_opt_bool, [TRACKED],
"split extra rmeta data that isn't relevant rlib ABI into a separate file"),
src_hash_algorithm: Option<SourceFileHashAlgorithm> = (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")]
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<CrateType>) -> bool {
if !self.target.crt_static_respected {
Expand Down
8 changes: 8 additions & 0 deletions tests/run-make/rdr-ignores-comments/after.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![crate_name = "foo"]
#![crate_type = "lib"]
// bbb
pub struct Foo;

impl Foo {
pub fn bar(self: Foo) {}
}
8 changes: 8 additions & 0 deletions tests/run-make/rdr-ignores-comments/before.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#![crate_name = "foo"]
#![crate_type = "lib"]
// aaa
pub struct Foo;

impl Foo {
pub fn bar(self: Foo) {}
}
26 changes: 26 additions & 0 deletions tests/run-make/rdr-ignores-comments/rmake.rs
Original file line number Diff line number Diff line change
@@ -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<P>(filename: P) -> u64
where
P: AsRef<Path>,
{
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()
}
Loading