use rustc::mir;
use rustc::traits::specialization_graph;
use rustc::ty::{self, Ty, TyCtxt, ReprOptions};
+use rustc::ty::codec::{self as ty_codec, TyEncoder};
use rustc::session::config::{self, CrateTypeProcMacro};
use rustc::util::nodemap::{FxHashMap, NodeSet};
use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque};
-use std::hash::Hash;
-use std::intrinsics;
use std::io::prelude::*;
use std::io::Cursor;
use std::path::Path;
}
}
+impl<'a, 'tcx> SpecializedEncoder<CrateNum> for EncodeContext<'a, 'tcx> {
+ #[inline]
+ fn specialized_encode(&mut self, cnum: &CrateNum) -> Result<(), Self::Error> {
+ self.emit_u32(cnum.as_u32())
+ }
+}
+
+impl<'a, 'tcx> SpecializedEncoder<DefId> for EncodeContext<'a, 'tcx> {
+ #[inline]
+ fn specialized_encode(&mut self, def_id: &DefId) -> Result<(), Self::Error> {
+ let DefId {
+ krate,
+ index,
+ } = *def_id;
+
+ krate.encode(self)?;
+ index.encode(self)
+ }
+}
+
+impl<'a, 'tcx> SpecializedEncoder<DefIndex> for EncodeContext<'a, 'tcx> {
+ #[inline]
+ fn specialized_encode(&mut self, def_index: &DefIndex) -> Result<(), Self::Error> {
+ self.emit_u32(def_index.as_u32())
+ }
+}
+
impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> {
fn specialized_encode(&mut self, ty: &Ty<'tcx>) -> Result<(), Self::Error> {
- self.encode_with_shorthand(ty, &ty.sty, |ecx| &mut ecx.type_shorthands)
+ ty_codec::encode_with_shorthand(self, ty, |ecx| &mut ecx.type_shorthands)
}
}
fn specialized_encode(&mut self,
predicates: &ty::GenericPredicates<'tcx>)
-> Result<(), Self::Error> {
- predicates.parent.encode(self)?;
- predicates.predicates.len().encode(self)?;
- for predicate in &predicates.predicates {
- self.encode_with_shorthand(predicate, predicate, |ecx| &mut ecx.predicate_shorthands)?
- }
- Ok(())
+ ty_codec::encode_predicates(self, predicates, |ecx| &mut ecx.predicate_shorthands)
}
}
-impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
-
- pub fn position(&self) -> usize {
+impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
+ fn position(&self) -> usize {
self.opaque.position()
}
+}
+
+impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn emit_node<F: FnOnce(&mut Self, usize) -> R, R>(&mut self, f: F) -> R {
assert_eq!(self.lazy_state, LazyState::NoNode);
})
}
- /// Encode the given value or a previously cached shorthand.
- fn encode_with_shorthand<T, U, M>(&mut self,
- value: &T,
- variant: &U,
- map: M)
- -> Result<(), <Self as Encoder>::Error>
- where M: for<'b> Fn(&'b mut Self) -> &'b mut FxHashMap<T, usize>,
- T: Clone + Eq + Hash,
- U: Encodable
- {
- let existing_shorthand = map(self).get(value).cloned();
- if let Some(shorthand) = existing_shorthand {
- return self.emit_usize(shorthand);
- }
-
- let start = self.position();
- variant.encode(self)?;
- let len = self.position() - start;
-
- // The shorthand encoding uses the same usize as the
- // discriminant, with an offset so they can't conflict.
- let discriminant = unsafe { intrinsics::discriminant_value(variant) };
- assert!(discriminant < SHORTHAND_OFFSET as u64);
- let shorthand = start + SHORTHAND_OFFSET;
-
- // Get the number of bits that leb128 could fit
- // in the same space as the fully encoded type.
- let leb128_bits = len * 7;
-
- // Check that the shorthand is a not longer than the
- // full encoding itself, i.e. it's an obvious win.
- if leb128_bits >= 64 || (shorthand as u64) < (1 << leb128_bits) {
- map(self).insert(value.clone(), shorthand);
- }
-
- Ok(())
- }
-
// Encodes something that corresponds to a single DepNode::GlobalMetaData
// and registers the Fingerprint in the `metadata_hashes` map.
pub fn tracked<'x, DATA, R>(&'x mut self,
if let Some(fingerprint) = fingerprint {
this.metadata_hashes.hashes.push(EncodedMetadataHash {
- def_index,
+ def_index: def_index.as_u32(),
hash: fingerprint,
})
}
let total_bytes = self.position();
self.metadata_hashes.hashes.push(EncodedMetadataHash {
- def_index: global_metadata_def_index(GlobalMetaDataKind::Krate),
+ def_index: global_metadata_def_index(GlobalMetaDataKind::Krate).as_u32(),
hash: Fingerprint::from_smaller_hash(link_meta.crate_hash.as_u64())
});
fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> {
debug!("IsolatedEncoder::encode_struct_ctor({:?})", def_id);
let tcx = self.tcx;
- let variant = tcx.adt_def(adt_def_id).struct_variant();
+ let adt_def = tcx.adt_def(adt_def_id);
+ let variant = adt_def.struct_variant();
let data = VariantData {
ctor_kind: variant.ctor_kind,
}
}
+ // If the structure is marked as non_exhaustive then lower the visibility
+ // to within the crate.
+ if adt_def.is_non_exhaustive() && ctor_vis == ty::Visibility::Public {
+ ctor_vis = ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
+ }
+
let repr_options = get_repr_options(&tcx, adt_def_id);
Entry {
ctor_sig: None,
}), repr_options)
}
- hir::ItemDefaultImpl(..) => {
+ hir::ItemAutoImpl(..) => {
let data = ImplData {
polarity: hir::ImplPolarity::Positive,
defaultness: hir::Defaultness::Final,
trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)),
};
- EntryKind::DefaultImpl(self.lazy(&data))
+ EntryKind::AutoImpl(self.lazy(&data))
}
hir::ItemImpl(_, polarity, defaultness, ..) => {
let trait_ref = tcx.impl_trait_ref(def_id);
let data = TraitData {
unsafety: trait_def.unsafety,
paren_sugar: trait_def.paren_sugar,
- has_default_impl: tcx.trait_has_default_impl(def_id),
+ has_auto_impl: tcx.trait_is_auto(def_id),
super_predicates: self.lazy(&tcx.super_predicates_of(def_id)),
};
}
hir::ForeignItemStatic(_, true) => EntryKind::ForeignMutStatic,
hir::ForeignItemStatic(_, false) => EntryKind::ForeignImmStatic,
+ hir::ForeignItemType => EntryKind::ForeignType,
};
Entry {
fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
match ty.node {
- hir::TyImplTrait(_) => {
+ hir::TyImplTraitExistential(_) => {
let def_id = self.tcx.hir.local_def_id(ty.id);
self.record(def_id, IsolatedEncoder::encode_info_for_anon_ty, def_id);
}
hir::ItemGlobalAsm(..) |
hir::ItemExternCrate(..) |
hir::ItemUse(..) |
- hir::ItemDefaultImpl(..) |
+ hir::ItemAutoImpl(..) |
hir::ItemTy(..) => {
// no sub-item recording needed in these cases
}