Auto merge of #28702 - arielb1:metadata-versioning, r=nrc

This prevents ICEs when old crates are used with a new version of
rustc. Currently, the linking of crates compiled with different
versions of rustc is completely unsupported.

Fixes #28700

r? @nrc
This commit is contained in:
bors 2015-09-29 23:26:34 +00:00
commit 65d5c08337
6 changed files with 42 additions and 2 deletions

View File

@ -2074,4 +2074,5 @@ register_diagnostics! {
E0495, // cannot infer an appropriate lifetime due to conflicting requirements
E0496, // .. name `..` shadows a .. name that is already in scope
E0498, // malformed plugin attribute
E0514, // metadata version mismatch
}

View File

@ -259,3 +259,11 @@ pub const tag_defaulted_trait: usize = 0xa4;
pub const tag_impl_coerce_unsized_kind: usize = 0xa5;
pub const tag_items_data_item_constness: usize = 0xa6;
pub const tag_rustc_version: usize = 0x10f;
pub fn rustc_version() -> String {
format!(
"rustc {}",
option_env!("CFG_VERSION").unwrap_or("unknown version")
)
}

View File

@ -15,6 +15,7 @@
use back::svh::Svh;
use session::{config, Session};
use session::search_paths::PathKind;
use metadata::common::rustc_version;
use metadata::cstore;
use metadata::cstore::{CStore, CrateSource, MetadataBlob};
use metadata::decoder;
@ -270,6 +271,24 @@ impl<'a> CrateReader<'a> {
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()) {
span_err!(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")
);
self.sess.abort_if_errors();
}
}
fn register_crate(&mut self,
root: &Option<CratePaths>,
ident: &str,
@ -279,6 +298,8 @@ impl<'a> CrateReader<'a> {
explicitly_linked: bool)
-> (ast::CrateNum, Rc<cstore::crate_metadata>,
cstore::CrateSource) {
self.verify_rustc_version(name, span, &lib.metadata);
// Claim this crate number and cache it
let cnum = self.next_crate_num;
self.next_crate_num += 1;

View File

@ -77,6 +77,11 @@ pub fn load_index(data: &[u8]) -> index::Index {
index::Index::from_buf(index.data, index.start, index.end)
}
pub fn crate_rustc_version(data: &[u8]) -> Option<String> {
let doc = rbml::Doc::new(data);
reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.as_str())
}
#[derive(Debug, PartialEq)]
enum Family {
ImmStatic, // c

View File

@ -1923,6 +1923,10 @@ fn encode_hash(rbml_w: &mut Encoder, hash: &Svh) {
rbml_w.wr_tagged_str(tag_crate_hash, hash.as_str());
}
fn encode_rustc_version(rbml_w: &mut Encoder) {
rbml_w.wr_tagged_str(tag_rustc_version, &rustc_version());
}
fn encode_crate_name(rbml_w: &mut Encoder, crate_name: &str) {
rbml_w.wr_tagged_str(tag_crate_crate_name, crate_name);
}
@ -2051,6 +2055,7 @@ fn encode_metadata_inner(wr: &mut Cursor<Vec<u8>>,
let mut rbml_w = Encoder::new(wr);
encode_rustc_version(&mut rbml_w);
encode_crate_name(&mut rbml_w, &ecx.link_meta.crate_name);
encode_crate_triple(&mut rbml_w, &tcx.sess.opts.target_triple);
encode_hash(&mut rbml_w, &ecx.link_meta.crate_hash);

View File

@ -244,7 +244,7 @@ impl OverloadedCallType {
// can just use the tcx as the typer.
//
// FIXME(stage0): the :'t here is probably only important for stage0
pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d+'t> {
pub struct ExprUseVisitor<'d, 't, 'a: 't, 'tcx:'a+'d> {
typer: &'t infer::InferCtxt<'a, 'tcx>,
mc: mc::MemCategorizationContext<'t, 'a, 'tcx>,
delegate: &'d mut Delegate<'tcx>,
@ -278,7 +278,7 @@ enum PassArgs {
impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
pub fn new(delegate: &'d mut Delegate<'tcx>,
typer: &'t infer::InferCtxt<'a, 'tcx>)
-> ExprUseVisitor<'d,'t,'a,'tcx>
-> ExprUseVisitor<'d,'t,'a,'tcx> where 'tcx:'a
{
ExprUseVisitor {
typer: typer,