Skip to content

Commit f4c68d2

Browse files
committed
rustc_metadata: don't break the version check when CrateRoot changes.
1 parent 1c11ea3 commit f4c68d2

File tree

4 files changed

+31
-18
lines changed

4 files changed

+31
-18
lines changed

src/librustc_metadata/decoder.rs

+4
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,10 @@ impl<'a, 'tcx> MetadataBlob {
420420
self.raw_bytes().starts_with(METADATA_HEADER)
421421
}
422422

423+
pub fn get_rustc_version(&self) -> String {
424+
Lazy::with_position(METADATA_HEADER.len() + 4).decode(self)
425+
}
426+
423427
pub fn get_root(&self) -> CrateRoot {
424428
let slice = self.raw_bytes();
425429
let offset = METADATA_HEADER.len();

src/librustc_metadata/encoder.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -1278,7 +1278,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
12781278
let link_meta = self.link_meta;
12791279
let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro);
12801280
let root = self.lazy(&CrateRoot {
1281-
rustc_version: rustc_version(),
12821281
name: link_meta.crate_name,
12831282
triple: tcx.sess.opts.target_triple.clone(),
12841283
hash: link_meta.crate_hash,
@@ -1368,7 +1367,8 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
13681367
// Will be filed with the root position after encoding everything.
13691368
cursor.write_all(&[0, 0, 0, 0]).unwrap();
13701369

1371-
let root = EncodeContext {
1370+
let root = {
1371+
let mut ecx = EncodeContext {
13721372
opaque: opaque::Encoder::new(&mut cursor),
13731373
tcx: tcx,
13741374
reexports: reexports,
@@ -1378,8 +1378,15 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
13781378
lazy_state: LazyState::NoNode,
13791379
type_shorthands: Default::default(),
13801380
predicate_shorthands: Default::default(),
1381-
}
1382-
.encode_crate_root();
1381+
};
1382+
1383+
// Encode the rustc version string in a predictable location.
1384+
rustc_version().encode(&mut ecx).unwrap();
1385+
1386+
// Encode all the entries and extra information in the crate,
1387+
// culminating in the `CrateRoot` which points to all of it.
1388+
ecx.encode_crate_root()
1389+
};
13831390
let mut result = cursor.into_inner();
13841391

13851392
// Encode the root position.

src/librustc_metadata/locator.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -629,25 +629,26 @@ impl<'a> Context<'a> {
629629
}
630630

631631
fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> {
632-
let root = metadata.get_root();
633-
if let Some(is_proc_macro) = self.is_proc_macro {
634-
if root.macro_derive_registrar.is_some() != is_proc_macro {
635-
return None;
636-
}
637-
}
638-
639632
let rustc_version = rustc_version();
640-
if root.rustc_version != rustc_version {
633+
let found_version = metadata.get_rustc_version();
634+
if found_version != rustc_version {
641635
info!("Rejecting via version: expected {} got {}",
642636
rustc_version,
643-
root.rustc_version);
637+
found_version);
644638
self.rejected_via_version.push(CrateMismatch {
645639
path: libpath.to_path_buf(),
646-
got: root.rustc_version,
640+
got: found_version,
647641
});
648642
return None;
649643
}
650644

645+
let root = metadata.get_root();
646+
if let Some(is_proc_macro) = self.is_proc_macro {
647+
if root.macro_derive_registrar.is_some() != is_proc_macro {
648+
return None;
649+
}
650+
}
651+
651652
if self.should_match_name {
652653
if self.crate_name != root.name {
653654
info!("Rejecting via crate name");

src/librustc_metadata/schema.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ pub fn rustc_version() -> String {
3434

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

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

@@ -163,7 +165,6 @@ pub enum LazyState {
163165

164166
#[derive(RustcEncodable, RustcDecodable)]
165167
pub struct CrateRoot {
166-
pub rustc_version: String,
167168
pub name: Symbol,
168169
pub triple: String,
169170
pub hash: hir::svh::Svh,

0 commit comments

Comments
 (0)