Change:
/// Metadata encoding version. /// N.B., increment this if you change the format of metadata such that /// the rustc version can't be found to compare with `rustc_version()`. <del> const METADATA_VERSION: u8 = 4; </del> <ins> const METADATA_VERSION: u8 = 5; </ins> /// Metadata header which includes `METADATA_VERSION`. <del> /// 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`, /// which is encoded as a 32-bit big-endian unsigned integer, /// and further followed by the rustc version string. <del> crate const METADATA_HEADER: &[u8; 12] = &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; </del> <ins> crate const METADATA_HEADER: &[u8; 8] = &[b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; </ins> /// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`, /// e.g. for `Lazy<[T]>`, this is the length (count of `T` values).

Discussion:
() appears to introduce some sort of bug in the archive generation, which causes script-servo to fail to build on perf: . do you think it's worth reverting that PR for now?
Hm, seems like this has since fixed itself. I'm going to close since it was probably spurious.
Hmm, that error sounds like a toolchain bug/limitation (it really shouldn't care what we throw in there). I wonder what the before/after size is for .
I have encountered this locally building Servo's script crate, as has Servo's CI.
Could someone provide the size (e.g. from ) before and after ? (which I was wondering about in ) Presumably for Servo itself it would have to be before and after a relevant rustup?
Before: After:
cc That's a 28.2% increase, much larger than what we saw for . Would be interesting to have artifact sizes (for benchmarks themselves) on perf although the damage has been done here. Okay that's bad but it doesn't increase the number of bits required to hold the number of bytes, maybe the whole size is closer to that threshold? That's my only guess so far as to why this is failing.
The pre-change rlib was ~530mb and post-change was in the range of ~550mb iirc.
EDIT2: that might have all been irrelevant, looks like the contents of the are the issue here, trying to create an archive with and just the fails.
So it turns out that our 4-byte prefix for is valid a COFF header. We have that so that very old rustc versions (pre-1.10, see ) don't succeed loading new s, but maybe it's been long enough? cc (we could also maybe rename the file in , which would presumably prevent older compilers from finding the file at all?) It's also possible we'll save some time if LLVM stops trying to parse our format as COFF.
Do I understand correctly by backwards compatibility we mean that if you're running an old rustc in a directory that happens to have rmeta files generated by a new rustc we'd just run into compilation errors if we didn't have the 4 byte zero prefix? i.e., it wouldn't introduce anything other than maybe odd-looking errors?

(I am struggling to understand why exactly we did this in the first place, as we don't guarantee metadata format within one minor release, even...) Hm, I would be ... surprised if LLVM started trying to parse arbitrary sections as various formats (e.g., COFF) but maybe that's normal behavior...
is newer than 1.10, so it'd really be just s, left around in sysroots or dirs (and I don't even think you can get this kind of error with Cargo?). IIUC, COFF is one of the major 3 formats (alongside ELF and Mach-O), and libraries are archives of files, so this is unsurprising to me. (EDIT: to clarify, what's surprising is that we accidentally made LLVM think we have a valid-ish COFF file, but once it thinks that, everything makes sense) LLVM has been parsing our as COFF, ever since 1.10, AFAICT. (Note that this doesn't apply to the special section of a crate, which has entirely different constraints, and also I think we changed its name since 1.10)
Thank you so much and