Change:
thread 'rustc' panicked at 'index out of bounds: the len is but the index is ', ../src/libserialize kind of expected, after switching toolchain from 1.15 back to 1.14. cargo clean && cargo build "repaired it"
Do you have some more information on how to reproduce this?
I hit this compiling hyper with 1.13 stable.
Which version of hyper is that? I can't reproduce with latest .
It was with master. I tried and now it works. So rustc/cargo were using libs compiled when I tried this with 1.15nightly?
Sounds a bit like cargo was re-using libraries that it should have re-compiled because the compiler has changed. cc
Sorry if I did not save the full backtrace - It was my first issue report. I switched away from 1.15 nightly back to 1.14 nightly in order to solve a serde macro issue. Cargo cleaning and rebuilding fixed the issue. I will make sure to run again and capture the output if it happens again. On 11/16/2016 4:54 PM, Michael Woerister wrote:
Sounds suspiciously like a Cargo bug! If there's a reproduction I'd be more than willing to dig in.
I believe I just reproduced this in Cargo itself: When executing with the last few lines are: So what's happening here is: is populating the entire crate cache with a bunch of libraries on the nightly compiler. switching compilers, Cargo decides to recompile everything. doesn't delete everything as it recompiles, rather incrementally builds up a new crate cache compiler, given to that directory, will read crates in that directory. compiler panics when reading a crate compiled by a future compiler. So I take back what I said earlier about this likely being a Cargo bug, it seems like this may be a bug in the compiler trying to read stale metadata? I thought we had like 10 checks in place to ensure we didn't do that, but maybe it's still leaking through?
I'm going to tag this as a stable-to-nightly regression as this appears to have been introduced in nightly. If I build cargo with beta and then switch to beta, the compiler doesn't ICE.
The panic on stable happens in we check version information. Did we change how we encode version information? cc
I incremented the header version number though... It should be impossible for older rustc to get that far.
on it looks the same on . Perhaps we just need a PR to bump that?
Oh it looks like my changes have reached stable. I wonder if perhaps the is in a precarious spot and/or has been moved or the serialization otherwise changed. This requires further investigation.
Why is this even calling leb128? Are we using variable-length integers in the metadata header?
I assumed leb128 was the crate being built, not one used by the compiler.
Sure enough. Now every change to requires us to update the LLVM version number, because checking the rustc version number requires parsing . I think we should go back to JSON version guard.
Ahh that's what it was. We can put it at the start then, before/after the absolute address. I'd forgotten that the whole struct would have to be decoded.
What was the PR that modified the versioning scheme? I gather that something has changed about it. Can somebody explain more clearly what is going wrong here?
I mistakenly put the version string inside a larger , somehow thinking that it being at the start helped, but if the whole (that is, ) can't be decoded (e.g. because its definition changed) then you don't get to see the version string, whereas before it was separate. The fix would be to separate it again, put it back at the start and leave it there. Or just encode/decode it before instead of as part of it. Either will work as long as it can't be affected by changes to the metadata schema. The PR that introduced the new schema was , although breakage didn't happen until changed later, for procedural macros and/or the name resolution changes ( would know).
removed the field from for macro modularization.
I believe I have a fix ready. Does this affect beta too now, or just nightly?
AFAIK it's just nightly, not beta or stable

Discussion:
self.raw_bytes().starts_with(METADATA_HEADER) } <ins> pub fn get_rustc_version(&self) -> String { Lazy::with_position(METADATA_HEADER.len() + 4).decode(self) } </ins> pub fn get_root(&self) -> CrateRoot { let slice = self.raw_bytes(); let offset = METADATA_HEADER.len();

let link_meta = self.link_meta; let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeProcMacro); let root = self.lazy(&CrateRoot { <del> rustc_version: rustc_version(), </del> name: link_meta.crate_name, triple: tcx.sess.opts.target_triple.clone(), hash: link_meta.crate_hash,

// Will be filed with the root position after encoding everything. cursor.write_all(&[0, 0, 0, 0]).unwrap(); <del> let root = EncodeContext { </del> <ins> let root = { let mut ecx = EncodeContext { </ins> opaque: opaque::Encoder::new(&mut cursor), tcx: tcx, reexports: reexports,

lazy_state: LazyState::NoNode, type_shorthands: Default::default(), predicate_shorthands: Default::default(), <del> } .encode_crate_root(); </del> <ins> }; // 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() }; </ins> let mut result = cursor.into_inner(); // Encode the root position.

} fn crate_matches(&mut self, metadata: &MetadataBlob, libpath: &Path) -> Option<Svh> { <del> 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; } } </del> let rustc_version = rustc_version(); <del> if root.rustc_version != rustc_version { </del> <ins> let found_version = metadata.get_rustc_version(); if found_version != rustc_version { </ins> info!("Rejecting via version: expected {} got {}", rustc_version, <del> root.rustc_version); </del> <ins> found_version); </ins> self.rejected_via_version.push(CrateMismatch { path: libpath.to_path_buf(), <del> got: root.rustc_version, </del> <ins> got: found_version, </ins> }); return None; } <ins> 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; } } </ins> if self.should_match_name { if self.crate_name != root.name { info!("Rejecting via crate name");

/// Metadata encoding version. /// NB: increment this if you change the format of metadata such that <del> /// the rustc version can't be found to compare with `RUSTC_VERSION`. pub const METADATA_VERSION: u8 = 3; </del> <ins> /// the rustc version can't be found to compare with `rustc_version()`. pub const METADATA_VERSION: u8 = 4; </ins> /// 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. /// <del> /// This header is followed by the position of the `CrateRoot`. </del> <ins> /// 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. </ins> pub const METADATA_HEADER: &'static [u8; 12] = &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];

#[derive(RustcEncodable, RustcDecodable)] pub struct CrateRoot { <del> pub rustc_version: String, </del> pub name: Symbol, pub triple: String, pub hash: hir::svh::Svh,