Skip to content

Commit 99f92df

Browse files
committed
Move metadata header and version checks together
This will make it easier to report rustc versions for older metadata formats.
1 parent cfa95fa commit 99f92df

File tree

2 files changed

+39
-25
lines changed

2 files changed

+39
-25
lines changed

compiler/rustc_metadata/src/locator.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@ use tracing::{debug, info};
241241
crate struct CrateLocator<'a> {
242242
// Immutable per-session configuration.
243243
only_needs_metadata: bool,
244-
sysroot: &'a Path,
245244
metadata_loader: &'a dyn MetadataLoader,
246245

247246
// Immutable per-search configuration.
@@ -308,7 +307,6 @@ impl<'a> CrateLocator<'a> {
308307

309308
CrateLocator {
310309
only_needs_metadata,
311-
sysroot: &sess.sysroot,
312310
metadata_loader,
313311
crate_name,
314312
exact_paths: if hash.is_none() {
@@ -547,6 +545,20 @@ impl<'a> CrateLocator<'a> {
547545
continue;
548546
}
549547
}
548+
Err(MetadataError::VersionMismatch(found_version)) => {
549+
// The file was present and created by the same compiler version, but we
550+
// couldn't load it for some reason. Give a hard error instead of silently
551+
// ignoring it, but only if we would have given an error anyway.
552+
let rustc_version = rustc_version();
553+
info!(
554+
"Rejecting via version: expected {} got {}",
555+
rustc_version, found_version
556+
);
557+
self.crate_rejections
558+
.via_version
559+
.push(CrateMismatch { path: lib, got: found_version });
560+
continue;
561+
}
550562
Err(MetadataError::LoadFailure(err)) => {
551563
info!("no metadata found: {}", err);
552564
// The file was present and created by the same compiler version, but we
@@ -591,16 +603,6 @@ impl<'a> CrateLocator<'a> {
591603
}
592604

593605
fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
594-
let rustc_version = rustc_version();
595-
let found_version = metadata.get_rustc_version();
596-
if found_version != rustc_version {
597-
info!("Rejecting via version: expected {} got {}", rustc_version, found_version);
598-
self.crate_rejections
599-
.via_version
600-
.push(CrateMismatch { path: libpath.to_path_buf(), got: found_version });
601-
return None;
602-
}
603-
604606
let root = metadata.get_root();
605607
if root.is_proc_macro_crate() != self.is_proc_macro {
606608
info!(
@@ -742,13 +744,9 @@ fn get_metadata_section<'p>(
742744
}
743745
};
744746
let blob = MetadataBlob::new(raw_bytes);
745-
if blob.is_compatible() {
746-
Ok(blob)
747-
} else {
748-
Err(MetadataError::LoadFailure(format!(
749-
"invalid metadata version found: {}",
750-
filename.display()
751-
)))
747+
match blob.check_compatibility() {
748+
Ok(()) => Ok(blob),
749+
Err(version) => Err(MetadataError::VersionMismatch(version)),
752750
}
753751
}
754752

@@ -862,6 +860,8 @@ enum MetadataError<'a> {
862860
NotPresent(&'a Path),
863861
/// The file was present and invalid.
864862
LoadFailure(String),
863+
/// The file was present, but compiled with a different rustc version.
864+
VersionMismatch(String),
865865
}
866866

867867
impl fmt::Display for MetadataError<'_> {
@@ -871,6 +871,11 @@ impl fmt::Display for MetadataError<'_> {
871871
f.write_str(&format!("no such file: '{}'", filename.display()))
872872
}
873873
MetadataError::LoadFailure(msg) => f.write_str(msg),
874+
MetadataError::VersionMismatch(found_version) => f.write_str(&format!(
875+
"rustc version mismatch. expected {}, found {}",
876+
rustc_version(),
877+
found_version,
878+
)),
874879
}
875880
}
876881
}

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -626,13 +626,22 @@ impl<'tcx> MetadataBlob {
626626
MetadataBlob(Lrc::new(metadata_ref))
627627
}
628628

629-
crate fn is_compatible(&self) -> bool {
630-
self.blob().starts_with(METADATA_HEADER)
631-
}
629+
crate fn check_compatibility(&self) -> Result<(), String> {
630+
if !self.blob().starts_with(METADATA_HEADER) {
631+
if self.blob().starts_with(b"rust") {
632+
return Err("<unknown rustc version>".to_string());
633+
}
634+
return Err("<invalid metadata header>".to_string());
635+
}
632636

633-
crate fn get_rustc_version(&self) -> String {
634-
Lazy::<String>::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 4).unwrap())
635-
.decode(self)
637+
let found_version =
638+
Lazy::<String>::from_position(NonZeroUsize::new(METADATA_HEADER.len() + 4).unwrap())
639+
.decode(self);
640+
if rustc_version() != found_version {
641+
return Err(found_version);
642+
}
643+
644+
Ok(())
636645
}
637646

638647
crate fn get_root(&self) -> CrateRoot<'tcx> {

0 commit comments

Comments
 (0)