pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 cstore: &cstore::CStore,
                                 reexports: &def::ExportMap,
                                 link_meta: &LinkMeta,
                                 exported_symbols: &NodeSet)
                                 -> Vec<u8> {
    let mut cursor = Cursor::new(vec![]);
    cursor.write_all(METADATA_HEADER).unwrap();

    // Will be filed with the root position after encoding everything.
    cursor.write_all(&[0, 0, 0, 0]).unwrap();

    let root = {
        let mut ecx = EncodeContext {
            opaque: opaque::Encoder::new(&mut cursor),
            tcx: tcx,
            reexports: reexports,
            link_meta: link_meta,
            cstore: cstore,
            exported_symbols: exported_symbols,
            lazy_state: LazyState::NoNode,
            type_shorthands: Default::default(),
            predicate_shorthands: Default::default(),
        };

        // 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.
    let header = METADATA_HEADER.len();
    let pos = root.position;
    result[header + 0] = (pos >> 24) as u8;
    result[header + 1] = (pos >> 16) as u8;
    result[header + 2] = (pos >> 8) as u8;
    result[header + 3] = (pos >> 0) as u8;

    result
}
// NOTE(eddyb) The following comment was preserved for posterity, even
// though it's no longer relevant as EBML (which uses nested & tagged
// "documents") was replaced with a scheme that can't go out of bounds.
//
// And here we run into yet another obscure archive bug: in which metadata
// loaded from archives may have trailing garbage bytes. Awhile back one of
// our tests was failing sporadically on the OSX 64-bit builders (both nopt
// and opt) by having ebml generate an out-of-bounds panic when looking at
// metadata.
//
// Upon investigation it turned out that the metadata file inside of an rlib
// (and ar archive) was being corrupted. Some compilations would generate a
// metadata file which would end in a few extra bytes, while other
// compilations would not have these extra bytes appended to the end. These
// extra bytes were interpreted by ebml as an extra tag, so they ended up
// being interpreted causing the out-of-bounds.
//
// The root cause of why these extra bytes were appearing was never
// discovered, and in the meantime the solution we're employing is to insert
// the length of the metadata to the start of the metadata. Later on this
// will allow us to slice the metadata to the precise length that we just
// generated regardless of trailing bytes that end up in it.
NOTE(eddyb) The following comment was preserved for posterity, even
though it's no longer relevant as EBML (which uses nested & tagged
"documents") was replaced with a scheme that can't go out of bounds.

And here we run into yet another obscure archive bug: in which metadata
loaded from archives may have trailing garbage bytes. Awhile back one of
our tests was failing sporadically on the OSX 64-bit builders (both nopt
and opt) by having ebml generate an out-of-bounds panic when looking at
metadata.

Upon investigation it turned out that the metadata file inside of an rlib
(and ar archive) was being corrupted. Some compilations would generate a
metadata file which would end in a few extra bytes, while other
compilations would not have these extra bytes appended to the end. These
extra bytes were interpreted by ebml as an extra tag, so they ended up
being interpreted causing the out-of-bounds.

The root cause of why these extra bytes were appearing was never
discovered, and in the meantime the solution we're employing is to insert
the length of the metadata to the start of the metadata. Later on this
will allow us to slice the metadata to the precise length that we just
generated regardless of trailing bytes that end up in it.
NOTE ( eddyb ) The following comment was preserved for posterity even though it ' s no longer relevant as EBML ( which uses nested & tagged " documents " ) was replaced with a scheme that can ' t go out of bounds . And here we run into yet another obscure archive bug : in which metadata loaded from archives may have trailing garbage bytes . Awhile back one of our tests was failing sporadically on the OSX 64 - bit builders ( both nopt and opt ) by having ebml generate an out - of - bounds panic when looking at metadata . Upon investigation it turned out that the metadata file inside of an rlib ( and ar archive ) was being corrupted . Some compilations would generate a metadata file which would end in a few extra bytes while other compilations would not have these extra bytes appended to the end . These extra bytes were interpreted by ebml as an extra tag so they ended up being interpreted causing the out - of - bounds . The root cause of why these extra bytes were appearing was never discovered and in the meantime the solution we ' re employing is to insert the length of the metadata to the start of the metadata . Later on this will allow us to slice the metadata to the precise length that we just generated regardless of trailing bytes that end up in it .
pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                 cstore: &cstore::CStore,
                                 reexports: &def::ExportMap,
                                 link_meta: &LinkMeta,
                                 exported_symbols: &NodeSet)
                                 -> Vec<u8> {
    let mut cursor = Cursor::new(vec![]);
    cursor.write_all(METADATA_HEADER).unwrap();
    // Will be filed with the root position after encoding everything.
    cursor.write_all(&[0, 0, 0, 0]).unwrap();
    let root = {
        let mut ecx = EncodeContext {
            opaque: opaque::Encoder::new(&mut cursor),
            tcx: tcx,
            reexports: reexports,
            link_meta: link_meta,
            cstore: cstore,
            exported_symbols: exported_symbols,
            lazy_state: LazyState::NoNode,
            type_shorthands: Default::default(),
            predicate_shorthands: Default::default(),
        };
        // 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.
    let header = METADATA_HEADER.len();
    let pos = root.position;
    result[header + 0] = (pos >> 24) as u8;
    result[header + 1] = (pos >> 16) as u8;
    result[header + 2] = (pos >> 8) as u8;
    result[header + 3] = (pos >> 0) as u8;
    result
}
pub fn encode_metadata < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , cstore : & cstore :: CStore , reexports : & def :: ExportMap , link_meta : & LinkMeta , exported_symbols : & NodeSet ) -> Vec < u8 > { let mut cursor = Cursor :: new ( vec ! [ ] ) ; cursor . write_all ( METADATA_HEADER ) . unwrap ( ) ; // Will be filed with the root position after encoding everything. cursor . write_all ( & [ 0 , 0 , 0 , 0 ] ) . unwrap ( ) ; let root = { let mut ecx = EncodeContext { opaque : opaque :: Encoder :: new ( & mut cursor ) , tcx : tcx , reexports : reexports , link_meta : link_meta , cstore : cstore , exported_symbols : exported_symbols , lazy_state : LazyState :: NoNode , type_shorthands : Default :: default ( ) , predicate_shorthands : Default :: default ( ) , } ; // 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. let header = METADATA_HEADER . len ( ) ; let pos = root . position ; result [ header + 0 ] = ( pos >> 24 ) as u8 ; result [ header + 1 ] = ( pos >> 16 ) as u8 ; result [ header + 2 ] = ( pos >> 8 ) as u8 ; result [ header + 3 ] = ( pos >> 0 ) as u8 ; result }
NOTE(eddyb) The following comment was preserved for posterity, even
though it's no longer relevant as EBML (which uses nested & tagged
"documents") was replaced with a scheme that can't go out of bounds.
NOTE ( eddyb ) The following comment was preserved for posterity even though it ' s no longer relevant as EBML ( which uses nested & tagged " documents " ) was replaced with a scheme that can ' t go out of bounds .
tcx
TyCtxt<'a, 'tcx, 'tcx>
cstore
&cstore::CStore
reexports
&def::ExportMap
link_meta
&LinkMeta
exported_symbols
&NodeSet