Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc_metadata: don't break the version check when CrateRoot changes. #37931

Merged
merged 1 commit into from
Nov 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,10 @@ impl<'a, 'tcx> MetadataBlob {
self.raw_bytes().starts_with(METADATA_HEADER)
}

pub fn get_rustc_version(&self) -> String {
Lazy::with_position(METADATA_HEADER.len() + 4).decode(self)
}

pub fn get_root(&self) -> CrateRoot {
let slice = self.raw_bytes();
let offset = METADATA_HEADER.len();
Expand Down
15 changes: 11 additions & 4 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1278,7 +1278,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let link_meta = self.link_meta;
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro);
let root = self.lazy(&CrateRoot {
rustc_version: rustc_version(),
name: link_meta.crate_name,
triple: tcx.sess.opts.target_triple.clone(),
hash: link_meta.crate_hash,
Expand Down Expand Up @@ -1368,7 +1367,8 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
// Will be filed with the root position after encoding everything.
cursor.write_all(&[0, 0, 0, 0]).unwrap();

let root = EncodeContext {
let root = {
let mut ecx = EncodeContext {
opaque: opaque::Encoder::new(&mut cursor),
tcx: tcx,
reexports: reexports,
Expand All @@ -1378,8 +1378,15 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
lazy_state: LazyState::NoNode,
type_shorthands: Default::default(),
predicate_shorthands: Default::default(),
}
.encode_crate_root();
};

// Encode the rustc version string in a predictable location.
rustc_version().encode(&mut ecx).unwrap();

// Encode all the entries and extra information in the crate,
// culminating in the `CrateRoot` which points to all of it.
ecx.encode_crate_root()
};
let mut result = cursor.into_inner();

// Encode the root position.
Expand Down
21 changes: 11 additions & 10 deletions src/librustc_metadata/locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,25 +629,26 @@ impl<'a> Context<'a> {
}

fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
let root = metadata.get_root();
if let Some(is_proc_macro) = self.is_proc_macro {
if root.macro_derive_registrar.is_some() != is_proc_macro {
return None;
}
}

let rustc_version = rustc_version();
if root.rustc_version != rustc_version {
let found_version = metadata.get_rustc_version();
if found_version != rustc_version {
info!("Rejecting via version: expected {} got {}",
rustc_version,
root.rustc_version);
found_version);
self.rejected_via_version.push(CrateMismatch {
path: libpath.to_path_buf(),
got: root.rustc_version,
got: found_version,
});
return None;
}

let root = metadata.get_root();
if let Some(is_proc_macro) = self.is_proc_macro {
if root.macro_derive_registrar.is_some() != is_proc_macro {
return None;
}
}

if self.should_match_name {
if self.crate_name != root.name {
info!("Rejecting via crate name");
Expand Down
9 changes: 5 additions & 4 deletions src/librustc_metadata/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,17 @@ pub fn rustc_version() -> String {

/// Metadata encoding version.
/// NB: increment this if you change the format of metadata such that
/// the rustc version can't be found to compare with `RUSTC_VERSION`.
pub const METADATA_VERSION: u8 = 3;
/// the rustc version can't be found to compare with `rustc_version()`.
pub const METADATA_VERSION: u8 = 4;

/// Metadata header which includes `METADATA_VERSION`.
/// To get older versions of rustc to ignore this metadata,
/// there are 4 zero bytes at the start, which are treated
/// as a length of 0 by old compilers.
///
/// This header is followed by the position of the `CrateRoot`.
/// This header is followed by the position of the `CrateRoot`,
/// which is encoded as a 32-bit big-endian unsigned integer,
/// and further followed by the rustc version string.
pub const METADATA_HEADER: &'static [u8; 12] =
&[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];

Expand Down Expand Up @@ -163,7 +165,6 @@ pub enum LazyState {

#[derive(RustcEncodable, RustcDecodable)]
pub struct CrateRoot {
pub rustc_version: String,
pub name: Symbol,
pub triple: String,
pub hash: hir::svh::Svh,
Expand Down