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:
commit
65d5c08337
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
)
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user