Skip to content

Commit

Permalink
Auto merge of #28702 - arielb1:metadata-versioning, r=nrc
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Sep 29, 2015
2 parents 59eb444 + f2d5ebe commit 65d5c08
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/librustc/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
8 changes: 8 additions & 0 deletions src/librustc/metadata/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")
)
}
21 changes: 21 additions & 0 deletions src/librustc/metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/middle/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 65d5c08

Please sign in to comment.