1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
15 use rustc
::middle
::cstore
::{InlinedItemRef, LinkMeta}
;
16 use rustc
::middle
::cstore
::{LinkagePreference, NativeLibraryKind}
;
18 use rustc
::hir
::def_id
::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId}
;
19 use rustc
::middle
::dependency_format
::Linkage
;
20 use rustc
::middle
::lang_items
;
22 use rustc
::traits
::specialization_graph
;
23 use rustc
::ty
::{self, Ty, TyCtxt}
;
25 use rustc
::mir
::mir_map
::MirMap
;
26 use rustc
::session
::config
::{self, CrateTypeRustcMacro}
;
27 use rustc
::util
::nodemap
::{FnvHashMap, NodeSet}
;
29 use rustc_serialize
::{Encodable, Encoder, SpecializedEncoder, opaque}
;
32 use std
::io
::prelude
::*;
36 use syntax
::ast
::{self, CRATE_NODE_ID}
;
41 use rustc
::hir
::{self, PatKind}
;
42 use rustc
::hir
::intravisit
::Visitor
;
43 use rustc
::hir
::intravisit
;
45 use super::index_builder
::{FromId, IndexBuilder, Untracked}
;
47 pub struct EncodeContext
<'a
, 'tcx
: 'a
> {
48 opaque
: opaque
::Encoder
<'a
>,
49 pub tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
50 reexports
: &'a def
::ExportMap
,
51 link_meta
: &'a LinkMeta
,
52 cstore
: &'a cstore
::CStore
,
53 reachable
: &'a NodeSet
,
54 mir_map
: &'a MirMap
<'tcx
>,
56 lazy_state
: LazyState
,
57 type_shorthands
: FnvHashMap
<Ty
<'tcx
>, usize>,
58 predicate_shorthands
: FnvHashMap
<ty
::Predicate
<'tcx
>, usize>,
61 macro_rules
! encoder_methods
{
62 ($
($name
:ident($ty
:ty
);)*) => {
63 $
(fn $
name(&mut self, value
: $ty
) -> Result
<(), Self::Error
> {
64 self.opaque
.$
name(value
)
69 impl<'a
, 'tcx
> Encoder
for EncodeContext
<'a
, 'tcx
> {
70 type Error
= <opaque
::Encoder
<'a
> as Encoder
>::Error
;
72 fn emit_nil(&mut self) -> Result
<(), Self::Error
> {
97 impl<'a
, 'tcx
, T
> SpecializedEncoder
<Lazy
<T
>> for EncodeContext
<'a
, 'tcx
> {
98 fn specialized_encode(&mut self, lazy
: &Lazy
<T
>) -> Result
<(), Self::Error
> {
99 self.emit_lazy_distance(lazy
.position
, Lazy
::<T
>::min_size())
103 impl<'a
, 'tcx
, T
> SpecializedEncoder
<LazySeq
<T
>> for EncodeContext
<'a
, 'tcx
> {
104 fn specialized_encode(&mut self, seq
: &LazySeq
<T
>) -> Result
<(), Self::Error
> {
105 self.emit_usize(seq
.len
)?
;
109 self.emit_lazy_distance(seq
.position
, LazySeq
::<T
>::min_size(seq
.len
))
113 impl<'a
, 'tcx
> SpecializedEncoder
<Ty
<'tcx
>> for EncodeContext
<'a
, 'tcx
> {
114 fn specialized_encode(&mut self, ty
: &Ty
<'tcx
>) -> Result
<(), Self::Error
> {
115 self.encode_with_shorthand(ty
, &ty
.sty
, |ecx
| &mut ecx
.type_shorthands
)
119 impl<'a
, 'tcx
> SpecializedEncoder
<ty
::GenericPredicates
<'tcx
>> for EncodeContext
<'a
, 'tcx
> {
120 fn specialized_encode(&mut self, predicates
: &ty
::GenericPredicates
<'tcx
>)
121 -> Result
<(), Self::Error
> {
122 predicates
.parent
.encode(self)?
;
123 predicates
.predicates
.len().encode(self)?
;
124 for predicate
in &predicates
.predicates
{
125 self.encode_with_shorthand(predicate
, predicate
, |ecx
| &mut ecx
.predicate_shorthands
)?
131 impl<'a
, 'tcx
> EncodeContext
<'a
, 'tcx
> {
132 pub fn position(&self) -> usize {
133 self.opaque
.position()
136 fn emit_node
<F
: FnOnce(&mut Self, usize) -> R
, R
>(&mut self, f
: F
) -> R
{
137 assert_eq
!(self.lazy_state
, LazyState
::NoNode
);
138 let pos
= self.position();
139 self.lazy_state
= LazyState
::NodeStart(pos
);
140 let r
= f(self, pos
);
141 self.lazy_state
= LazyState
::NoNode
;
145 fn emit_lazy_distance(&mut self, position
: usize, min_size
: usize)
146 -> Result
<(), <Self as Encoder
>::Error
> {
147 let min_end
= position
+ min_size
;
148 let distance
= match self.lazy_state
{
149 LazyState
::NoNode
=> {
150 bug
!("emit_lazy_distance: outside of a metadata node")
152 LazyState
::NodeStart(start
) => {
153 assert
!(min_end
<= start
);
156 LazyState
::Previous(last_min_end
) => {
157 assert
!(last_min_end
<= position
);
158 position
- last_min_end
161 self.lazy_state
= LazyState
::Previous(min_end
);
162 self.emit_usize(distance
)
165 pub fn lazy
<T
: Encodable
>(&mut self, value
: &T
) -> Lazy
<T
> {
166 self.emit_node(|ecx
, pos
| {
167 value
.encode(ecx
).unwrap();
169 assert
!(pos
+ Lazy
::<T
>::min_size() <= ecx
.position());
170 Lazy
::with_position(pos
)
174 fn lazy_seq
<I
, T
>(&mut self, iter
: I
) -> LazySeq
<T
>
175 where I
: IntoIterator
<Item
=T
>, T
: Encodable
{
176 self.emit_node(|ecx
, pos
| {
177 let len
= iter
.into_iter().map(|value
| value
.encode(ecx
).unwrap()).count();
179 assert
!(pos
+ LazySeq
::<T
>::min_size(len
) <= ecx
.position());
180 LazySeq
::with_position_and_length(pos
, len
)
184 fn lazy_seq_ref
<'b
, I
, T
>(&mut self, iter
: I
) -> LazySeq
<T
>
185 where I
: IntoIterator
<Item
=&'b T
>, T
: 'b
+ Encodable
{
186 self.emit_node(|ecx
, pos
| {
187 let len
= iter
.into_iter().map(|value
| value
.encode(ecx
).unwrap()).count();
189 assert
!(pos
+ LazySeq
::<T
>::min_size(len
) <= ecx
.position());
190 LazySeq
::with_position_and_length(pos
, len
)
194 /// Encode the given value or a previously cached shorthand.
195 fn encode_with_shorthand
<T
, U
, M
>(&mut self, value
: &T
, variant
: &U
, map
: M
)
196 -> Result
<(), <Self as Encoder
>::Error
>
197 where M
: for<'b
> Fn(&'b
mut Self) -> &'b
mut FnvHashMap
<T
, usize>,
198 T
: Clone
+ Eq
+ Hash
,
200 let existing_shorthand
= map(self).get(value
).cloned();
201 if let Some(shorthand
) = existing_shorthand
{
202 return self.emit_usize(shorthand
);
205 let start
= self.position();
206 variant
.encode(self)?
;
207 let len
= self.position() - start
;
209 // The shorthand encoding uses the same usize as the
210 // discriminant, with an offset so they can't conflict.
211 let discriminant
= unsafe {
212 intrinsics
::discriminant_value(variant
)
214 assert
!(discriminant
< SHORTHAND_OFFSET
as u64);
215 let shorthand
= start
+ SHORTHAND_OFFSET
;
217 // Get the number of bits that leb128 could fit
218 // in the same space as the fully encoded type.
219 let leb128_bits
= len
* 7;
221 // Check that the shorthand is a not longer than the
222 // full encoding itself, i.e. it's an obvious win.
223 if leb128_bits
>= 64 || (shorthand
as u64) < (1 << leb128_bits
) {
224 map(self).insert(value
.clone(), shorthand
);
230 /// For every DefId that we create a metadata item for, we include a
231 /// serialized copy of its DefKey, which allows us to recreate a path.
232 fn encode_def_key(&mut self, def_id
: DefId
) -> Lazy
<hir
::map
::DefKey
> {
234 self.lazy(&tcx
.map
.def_key(def_id
))
237 fn encode_item_variances(&mut self, def_id
: DefId
) -> LazySeq
<ty
::Variance
> {
239 self.lazy_seq(tcx
.item_variances(def_id
).iter().cloned())
242 fn encode_item_type(&mut self, def_id
: DefId
) -> Lazy
<Ty
<'tcx
>> {
244 self.lazy(&tcx
.lookup_item_type(def_id
).ty
)
247 /// Encode data for the given variant of the given ADT. The
248 /// index of the variant is untracked: this is ok because we
249 /// will have to lookup the adt-def by its id, and that gives us
250 /// the right to access any information in the adt-def (including,
251 /// e.g., the length of the various vectors).
252 fn encode_enum_variant_info(&mut self,
253 (enum_did
, Untracked(index
)):
254 (DefId
, Untracked
<usize>)) -> Entry
<'tcx
> {
256 let def
= tcx
.lookup_adt_def(enum_did
);
257 let variant
= &def
.variants
[index
];
258 let def_id
= variant
.did
;
260 let data
= VariantData
{
262 disr
: variant
.disr_val
.to_u64_unchecked(),
266 let enum_id
= tcx
.map
.as_local_node_id(enum_did
).unwrap();
267 let enum_vis
= &tcx
.map
.expect_item(enum_id
).vis
;
270 kind
: EntryKind
::Variant(self.lazy(&data
)),
271 visibility
: enum_vis
.simplify(),
272 def_key
: self.encode_def_key(def_id
),
273 attributes
: self.encode_attributes(&tcx
.get_attrs(def_id
)),
274 children
: self.lazy_seq(variant
.fields
.iter().map(|f
| {
275 assert
!(f
.did
.is_local());
278 stability
: self.encode_stability(def_id
),
279 deprecation
: self.encode_deprecation(def_id
),
281 ty
: Some(self.encode_item_type(def_id
)),
282 inherent_impls
: LazySeq
::empty(),
283 variances
: LazySeq
::empty(),
284 generics
: Some(self.encode_generics(def_id
)),
285 predicates
: Some(self.encode_predicates(def_id
)),
292 fn encode_info_for_mod(&mut self,
293 FromId(id
, (md
, attrs
, vis
)):
294 FromId
<(&hir
::Mod
, &[ast
::Attribute
], &hir
::Visibility
)>)
297 let def_id
= tcx
.map
.local_def_id(id
);
300 reexports
: match self.reexports
.get(&id
) {
301 Some(exports
) if *vis
== hir
::Public
=> {
302 self.lazy_seq_ref(exports
)
304 _
=> LazySeq
::empty()
309 kind
: EntryKind
::Mod(self.lazy(&data
)),
310 visibility
: vis
.simplify(),
311 def_key
: self.encode_def_key(def_id
),
312 attributes
: self.encode_attributes(attrs
),
313 children
: self.lazy_seq(md
.item_ids
.iter().map(|item_id
| {
314 tcx
.map
.local_def_id(item_id
.id
).index
316 stability
: self.encode_stability(def_id
),
317 deprecation
: self.encode_deprecation(def_id
),
320 inherent_impls
: LazySeq
::empty(),
321 variances
: LazySeq
::empty(),
332 fn simplify(&self) -> ty
::Visibility
;
335 impl Visibility
for hir
::Visibility
{
336 fn simplify(&self) -> ty
::Visibility
{
337 if *self == hir
::Public
{
338 ty
::Visibility
::Public
340 ty
::Visibility
::PrivateExternal
345 impl Visibility
for ty
::Visibility
{
346 fn simplify(&self) -> ty
::Visibility
{
347 if *self == ty
::Visibility
::Public
{
348 ty
::Visibility
::Public
350 ty
::Visibility
::PrivateExternal
355 impl<'a
, 'b
, 'tcx
> IndexBuilder
<'a
, 'b
, 'tcx
> {
356 fn encode_fields(&mut self,
358 let def
= self.tcx
.lookup_adt_def(adt_def_id
);
359 for (variant_index
, variant
) in def
.variants
.iter().enumerate() {
360 for (field_index
, field
) in variant
.fields
.iter().enumerate() {
361 self.record(field
.did
,
362 EncodeContext
::encode_field
,
363 (adt_def_id
, Untracked((variant_index
, field_index
))));
369 impl<'a
, 'tcx
> EncodeContext
<'a
, 'tcx
> {
370 /// Encode data for the given field of the given variant of the
371 /// given ADT. The indices of the variant/field are untracked:
372 /// this is ok because we will have to lookup the adt-def by its
373 /// id, and that gives us the right to access any information in
374 /// the adt-def (including, e.g., the length of the various
376 fn encode_field(&mut self,
377 (adt_def_id
, Untracked((variant_index
, field_index
))):
378 (DefId
, Untracked
<(usize, usize)>)) -> Entry
<'tcx
> {
380 let variant
= &tcx
.lookup_adt_def(adt_def_id
).variants
[variant_index
];
381 let field
= &variant
.fields
[field_index
];
383 let def_id
= field
.did
;
384 let variant_id
= tcx
.map
.as_local_node_id(variant
.did
).unwrap();
385 let variant_data
= tcx
.map
.expect_variant_data(variant_id
);
388 kind
: EntryKind
::Field
,
389 visibility
: field
.vis
.simplify(),
390 def_key
: self.encode_def_key(def_id
),
391 attributes
: self.encode_attributes(&variant_data
.fields()[field_index
].attrs
),
392 children
: LazySeq
::empty(),
393 stability
: self.encode_stability(def_id
),
394 deprecation
: self.encode_deprecation(def_id
),
396 ty
: Some(self.encode_item_type(def_id
)),
397 inherent_impls
: LazySeq
::empty(),
398 variances
: LazySeq
::empty(),
399 generics
: Some(self.encode_generics(def_id
)),
400 predicates
: Some(self.encode_predicates(def_id
)),
407 fn encode_struct_ctor(&mut self, (adt_def_id
, def_id
): (DefId
, DefId
))
409 let variant
= self.tcx
.lookup_adt_def(adt_def_id
).struct_variant();
411 let data
= VariantData
{
413 disr
: variant
.disr_val
.to_u64_unchecked(),
414 struct_ctor
: Some(def_id
.index
)
418 kind
: EntryKind
::Struct(self.lazy(&data
)),
419 visibility
: ty
::Visibility
::Public
,
420 def_key
: self.encode_def_key(def_id
),
421 attributes
: LazySeq
::empty(),
422 children
: LazySeq
::empty(),
423 stability
: self.encode_stability(def_id
),
424 deprecation
: self.encode_deprecation(def_id
),
426 ty
: Some(self.encode_item_type(def_id
)),
427 inherent_impls
: LazySeq
::empty(),
428 variances
: LazySeq
::empty(),
429 generics
: Some(self.encode_generics(def_id
)),
430 predicates
: Some(self.encode_predicates(def_id
)),
437 fn encode_generics(&mut self, def_id
: DefId
) -> Lazy
<ty
::Generics
<'tcx
>> {
439 self.lazy(tcx
.lookup_generics(def_id
))
442 fn encode_predicates(&mut self, def_id
: DefId
) -> Lazy
<ty
::GenericPredicates
<'tcx
>> {
444 self.lazy(&tcx
.lookup_predicates(def_id
))
447 fn encode_info_for_trait_item(&mut self, def_id
: DefId
) -> Entry
<'tcx
> {
450 let node_id
= tcx
.map
.as_local_node_id(def_id
).unwrap();
451 let ast_item
= tcx
.map
.expect_trait_item(node_id
);
452 let trait_item
= tcx
.impl_or_trait_item(def_id
);
454 let container
= |has_body
| if has_body
{
455 AssociatedContainer
::TraitWithDefault
457 AssociatedContainer
::TraitRequired
460 let kind
= match trait_item
{
461 ty
::ConstTraitItem(ref associated_const
) => {
462 EntryKind
::AssociatedConst(container(associated_const
.has_value
))
464 ty
::MethodTraitItem(ref method_ty
) => {
465 let fn_data
= if let hir
::MethodTraitItem(ref sig
, _
) = ast_item
.node
{
467 constness
: hir
::Constness
::NotConst
,
468 arg_names
: self.encode_fn_arg_names(&sig
.decl
)
473 let data
= MethodData
{
475 container
: container(method_ty
.has_body
),
476 explicit_self
: self.lazy(&method_ty
.explicit_self
)
478 EntryKind
::Method(self.lazy(&data
))
480 ty
::TypeTraitItem(_
) => {
481 EntryKind
::AssociatedType(container(false))
487 visibility
: trait_item
.vis().simplify(),
488 def_key
: self.encode_def_key(def_id
),
489 attributes
: self.encode_attributes(&ast_item
.attrs
),
490 children
: LazySeq
::empty(),
491 stability
: self.encode_stability(def_id
),
492 deprecation
: self.encode_deprecation(def_id
),
494 ty
: match trait_item
{
495 ty
::ConstTraitItem(_
) |
496 ty
::MethodTraitItem(_
) => {
497 Some(self.encode_item_type(def_id
))
499 ty
::TypeTraitItem(ref associated_type
) => {
500 associated_type
.ty
.map(|ty
| self.lazy(&ty
))
503 inherent_impls
: LazySeq
::empty(),
504 variances
: LazySeq
::empty(),
505 generics
: Some(self.encode_generics(def_id
)),
506 predicates
: Some(self.encode_predicates(def_id
)),
508 ast
: if let ty
::ConstTraitItem(_
) = trait_item
{
509 let trait_def_id
= trait_item
.container().id();
510 Some(self.encode_inlined_item(InlinedItemRef
::TraitItem(trait_def_id
, ast_item
)))
514 mir
: self.encode_mir(def_id
)
518 fn encode_info_for_impl_item(&mut self, def_id
: DefId
) -> Entry
<'tcx
> {
519 let node_id
= self.tcx
.map
.as_local_node_id(def_id
).unwrap();
520 let ast_item
= self.tcx
.map
.expect_impl_item(node_id
);
521 let impl_item
= self.tcx
.impl_or_trait_item(def_id
);
522 let impl_def_id
= impl_item
.container().id();
524 let container
= match ast_item
.defaultness
{
525 hir
::Defaultness
::Default
=> AssociatedContainer
::ImplDefault
,
526 hir
::Defaultness
::Final
=> AssociatedContainer
::ImplFinal
529 let kind
= match impl_item
{
530 ty
::ConstTraitItem(_
) => {
531 EntryKind
::AssociatedConst(container
)
533 ty
::MethodTraitItem(ref method_ty
) => {
534 let fn_data
= if let hir
::ImplItemKind
::Method(ref sig
, _
) = ast_item
.node
{
536 constness
: sig
.constness
,
537 arg_names
: self.encode_fn_arg_names(&sig
.decl
)
542 let data
= MethodData
{
544 container
: container
,
545 explicit_self
: self.lazy(&method_ty
.explicit_self
)
547 EntryKind
::Method(self.lazy(&data
))
549 ty
::TypeTraitItem(_
) => {
550 EntryKind
::AssociatedType(container
)
554 let (ast
, mir
) = if let ty
::ConstTraitItem(_
) = impl_item
{
556 } else if let hir
::ImplItemKind
::Method(ref sig
, _
) = ast_item
.node
{
557 let generics
= self.tcx
.lookup_generics(def_id
);
558 let types
= generics
.parent_types
as usize + generics
.types
.len();
559 let needs_inline
= types
> 0 || attr
::requests_inline(&ast_item
.attrs
);
560 let is_const_fn
= sig
.constness
== hir
::Constness
::Const
;
561 (is_const_fn
, needs_inline
|| is_const_fn
)
568 visibility
: impl_item
.vis().simplify(),
569 def_key
: self.encode_def_key(def_id
),
570 attributes
: self.encode_attributes(&ast_item
.attrs
),
571 children
: LazySeq
::empty(),
572 stability
: self.encode_stability(def_id
),
573 deprecation
: self.encode_deprecation(def_id
),
575 ty
: match impl_item
{
576 ty
::ConstTraitItem(_
) |
577 ty
::MethodTraitItem(_
) => {
578 Some(self.encode_item_type(def_id
))
580 ty
::TypeTraitItem(ref associated_type
) => {
581 associated_type
.ty
.map(|ty
| self.lazy(&ty
))
584 inherent_impls
: LazySeq
::empty(),
585 variances
: LazySeq
::empty(),
586 generics
: Some(self.encode_generics(def_id
)),
587 predicates
: Some(self.encode_predicates(def_id
)),
590 Some(self.encode_inlined_item(InlinedItemRef
::ImplItem(impl_def_id
, ast_item
)))
595 self.encode_mir(def_id
)
602 fn encode_fn_arg_names(&mut self, decl
: &hir
::FnDecl
) -> LazySeq
<ast
::Name
> {
603 self.lazy_seq(decl
.inputs
.iter().map(|arg
| {
604 if let PatKind
::Binding(_
, ref path1
, _
) = arg
.pat
.node
{
607 syntax
::parse
::token
::intern("")
612 fn encode_mir(&mut self, def_id
: DefId
) -> Option
<Lazy
<mir
::repr
::Mir
<'tcx
>>> {
613 self.mir_map
.map
.get(&def_id
).map(|mir
| self.lazy(mir
))
616 // Encodes the inherent implementations of a structure, enumeration, or trait.
617 fn encode_inherent_implementations(&mut self, def_id
: DefId
) -> LazySeq
<DefIndex
> {
618 match self.tcx
.inherent_impls
.borrow().get(&def_id
) {
619 None
=> LazySeq
::empty(),
620 Some(implementations
) => {
621 self.lazy_seq(implementations
.iter().map(|&def_id
| {
622 assert
!(def_id
.is_local());
629 fn encode_stability(&mut self, def_id
: DefId
) -> Option
<Lazy
<attr
::Stability
>> {
630 self.tcx
.lookup_stability(def_id
).map(|stab
| self.lazy(stab
))
633 fn encode_deprecation(&mut self, def_id
: DefId
) -> Option
<Lazy
<attr
::Deprecation
>> {
634 self.tcx
.lookup_deprecation(def_id
).map(|depr
| self.lazy(&depr
))
637 fn encode_info_for_item(&mut self,
638 (def_id
, item
): (DefId
, &hir
::Item
)) -> Entry
<'tcx
> {
641 debug
!("encoding info for item at {}",
642 tcx
.sess
.codemap().span_to_string(item
.span
));
644 let kind
= match item
.node
{
645 hir
::ItemStatic(_
, hir
::MutMutable
, _
) => EntryKind
::MutStatic
,
646 hir
::ItemStatic(_
, hir
::MutImmutable
, _
) => EntryKind
::ImmStatic
,
647 hir
::ItemConst(..) => EntryKind
::Const
,
648 hir
::ItemFn(ref decl
, _
, constness
, ..) => {
650 constness
: constness
,
651 arg_names
: self.encode_fn_arg_names(&decl
)
654 EntryKind
::Fn(self.lazy(&data
))
656 hir
::ItemMod(ref m
) => {
657 return self.encode_info_for_mod(FromId(item
.id
, (m
, &item
.attrs
, &item
.vis
)));
659 hir
::ItemForeignMod(_
) => EntryKind
::ForeignMod
,
660 hir
::ItemTy(..) => EntryKind
::Type
,
661 hir
::ItemEnum(..) => EntryKind
::Enum
,
662 hir
::ItemStruct(ref struct_def
, _
) => {
663 let variant
= tcx
.lookup_adt_def(def_id
).struct_variant();
665 /* Encode def_ids for each field and method
666 for methods, write all the stuff get_trait_method
668 let struct_ctor
= if !struct_def
.is_struct() {
669 Some(tcx
.map
.local_def_id(struct_def
.id()).index
)
673 EntryKind
::Struct(self.lazy(&VariantData
{
675 disr
: variant
.disr_val
.to_u64_unchecked(),
676 struct_ctor
: struct_ctor
679 hir
::ItemUnion(..) => {
680 let variant
= tcx
.lookup_adt_def(def_id
).struct_variant();
682 EntryKind
::Union(self.lazy(&VariantData
{
684 disr
: variant
.disr_val
.to_u64_unchecked(),
688 hir
::ItemDefaultImpl(..) => {
689 let data
= ImplData
{
690 polarity
: hir
::ImplPolarity
::Positive
,
692 coerce_unsized_kind
: None
,
693 trait_ref
: tcx
.impl_trait_ref(def_id
).map(|trait_ref
| self.lazy(&trait_ref
))
696 EntryKind
::DefaultImpl(self.lazy(&data
))
698 hir
::ItemImpl(_
, polarity
, ..) => {
699 let trait_ref
= tcx
.impl_trait_ref(def_id
);
700 let parent
= if let Some(trait_ref
) = trait_ref
{
701 let trait_def
= tcx
.lookup_trait_def(trait_ref
.def_id
);
702 trait_def
.ancestors(def_id
).skip(1).next().and_then(|node
| {
704 specialization_graph
::Node
::Impl(parent
) => Some(parent
),
712 let data
= ImplData
{
715 coerce_unsized_kind
: tcx
.custom_coerce_unsized_kinds
.borrow()
716 .get(&def_id
).cloned(),
717 trait_ref
: trait_ref
.map(|trait_ref
| self.lazy(&trait_ref
))
720 EntryKind
::Impl(self.lazy(&data
))
722 hir
::ItemTrait(..) => {
723 let trait_def
= tcx
.lookup_trait_def(def_id
);
724 let data
= TraitData
{
725 unsafety
: trait_def
.unsafety
,
726 paren_sugar
: trait_def
.paren_sugar
,
727 has_default_impl
: tcx
.trait_has_default_impl(def_id
),
728 trait_ref
: self.lazy(&trait_def
.trait_ref
),
729 super_predicates
: self.lazy(&tcx
.lookup_super_predicates(def_id
))
732 EntryKind
::Trait(self.lazy(&data
))
734 hir
::ItemExternCrate(_
) | hir
::ItemUse(_
) => {
735 bug
!("cannot encode info for item {:?}", item
)
741 visibility
: item
.vis
.simplify(),
742 def_key
: self.encode_def_key(def_id
),
743 attributes
: self.encode_attributes(&item
.attrs
),
744 children
: match item
.node
{
745 hir
::ItemForeignMod(ref fm
) => {
746 self.lazy_seq(fm
.items
.iter().map(|foreign_item
| {
747 tcx
.map
.local_def_id(foreign_item
.id
).index
750 hir
::ItemEnum(..) => {
751 let def
= self.tcx
.lookup_adt_def(def_id
);
752 self.lazy_seq(def
.variants
.iter().map(|v
| {
753 assert
!(v
.did
.is_local());
757 hir
::ItemStruct(..) |
758 hir
::ItemUnion(..) => {
759 let def
= self.tcx
.lookup_adt_def(def_id
);
760 self.lazy_seq(def
.struct_variant().fields
.iter().map(|f
| {
761 assert
!(f
.did
.is_local());
766 hir
::ItemTrait(..) => {
767 self.lazy_seq(tcx
.impl_or_trait_items(def_id
).iter().map(|&def_id
| {
768 assert
!(def_id
.is_local());
772 _
=> LazySeq
::empty()
774 stability
: self.encode_stability(def_id
),
775 deprecation
: self.encode_deprecation(def_id
),
777 ty
: match item
.node
{
778 hir
::ItemStatic(..) |
783 hir
::ItemStruct(..) |
785 hir
::ItemImpl(..) => {
786 Some(self.encode_item_type(def_id
))
790 inherent_impls
: self.encode_inherent_implementations(def_id
),
791 variances
: match item
.node
{
793 hir
::ItemStruct(..) |
795 hir
::ItemTrait(..) => {
796 self.encode_item_variances(def_id
)
798 _
=> LazySeq
::empty()
800 generics
: match item
.node
{
801 hir
::ItemStatic(..) |
806 hir
::ItemStruct(..) |
809 hir
::ItemTrait(..) => {
810 Some(self.encode_generics(def_id
))
814 predicates
: match item
.node
{
815 hir
::ItemStatic(..) |
820 hir
::ItemStruct(..) |
823 hir
::ItemTrait(..) => {
824 Some(self.encode_predicates(def_id
))
829 ast
: match item
.node
{
831 hir
::ItemFn(_
, _
, hir
::Constness
::Const
, ..) => {
832 Some(self.encode_inlined_item(InlinedItemRef
::Item(def_id
, item
)))
836 mir
: match item
.node
{
837 hir
::ItemConst(..) => {
838 self.encode_mir(def_id
)
840 hir
::ItemFn(_
, _
, constness
, _
, ref generics
, _
) => {
841 let tps_len
= generics
.ty_params
.len();
842 let needs_inline
= tps_len
> 0 || attr
::requests_inline(&item
.attrs
);
843 if needs_inline
|| constness
== hir
::Constness
::Const
{
844 self.encode_mir(def_id
)
855 impl<'a
, 'b
, 'tcx
> IndexBuilder
<'a
, 'b
, 'tcx
> {
856 /// In some cases, along with the item itself, we also
857 /// encode some sub-items. Usually we want some info from the item
858 /// so it's easier to do that here then to wait until we would encounter
859 /// normally in the visitor walk.
860 fn encode_addl_info_for_item(&mut self,
862 let def_id
= self.tcx
.map
.local_def_id(item
.id
);
864 hir
::ItemStatic(..) |
868 hir
::ItemForeignMod(..) |
869 hir
::ItemExternCrate(..) |
871 hir
::ItemDefaultImpl(..) |
873 // no sub-item recording needed in these cases
875 hir
::ItemEnum(..) => {
876 self.encode_fields(def_id
);
878 let def
= self.tcx
.lookup_adt_def(def_id
);
879 for (i
, variant
) in def
.variants
.iter().enumerate() {
880 self.record(variant
.did
,
881 EncodeContext
::encode_enum_variant_info
,
882 (def_id
, Untracked(i
)));
885 hir
::ItemStruct(ref struct_def
, _
) => {
886 self.encode_fields(def_id
);
888 // If this is a tuple-like struct, encode the type of the constructor.
889 match self.tcx
.lookup_adt_def(def_id
).struct_variant().kind
{
890 ty
::VariantKind
::Struct
=> {
891 // no value for structs like struct Foo { ... }
893 ty
::VariantKind
::Tuple
| ty
::VariantKind
::Unit
=> {
894 // there is a value for structs like `struct
895 // Foo()` and `struct Foo`
896 let ctor_def_id
= self.tcx
.map
.local_def_id(struct_def
.id());
897 self.record(ctor_def_id
,
898 EncodeContext
::encode_struct_ctor
,
899 (def_id
, ctor_def_id
));
903 hir
::ItemUnion(..) => {
904 self.encode_fields(def_id
);
906 hir
::ItemImpl(..) => {
907 for &trait_item_def_id
in &self.tcx
.impl_or_trait_items(def_id
)[..] {
908 self.record(trait_item_def_id
,
909 EncodeContext
::encode_info_for_impl_item
,
913 hir
::ItemTrait(..) => {
914 for &item_def_id
in &self.tcx
.impl_or_trait_items(def_id
)[..] {
915 self.record(item_def_id
,
916 EncodeContext
::encode_info_for_trait_item
,
924 impl<'a
, 'tcx
> EncodeContext
<'a
, 'tcx
> {
925 fn encode_info_for_foreign_item(&mut self,
926 (def_id
, nitem
): (DefId
, &hir
::ForeignItem
))
930 debug
!("writing foreign item {}", tcx
.node_path_str(nitem
.id
));
932 let kind
= match nitem
.node
{
933 hir
::ForeignItemFn(ref fndecl
, _
) => {
935 constness
: hir
::Constness
::NotConst
,
936 arg_names
: self.encode_fn_arg_names(&fndecl
)
938 EntryKind
::ForeignFn(self.lazy(&data
))
940 hir
::ForeignItemStatic(_
, true) => EntryKind
::ForeignMutStatic
,
941 hir
::ForeignItemStatic(_
, false) => EntryKind
::ForeignImmStatic
946 visibility
: nitem
.vis
.simplify(),
947 def_key
: self.encode_def_key(def_id
),
948 attributes
: self.encode_attributes(&nitem
.attrs
),
949 children
: LazySeq
::empty(),
950 stability
: self.encode_stability(def_id
),
951 deprecation
: self.encode_deprecation(def_id
),
953 ty
: Some(self.encode_item_type(def_id
)),
954 inherent_impls
: LazySeq
::empty(),
955 variances
: LazySeq
::empty(),
956 generics
: Some(self.encode_generics(def_id
)),
957 predicates
: Some(self.encode_predicates(def_id
)),
965 struct EncodeVisitor
<'a
, 'b
: 'a
, 'tcx
: 'b
> {
966 index
: IndexBuilder
<'a
, 'b
, 'tcx
>,
969 impl<'a
, 'b
, 'tcx
> Visitor
<'tcx
> for EncodeVisitor
<'a
, 'b
, 'tcx
> {
970 fn visit_expr(&mut self, ex
: &'tcx hir
::Expr
) {
971 intravisit
::walk_expr(self, ex
);
972 self.index
.encode_info_for_expr(ex
);
974 fn visit_item(&mut self, item
: &'tcx hir
::Item
) {
975 intravisit
::walk_item(self, item
);
976 let def_id
= self.index
.tcx
.map
.local_def_id(item
.id
);
978 hir
::ItemExternCrate(_
) | hir
::ItemUse(_
) => (), // ignore these
979 _
=> self.index
.record(def_id
,
980 EncodeContext
::encode_info_for_item
,
983 self.index
.encode_addl_info_for_item(item
);
985 fn visit_foreign_item(&mut self, ni
: &'tcx hir
::ForeignItem
) {
986 intravisit
::walk_foreign_item(self, ni
);
987 let def_id
= self.index
.tcx
.map
.local_def_id(ni
.id
);
988 self.index
.record(def_id
,
989 EncodeContext
::encode_info_for_foreign_item
,
992 fn visit_ty(&mut self, ty
: &'tcx hir
::Ty
) {
993 intravisit
::walk_ty(self, ty
);
994 self.index
.encode_info_for_ty(ty
);
998 impl<'a
, 'b
, 'tcx
> IndexBuilder
<'a
, 'b
, 'tcx
> {
999 fn encode_info_for_ty(&mut self, ty
: &hir
::Ty
) {
1000 if let hir
::TyImplTrait(_
) = ty
.node
{
1001 let def_id
= self.tcx
.map
.local_def_id(ty
.id
);
1003 EncodeContext
::encode_info_for_anon_ty
,
1008 fn encode_info_for_expr(&mut self, expr
: &hir
::Expr
) {
1010 hir
::ExprClosure(..) => {
1011 let def_id
= self.tcx
.map
.local_def_id(expr
.id
);
1013 EncodeContext
::encode_info_for_closure
,
1021 impl<'a
, 'tcx
> EncodeContext
<'a
, 'tcx
> {
1022 fn encode_info_for_anon_ty(&mut self, def_id
: DefId
) -> Entry
<'tcx
> {
1024 kind
: EntryKind
::Type
,
1025 visibility
: ty
::Visibility
::Public
,
1026 def_key
: self.encode_def_key(def_id
),
1027 attributes
: LazySeq
::empty(),
1028 children
: LazySeq
::empty(),
1032 ty
: Some(self.encode_item_type(def_id
)),
1033 inherent_impls
: LazySeq
::empty(),
1034 variances
: LazySeq
::empty(),
1035 generics
: Some(self.encode_generics(def_id
)),
1036 predicates
: Some(self.encode_predicates(def_id
)),
1043 fn encode_info_for_closure(&mut self, def_id
: DefId
) -> Entry
<'tcx
> {
1046 let data
= ClosureData
{
1047 kind
: tcx
.closure_kind(def_id
),
1048 ty
: self.lazy(&tcx
.tables
.borrow().closure_tys
[&def_id
])
1052 kind
: EntryKind
::Closure(self.lazy(&data
)),
1053 visibility
: ty
::Visibility
::Public
,
1054 def_key
: self.encode_def_key(def_id
),
1055 attributes
: self.encode_attributes(&tcx
.get_attrs(def_id
)),
1056 children
: LazySeq
::empty(),
1061 inherent_impls
: LazySeq
::empty(),
1062 variances
: LazySeq
::empty(),
1067 mir
: self.encode_mir(def_id
)
1071 fn encode_info_for_items(&mut self) -> Index
{
1072 let krate
= self.tcx
.map
.krate();
1073 let mut index
= IndexBuilder
::new(self);
1074 index
.record(DefId
::local(CRATE_DEF_INDEX
),
1075 EncodeContext
::encode_info_for_mod
,
1076 FromId(CRATE_NODE_ID
, (&krate
.module
, &krate
.attrs
, &hir
::Public
)));
1077 let mut visitor
= EncodeVisitor
{
1080 krate
.visit_all_items(&mut visitor
);
1081 visitor
.index
.into_items()
1084 fn encode_attributes(&mut self, attrs
: &[ast
::Attribute
]) -> LazySeq
<ast
::Attribute
> {
1085 self.lazy_seq_ref(attrs
)
1088 fn encode_crate_deps(&mut self) -> LazySeq
<CrateDep
> {
1089 fn get_ordered_deps(cstore
: &cstore
::CStore
)
1090 -> Vec
<(CrateNum
, Rc
<cstore
::CrateMetadata
>)> {
1091 // Pull the cnums and name,vers,hash out of cstore
1092 let mut deps
= Vec
::new();
1093 cstore
.iter_crate_data(|cnum
, val
| {
1094 deps
.push((cnum
, val
.clone()));
1098 deps
.sort_by(|kv1
, kv2
| kv1
.0
.cmp(&kv2
.0
));
1100 // Sanity-check the crate numbers
1101 let mut expected_cnum
= 1;
1102 for &(n
, _
) in &deps
{
1103 assert_eq
!(n
, CrateNum
::new(expected_cnum
));
1110 // We're just going to write a list of crate 'name-hash-version's, with
1111 // the assumption that they are numbered 1 to n.
1112 // FIXME (#2166): This is not nearly enough to support correct versioning
1113 // but is enough to get transitive crate dependencies working.
1114 let deps
= get_ordered_deps(self.cstore
);
1115 self.lazy_seq(deps
.iter().map(|&(_
, ref dep
)| {
1117 name
: syntax
::parse
::token
::intern(dep
.name()),
1119 explicitly_linked
: dep
.explicitly_linked
.get()
1124 fn encode_lang_items(&mut self)
1125 -> (LazySeq
<(DefIndex
, usize)>, LazySeq
<lang_items
::LangItem
>) {
1127 let lang_items
= tcx
.lang_items
.items().iter();
1128 (self.lazy_seq(lang_items
.enumerate().filter_map(|(i
, &opt_def_id
)| {
1129 if let Some(def_id
) = opt_def_id
{
1130 if def_id
.is_local() {
1131 return Some((def_id
.index
, i
));
1135 })), self.lazy_seq_ref(&tcx
.lang_items
.missing
))
1138 fn encode_native_libraries(&mut self) -> LazySeq
<(NativeLibraryKind
, String
)> {
1139 let used_libraries
= self.tcx
.sess
.cstore
.used_libraries();
1140 self.lazy_seq(used_libraries
.into_iter().filter_map(|(lib
, kind
)| {
1142 cstore
::NativeStatic
=> None
, // these libraries are not propagated
1143 cstore
::NativeFramework
| cstore
::NativeUnknown
=> {
1150 fn encode_codemap(&mut self) -> LazySeq
<syntax_pos
::FileMap
> {
1151 let codemap
= self.tcx
.sess
.codemap();
1152 let all_filemaps
= codemap
.files
.borrow();
1153 self.lazy_seq_ref(all_filemaps
.iter().filter(|filemap
| {
1154 // No need to export empty filemaps, as they can't contain spans
1155 // that need translation.
1156 // Also no need to re-export imported filemaps, as any downstream
1157 // crate will import them from their original source.
1158 !filemap
.lines
.borrow().is_empty() && !filemap
.is_imported()
1159 }).map(|filemap
| &**filemap
))
1162 /// Serialize the text of the exported macros
1163 fn encode_macro_defs(&mut self) -> LazySeq
<MacroDef
> {
1165 self.lazy_seq(tcx
.map
.krate().exported_macros
.iter().map(|def
| {
1168 attrs
: def
.attrs
.to_vec(),
1170 body
: ::syntax
::print
::pprust
::tts_to_string(&def
.body
)
1176 struct ImplVisitor
<'a
, 'tcx
:'a
> {
1177 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1178 impls
: FnvHashMap
<DefId
, Vec
<DefIndex
>>
1181 impl<'a
, 'tcx
, 'v
> Visitor
<'v
> for ImplVisitor
<'a
, 'tcx
> {
1182 fn visit_item(&mut self, item
: &hir
::Item
) {
1183 if let hir
::ItemImpl(..) = item
.node
{
1184 let impl_id
= self.tcx
.map
.local_def_id(item
.id
);
1185 if let Some(trait_ref
) = self.tcx
.impl_trait_ref(impl_id
) {
1186 self.impls
.entry(trait_ref
.def_id
)
1188 .push(impl_id
.index
);
1194 impl<'a
, 'tcx
> EncodeContext
<'a
, 'tcx
> {
1195 /// Encodes an index, mapping each trait to its (local) implementations.
1196 fn encode_impls(&mut self) -> LazySeq
<TraitImpls
> {
1197 let mut visitor
= ImplVisitor
{
1201 self.tcx
.map
.krate().visit_all_items(&mut visitor
);
1203 let all_impls
: Vec
<_
> = visitor
.impls
.into_iter().map(|(trait_def_id
, impls
)| {
1205 trait_id
: (trait_def_id
.krate
.as_u32(), trait_def_id
.index
),
1206 impls
: self.lazy_seq(impls
)
1210 self.lazy_seq(all_impls
)
1213 // Encodes all reachable symbols in this crate into the metadata.
1215 // This pass is seeded off the reachability list calculated in the
1216 // middle::reachable module but filters out items that either don't have a
1217 // symbol associated with them (they weren't translated) or if they're an FFI
1218 // definition (as that's not defined in this crate).
1219 fn encode_reachable(&mut self) -> LazySeq
<DefIndex
> {
1220 let reachable
= self.reachable
;
1222 self.lazy_seq(reachable
.iter().map(|&id
| tcx
.map
.local_def_id(id
).index
))
1225 fn encode_dylib_dependency_formats(&mut self) -> LazySeq
<Option
<LinkagePreference
>> {
1226 match self.tcx
.sess
.dependency_formats
.borrow().get(&config
::CrateTypeDylib
) {
1228 self.lazy_seq(arr
.iter().map(|slot
| {
1230 Linkage
::NotLinked
|
1231 Linkage
::IncludedFromDylib
=> None
,
1233 Linkage
::Dynamic
=> Some(LinkagePreference
::RequireDynamic
),
1234 Linkage
::Static
=> Some(LinkagePreference
::RequireStatic
),
1238 None
=> LazySeq
::empty()
1242 fn encode_crate_root(&mut self) -> Lazy
<CrateRoot
> {
1243 let mut i
= self.position();
1244 let crate_deps
= self.encode_crate_deps();
1245 let dylib_dependency_formats
= self.encode_dylib_dependency_formats();
1246 let dep_bytes
= self.position() - i
;
1248 // Encode the language items.
1249 i
= self.position();
1250 let (lang_items
, lang_items_missing
) = self.encode_lang_items();
1251 let lang_item_bytes
= self.position() - i
;
1253 // Encode the native libraries used
1254 i
= self.position();
1255 let native_libraries
= self.encode_native_libraries();
1256 let native_lib_bytes
= self.position() - i
;
1259 i
= self.position();
1260 let codemap
= self.encode_codemap();
1261 let codemap_bytes
= self.position() - i
;
1263 // Encode macro definitions
1264 i
= self.position();
1265 let macro_defs
= self.encode_macro_defs();
1266 let macro_defs_bytes
= self.position() - i
;
1268 // Encode the def IDs of impls, for coherence checking.
1269 i
= self.position();
1270 let impls
= self.encode_impls();
1271 let impl_bytes
= self.position() - i
;
1273 // Encode reachability info.
1274 i
= self.position();
1275 let reachable_ids
= self.encode_reachable();
1276 let reachable_bytes
= self.position() - i
;
1278 // Encode and index the items.
1279 i
= self.position();
1280 let items
= self.encode_info_for_items();
1281 let item_bytes
= self.position() - i
;
1283 i
= self.position();
1284 let index
= items
.write_index(&mut self.opaque
.cursor
);
1285 let index_bytes
= self.position() - i
;
1288 let link_meta
= self.link_meta
;
1289 let is_rustc_macro
= tcx
.sess
.crate_types
.borrow().contains(&CrateTypeRustcMacro
);
1290 let root
= self.lazy(&CrateRoot
{
1291 rustc_version
: RUSTC_VERSION
.to_string(),
1292 name
: link_meta
.crate_name
.clone(),
1293 triple
: tcx
.sess
.opts
.target_triple
.clone(),
1294 hash
: link_meta
.crate_hash
,
1295 disambiguator
: tcx
.sess
.local_crate_disambiguator().to_string(),
1296 panic_strategy
: tcx
.sess
.opts
.cg
.panic
.clone(),
1297 plugin_registrar_fn
: tcx
.sess
.plugin_registrar_fn
.get().map(|id
| {
1298 tcx
.map
.local_def_id(id
).index
1300 macro_derive_registrar
: if is_rustc_macro
{
1301 let id
= tcx
.sess
.derive_registrar_fn
.get().unwrap();
1302 Some(tcx
.map
.local_def_id(id
).index
)
1307 crate_deps
: crate_deps
,
1308 dylib_dependency_formats
: dylib_dependency_formats
,
1309 lang_items
: lang_items
,
1310 lang_items_missing
: lang_items_missing
,
1311 native_libraries
: native_libraries
,
1313 macro_defs
: macro_defs
,
1315 reachable_ids
: reachable_ids
,
1319 let total_bytes
= self.position();
1321 if self.tcx
.sess
.meta_stats() {
1322 let mut zero_bytes
= 0;
1323 for e
in self.opaque
.cursor
.get_ref() {
1329 println
!("metadata stats:");
1330 println
!(" dep bytes: {}", dep_bytes
);
1331 println
!(" lang item bytes: {}", lang_item_bytes
);
1332 println
!(" native bytes: {}", native_lib_bytes
);
1333 println
!(" codemap bytes: {}", codemap_bytes
);
1334 println
!(" macro def bytes: {}", macro_defs_bytes
);
1335 println
!(" impl bytes: {}", impl_bytes
);
1336 println
!(" reachable bytes: {}", reachable_bytes
);
1337 println
!(" item bytes: {}", item_bytes
);
1338 println
!(" index bytes: {}", index_bytes
);
1339 println
!(" zero bytes: {}", zero_bytes
);
1340 println
!(" total bytes: {}", total_bytes
);
1347 // NOTE(eddyb) The following comment was preserved for posterity, even
1348 // though it's no longer relevant as EBML (which uses nested & tagged
1349 // "documents") was replaced with a scheme that can't go out of bounds.
1351 // And here we run into yet another obscure archive bug: in which metadata
1352 // loaded from archives may have trailing garbage bytes. Awhile back one of
1353 // our tests was failing sporadically on the OSX 64-bit builders (both nopt
1354 // and opt) by having ebml generate an out-of-bounds panic when looking at
1357 // Upon investigation it turned out that the metadata file inside of an rlib
1358 // (and ar archive) was being corrupted. Some compilations would generate a
1359 // metadata file which would end in a few extra bytes, while other
1360 // compilations would not have these extra bytes appended to the end. These
1361 // extra bytes were interpreted by ebml as an extra tag, so they ended up
1362 // being interpreted causing the out-of-bounds.
1364 // The root cause of why these extra bytes were appearing was never
1365 // discovered, and in the meantime the solution we're employing is to insert
1366 // the length of the metadata to the start of the metadata. Later on this
1367 // will allow us to slice the metadata to the precise length that we just
1368 // generated regardless of trailing bytes that end up in it.
1370 pub fn encode_metadata
<'a
, 'tcx
>(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
1371 cstore
: &cstore
::CStore
,
1372 reexports
: &def
::ExportMap
,
1373 link_meta
: &LinkMeta
,
1374 reachable
: &NodeSet
,
1375 mir_map
: &MirMap
<'tcx
>) -> Vec
<u8> {
1376 let mut cursor
= Cursor
::new(vec
![]);
1377 cursor
.write_all(METADATA_HEADER
).unwrap();
1379 // Will be filed with the root position after encoding everything.
1380 cursor
.write_all(&[0, 0, 0, 0]).unwrap();
1382 let root
= EncodeContext
{
1383 opaque
: opaque
::Encoder
::new(&mut cursor
),
1385 reexports
: reexports
,
1386 link_meta
: link_meta
,
1388 reachable
: reachable
,
1390 lazy_state
: LazyState
::NoNode
,
1391 type_shorthands
: Default
::default(),
1392 predicate_shorthands
: Default
::default()
1393 }.encode_crate_root();
1394 let mut result
= cursor
.into_inner();
1396 // Encode the root position.
1397 let header
= METADATA_HEADER
.len();
1398 let pos
= root
.position
;
1399 result
[header
+ 0] = (pos
>> 24) as u8;
1400 result
[header
+ 1] = (pos
>> 16) as u8;
1401 result
[header
+ 2] = (pos
>> 8) as u8;
1402 result
[header
+ 3] = (pos
>> 0) as u8;