Move metadata header and version checks together
This will make it easier to report rustc versions for older metadata formats.
This commit is contained in:
parent
14fbc3c005
commit
fdff4d7682
@ -676,6 +676,7 @@ fn list_metadata(early_dcx: &EarlyDiagCtxt, sess: &Session, metadata_loader: &dy
|
|||||||
metadata_loader,
|
metadata_loader,
|
||||||
&mut v,
|
&mut v,
|
||||||
&sess.opts.unstable_opts.ls,
|
&sess.opts.unstable_opts.ls,
|
||||||
|
sess.cfg_version,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
safe_println!("{}", String::from_utf8(v).unwrap());
|
safe_println!("{}", String::from_utf8(v).unwrap());
|
||||||
|
@ -569,8 +569,13 @@ fn extract_one(
|
|||||||
debug!("skipping empty file");
|
debug!("skipping empty file");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let (hash, metadata) =
|
let (hash, metadata) = match get_metadata_section(
|
||||||
match get_metadata_section(self.target, flavor, &lib, self.metadata_loader) {
|
self.target,
|
||||||
|
flavor,
|
||||||
|
&lib,
|
||||||
|
self.metadata_loader,
|
||||||
|
self.cfg_version,
|
||||||
|
) {
|
||||||
Ok(blob) => {
|
Ok(blob) => {
|
||||||
if let Some(h) = self.crate_matches(&blob, &lib) {
|
if let Some(h) = self.crate_matches(&blob, &lib) {
|
||||||
(h, blob)
|
(h, blob)
|
||||||
@ -579,14 +584,25 @@ fn extract_one(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Err(MetadataError::VersionMismatch { expected_version, found_version }) => {
|
||||||
|
// The file was present and created by the same compiler version, but we
|
||||||
|
// couldn't load it for some reason. Give a hard error instead of silently
|
||||||
|
// ignoring it, but only if we would have given an error anyway.
|
||||||
|
info!(
|
||||||
|
"Rejecting via version: expected {} got {}",
|
||||||
|
expected_version, found_version
|
||||||
|
);
|
||||||
|
self.crate_rejections
|
||||||
|
.via_version
|
||||||
|
.push(CrateMismatch { path: lib, got: found_version });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
Err(MetadataError::LoadFailure(err)) => {
|
Err(MetadataError::LoadFailure(err)) => {
|
||||||
info!("no metadata found: {}", err);
|
info!("no metadata found: {}", err);
|
||||||
// The file was present and created by the same compiler version, but we
|
// The file was present and created by the same compiler version, but we
|
||||||
// couldn't load it for some reason. Give a hard error instead of silently
|
// couldn't load it for some reason. Give a hard error instead of silently
|
||||||
// ignoring it, but only if we would have given an error anyway.
|
// ignoring it, but only if we would have given an error anyway.
|
||||||
self.crate_rejections
|
self.crate_rejections.via_invalid.push(CrateMismatch { path: lib, got: err });
|
||||||
.via_invalid
|
|
||||||
.push(CrateMismatch { path: lib, got: err });
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Err(err @ MetadataError::NotPresent(_)) => {
|
Err(err @ MetadataError::NotPresent(_)) => {
|
||||||
@ -648,16 +664,6 @@ fn extract_one(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
|
fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
|
||||||
let rustc_version = rustc_version(self.cfg_version);
|
|
||||||
let found_version = metadata.get_rustc_version();
|
|
||||||
if found_version != rustc_version {
|
|
||||||
info!("Rejecting via version: expected {} got {}", rustc_version, found_version);
|
|
||||||
self.crate_rejections
|
|
||||||
.via_version
|
|
||||||
.push(CrateMismatch { path: libpath.to_path_buf(), got: found_version });
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let header = metadata.get_header();
|
let header = metadata.get_header();
|
||||||
if header.is_proc_macro_crate != self.is_proc_macro {
|
if header.is_proc_macro_crate != self.is_proc_macro {
|
||||||
info!(
|
info!(
|
||||||
@ -770,6 +776,7 @@ fn get_metadata_section<'p>(
|
|||||||
flavor: CrateFlavor,
|
flavor: CrateFlavor,
|
||||||
filename: &'p Path,
|
filename: &'p Path,
|
||||||
loader: &dyn MetadataLoader,
|
loader: &dyn MetadataLoader,
|
||||||
|
cfg_version: &'static str,
|
||||||
) -> Result<MetadataBlob, MetadataError<'p>> {
|
) -> Result<MetadataBlob, MetadataError<'p>> {
|
||||||
if !filename.exists() {
|
if !filename.exists() {
|
||||||
return Err(MetadataError::NotPresent(filename));
|
return Err(MetadataError::NotPresent(filename));
|
||||||
@ -847,13 +854,18 @@ fn get_metadata_section<'p>(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let blob = MetadataBlob(raw_bytes);
|
let blob = MetadataBlob(raw_bytes);
|
||||||
if blob.is_compatible() {
|
match blob.check_compatibility(cfg_version) {
|
||||||
Ok(blob)
|
Ok(()) => Ok(blob),
|
||||||
} else {
|
Err(None) => Err(MetadataError::LoadFailure(format!(
|
||||||
Err(MetadataError::LoadFailure(format!(
|
|
||||||
"invalid metadata version found: {}",
|
"invalid metadata version found: {}",
|
||||||
filename.display()
|
filename.display()
|
||||||
)))
|
))),
|
||||||
|
Err(Some(found_version)) => {
|
||||||
|
return Err(MetadataError::VersionMismatch {
|
||||||
|
expected_version: rustc_version(cfg_version),
|
||||||
|
found_version,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -864,9 +876,10 @@ pub fn list_file_metadata(
|
|||||||
metadata_loader: &dyn MetadataLoader,
|
metadata_loader: &dyn MetadataLoader,
|
||||||
out: &mut dyn Write,
|
out: &mut dyn Write,
|
||||||
ls_kinds: &[String],
|
ls_kinds: &[String],
|
||||||
|
cfg_version: &'static str,
|
||||||
) -> IoResult<()> {
|
) -> IoResult<()> {
|
||||||
let flavor = get_flavor_from_path(path);
|
let flavor = get_flavor_from_path(path);
|
||||||
match get_metadata_section(target, flavor, path, metadata_loader) {
|
match get_metadata_section(target, flavor, path, metadata_loader, cfg_version) {
|
||||||
Ok(metadata) => metadata.list_crate_metadata(out, ls_kinds),
|
Ok(metadata) => metadata.list_crate_metadata(out, ls_kinds),
|
||||||
Err(msg) => write!(out, "{msg}\n"),
|
Err(msg) => write!(out, "{msg}\n"),
|
||||||
}
|
}
|
||||||
@ -932,6 +945,8 @@ enum MetadataError<'a> {
|
|||||||
NotPresent(&'a Path),
|
NotPresent(&'a Path),
|
||||||
/// The file was present and invalid.
|
/// The file was present and invalid.
|
||||||
LoadFailure(String),
|
LoadFailure(String),
|
||||||
|
/// The file was present, but compiled with a different rustc version.
|
||||||
|
VersionMismatch { expected_version: String, found_version: String },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for MetadataError<'_> {
|
impl fmt::Display for MetadataError<'_> {
|
||||||
@ -941,6 +956,12 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
f.write_str(&format!("no such file: '{}'", filename.display()))
|
f.write_str(&format!("no such file: '{}'", filename.display()))
|
||||||
}
|
}
|
||||||
MetadataError::LoadFailure(msg) => f.write_str(msg),
|
MetadataError::LoadFailure(msg) => f.write_str(msg),
|
||||||
|
MetadataError::VersionMismatch { expected_version, found_version } => {
|
||||||
|
f.write_str(&format!(
|
||||||
|
"rustc version mismatch. expected {}, found {}",
|
||||||
|
expected_version, found_version,
|
||||||
|
))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -684,13 +684,25 @@ fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> Self {
|
|||||||
implement_ty_decoder!(DecodeContext<'a, 'tcx>);
|
implement_ty_decoder!(DecodeContext<'a, 'tcx>);
|
||||||
|
|
||||||
impl MetadataBlob {
|
impl MetadataBlob {
|
||||||
pub(crate) fn is_compatible(&self) -> bool {
|
pub(crate) fn check_compatibility(
|
||||||
self.blob().starts_with(METADATA_HEADER)
|
&self,
|
||||||
|
cfg_version: &'static str,
|
||||||
|
) -> Result<(), Option<String>> {
|
||||||
|
if !self.blob().starts_with(METADATA_HEADER) {
|
||||||
|
if self.blob().starts_with(b"rust") {
|
||||||
|
return Err(Some("<unknown rustc version>".to_owned()));
|
||||||
|
}
|
||||||
|
return Err(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_rustc_version(&self) -> String {
|
let found_version =
|
||||||
LazyValue::<String>::from_position(NonZero::new(METADATA_HEADER.len() + 8).unwrap())
|
LazyValue::<String>::from_position(NonZero::new(METADATA_HEADER.len() + 8).unwrap())
|
||||||
.decode(self)
|
.decode(self);
|
||||||
|
if rustc_version(cfg_version) != found_version {
|
||||||
|
return Err(Some(found_version));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn root_pos(&self) -> NonZero<usize> {
|
fn root_pos(&self) -> NonZero<usize> {
|
||||||
|
Loading…
Reference in New Issue
Block a user