//! Validates all used crates and extern libraries and loads their metadata
-use common::rustc_version;
use cstore::{self, CStore, CrateSource, MetadataBlob};
use decoder;
use loader::{self, CratePaths};
return ret;
}
- fn verify_rustc_version(&self,
- name: &str,
- span: Span,
- metadata: &MetadataBlob) {
- let crate_rustc_version = decoder::crate_rustc_version(metadata.as_slice());
- if crate_rustc_version != Some(rustc_version()) {
- let mut err = struct_span_fatal!(self.sess, span, E0514,
- "the crate `{}` has been compiled with {}, which is \
- incompatible with this version of rustc",
- name,
- crate_rustc_version
- .as_ref().map(|s| &**s)
- .unwrap_or("an old version of rustc"));
- err.help("consider removing the compiled binaries and recompiling \
- with your current version of rustc");
- err.emit();
- }
- }
-
fn verify_no_symbol_conflicts(&self,
span: Span,
metadata: &MetadataBlob) {
explicitly_linked: bool)
-> (ast::CrateNum, Rc<cstore::CrateMetadata>,
cstore::CrateSource) {
- self.verify_rustc_version(name, span, &lib.metadata);
self.verify_no_symbol_conflicts(span, &lib.metadata);
// Claim this crate number and cache it
rejected_via_hash: vec!(),
rejected_via_triple: vec!(),
rejected_via_kind: vec!(),
+ rejected_via_version: vec!(),
should_match_name: true,
};
match self.load(&mut load_ctxt) {
rejected_via_hash: vec!(),
rejected_via_triple: vec!(),
rejected_via_kind: vec!(),
+ rejected_via_version: vec!(),
should_match_name: true,
};
let library = self.load(&mut load_ctxt).or_else(|| {
//! metadata::loader or metadata::creader for all the juicy details!
use cstore::{MetadataBlob, MetadataVec, MetadataArchive};
+use common::{metadata_encoding_version, rustc_version};
use decoder;
-use encoder;
use rustc::hir::svh::Svh;
use rustc::session::Session;
pub rejected_via_hash: Vec<CrateMismatch>,
pub rejected_via_triple: Vec<CrateMismatch>,
pub rejected_via_kind: Vec<CrateMismatch>,
+ pub rejected_via_version: Vec<CrateMismatch>,
pub should_match_name: bool,
}
struct_span_err!(self.sess, self.span, E0462,
"found staticlib `{}` instead of rlib or dylib{}",
self.ident, add)
+ } else if !self.rejected_via_version.is_empty() {
+ struct_span_err!(self.sess, self.span, E0514,
+ "found crate `{}` compiled by an incompatible version of rustc{}",
+ self.ident, add)
} else {
struct_span_err!(self.sess, self.span, E0463,
"can't find crate for `{}`{}",
}
}
if !self.rejected_via_hash.is_empty() {
- err.note("perhaps this crate needs to be recompiled?");
+ err.note("perhaps that crate needs to be recompiled?");
let mismatches = self.rejected_via_hash.iter();
for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() {
err.note(&format!("crate `{}` path #{}: {}",
}
}
if !self.rejected_via_kind.is_empty() {
- err.help("please recompile this crate using --crate-type lib");
+ err.help("please recompile that crate using --crate-type lib");
let mismatches = self.rejected_via_kind.iter();
for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() {
err.note(&format!("crate `{}` path #{}: {}",
self.ident, i+1, path.display()));
}
}
+ if !self.rejected_via_version.is_empty() {
+ err.help(&format!("please recompile that crate using this compiler ({})",
+ rustc_version()));
+ let mismatches = self.rejected_via_version.iter();
+ for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() {
+ err.note(&format!("crate `{}` path #{}: {} compiled by {:?}",
+ self.ident, i+1, path.display(), got));
+ }
+ }
err.emit();
self.sess.abort_if_errors();
}
fn crate_matches(&mut self, crate_data: &[u8], libpath: &Path) -> Option<Svh> {
+ let crate_rustc_version = decoder::crate_rustc_version(crate_data);
+ if crate_rustc_version != Some(rustc_version()) {
+ let message = crate_rustc_version.unwrap_or(format!("an unknown compiler"));
+ info!("Rejecting via version: expected {} got {}", rustc_version(), message);
+ self.rejected_via_version.push(CrateMismatch {
+ path: libpath.to_path_buf(),
+ got: message
+ });
+ return None;
+ }
+
if self.should_match_name {
match decoder::maybe_get_crate_name(crate_data) {
Some(ref name) if self.crate_name == *name => {}
let cbuf = llvm::LLVMGetSectionContents(si.llsi);
let csz = llvm::LLVMGetSectionSize(si.llsi) as usize;
let cvbuf: *const u8 = cbuf as *const u8;
- let vlen = encoder::metadata_encoding_version.len();
+ let vlen = metadata_encoding_version.len();
debug!("checking {} bytes of metadata-version stamp",
vlen);
let minsz = cmp::min(vlen, csz);
let buf0 = slice::from_raw_parts(cvbuf, minsz);
- let version_ok = buf0 == encoder::metadata_encoding_version;
+ let version_ok = buf0 == metadata_encoding_version;
if !version_ok {
return Err((format!("incompatible metadata version found: '{}'",
filename.display())));