use rustc::hir::GenericParamKind;
use rustc::hir::map::definitions::DefPathTable;
use rustc_data_structures::fingerprint::Fingerprint;
+use rustc_data_structures::indexed_vec::IndexVec;
use rustc::middle::dependency_format::Linkage;
use rustc::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel,
metadata_symbol_name};
use std::u32;
use syntax::ast;
use syntax::attr;
+use syntax::ext::proc_macro::is_proc_macro_attr;
use syntax::source_map::Spanned;
-use syntax::symbol::{kw, sym};
+use syntax::symbol::{kw, sym, Ident};
use syntax_pos::{self, FileName, SourceFile, Span};
use log::{debug, trace};
impl<'tcx, T> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> {
fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> {
- self.emit_lazy_distance(lazy.position, Lazy::<T>::min_size())
+ self.emit_lazy_distance(*lazy)
}
}
-impl<'tcx, T> SpecializedEncoder<LazySeq<T>> for EncodeContext<'tcx> {
- fn specialized_encode(&mut self, seq: &LazySeq<T>) -> Result<(), Self::Error> {
- self.emit_usize(seq.len)?;
- if seq.len == 0 {
+impl<'tcx, T> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> {
+ fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> {
+ self.emit_usize(lazy.meta)?;
+ if lazy.meta == 0 {
return Ok(());
}
- self.emit_lazy_distance(seq.position, LazySeq::<T>::min_size(seq.len))
+ self.emit_lazy_distance(*lazy)
}
}
}
}
+impl SpecializedEncoder<Ident> for EncodeContext<'tcx> {
+ fn specialized_encode(&mut self, ident: &Ident) -> Result<(), Self::Error> {
+ // FIXME(jseyfried): intercrate hygiene
+ ident.name.encode(self)
+ }
+}
+
impl<'tcx> SpecializedEncoder<LocalDefId> for EncodeContext<'tcx> {
#[inline]
fn specialized_encode(&mut self, def_id: &LocalDefId) -> Result<(), Self::Error> {
}
}
-impl<'tcx> EncodeContext<'tcx> {
- fn emit_node<F: FnOnce(&mut Self, usize) -> R, R>(&mut self, f: F) -> R {
- assert_eq!(self.lazy_state, LazyState::NoNode);
- let pos = self.position();
- self.lazy_state = LazyState::NodeStart(pos);
- let r = f(self, pos);
- self.lazy_state = LazyState::NoNode;
- r
+/// Helper trait to allow overloading `EncodeContext::lazy` for iterators.
+trait EncodeContentsForLazy<T: ?Sized + LazyMeta> {
+ fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) -> T::Meta;
+}
+
+impl<T: Encodable> EncodeContentsForLazy<T> for &T {
+ fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) {
+ self.encode(ecx).unwrap()
+ }
+}
+
+impl<T: Encodable> EncodeContentsForLazy<T> for T {
+ fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) {
+ self.encode(ecx).unwrap()
}
+}
+
+impl<I, T> EncodeContentsForLazy<[T]> for I
+ where I: IntoIterator,
+ I::Item: EncodeContentsForLazy<T>,
+{
+ fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) -> usize {
+ self.into_iter().map(|value| value.encode_contents_for_lazy(ecx)).count()
+ }
+}
- fn emit_lazy_distance(&mut self,
- position: usize,
- min_size: usize)
- -> Result<(), <Self as Encoder>::Error> {
- let min_end = position + min_size;
+impl<'tcx> EncodeContext<'tcx> {
+ fn emit_lazy_distance<T: ?Sized + LazyMeta>(
+ &mut self,
+ lazy: Lazy<T>,
+ ) -> Result<(), <Self as Encoder>::Error> {
+ let min_end = lazy.position + T::min_size(lazy.meta);
let distance = match self.lazy_state {
LazyState::NoNode => bug!("emit_lazy_distance: outside of a metadata node"),
LazyState::NodeStart(start) => {
}
LazyState::Previous(last_min_end) => {
assert!(
- last_min_end <= position,
+ last_min_end <= lazy.position,
"make sure that the calls to `lazy*` \
are in the same order as the metadata fields",
);
- position - last_min_end
+ lazy.position - last_min_end
}
};
self.lazy_state = LazyState::Previous(min_end);
self.emit_usize(distance)
}
- pub fn lazy<T: Encodable>(&mut self, value: &T) -> Lazy<T> {
- self.emit_node(|ecx, pos| {
- value.encode(ecx).unwrap();
-
- assert!(pos + Lazy::<T>::min_size() <= ecx.position());
- Lazy::with_position(pos)
- })
- }
-
- pub fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T>
- where I: IntoIterator<Item = T>,
- T: Encodable
- {
- self.emit_node(|ecx, pos| {
- let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count();
+ fn lazy<T: ?Sized + LazyMeta>(
+ &mut self,
+ value: impl EncodeContentsForLazy<T>,
+ ) -> Lazy<T> {
+ let pos = self.position();
- assert!(pos + LazySeq::<T>::min_size(len) <= ecx.position());
- LazySeq::with_position_and_length(pos, len)
- })
- }
+ assert_eq!(self.lazy_state, LazyState::NoNode);
+ self.lazy_state = LazyState::NodeStart(pos);
+ let meta = value.encode_contents_for_lazy(self);
+ self.lazy_state = LazyState::NoNode;
- pub fn lazy_seq_ref<'b, I, T>(&mut self, iter: I) -> LazySeq<T>
- where I: IntoIterator<Item = &'b T>,
- T: 'b + Encodable
- {
- self.emit_node(|ecx, pos| {
- let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count();
+ assert!(pos + <T>::min_size(meta) <= self.position());
- assert!(pos + LazySeq::<T>::min_size(len) <= ecx.position());
- LazySeq::with_position_and_length(pos, len)
- })
+ Lazy::from_position_and_meta(pos, meta)
}
/// Emit the data for a `DefId` to the metadata. The function to
assert!(id.is_local());
let entry = op(self, data);
- let entry = self.lazy(&entry);
+ let entry = self.lazy(entry);
self.entries_index.record(id, entry);
}
self.lazy(definitions.def_path_table())
}
- fn encode_source_map(&mut self) -> LazySeq<syntax_pos::SourceFile> {
+ fn encode_source_map(&mut self) -> Lazy<[syntax_pos::SourceFile]> {
let source_map = self.tcx.sess.source_map();
let all_source_files = source_map.files();
})
.collect::<Vec<_>>();
- self.lazy_seq_ref(adapted.iter().map(|rc| &**rc))
+ self.lazy(adapted.iter().map(|rc| &**rc))
}
fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
+ let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
+
let mut i = self.position();
let crate_deps = self.encode_crate_deps();
}
n = new_n;
}
- self.lazy_seq(interpret_alloc_index)
+ self.lazy(interpret_alloc_index)
};
+
i = self.position();
let entries_index = self.entries_index.write_index(&mut self.opaque);
let entries_index_bytes = self.position() - i;
+ // Encode the proc macro data
+ i = self.position();
+ let proc_macro_data = self.encode_proc_macros();
+ let proc_macro_data_bytes = self.position() - i;
+
+
let attrs = tcx.hir().krate_attrs();
- let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
let has_default_lib_allocator = attr::contains_name(&attrs, sym::default_lib_allocator);
let has_global_allocator = *tcx.sess.has_global_allocator.get();
let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false);
- let root = self.lazy(&CrateRoot {
+ let root = self.lazy(CrateRoot {
name: tcx.crate_name(LOCAL_CRATE),
extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
triple: tcx.sess.opts.target_triple.clone(),
} else {
None
},
+ proc_macro_data,
proc_macro_stability: if is_proc_macro {
tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| stab.clone())
} else {
println!(" impl bytes: {}", impl_bytes);
println!(" exp. symbols bytes: {}", exported_symbols_bytes);
println!(" def-path table bytes: {}", def_path_table_bytes);
+ println!(" proc-macro-data-bytes: {}", proc_macro_data_bytes);
println!(" item bytes: {}", item_bytes);
println!(" entries index bytes: {}", entries_index_bytes);
println!(" zero bytes: {}", zero_bytes);
}
impl EncodeContext<'tcx> {
- fn encode_variances_of(&mut self, def_id: DefId) -> LazySeq<ty::Variance> {
+ fn encode_variances_of(&mut self, def_id: DefId) -> Lazy<[ty::Variance]> {
debug!("EncodeContext::encode_variances_of({:?})", def_id);
let tcx = self.tcx;
- self.lazy_seq_ref(&tcx.variances_of(def_id)[..])
+ self.lazy(&tcx.variances_of(def_id)[..])
}
fn encode_item_type(&mut self, def_id: DefId) -> Lazy<Ty<'tcx>> {
let tcx = self.tcx;
let ty = tcx.type_of(def_id);
debug!("EncodeContext::encode_item_type({:?}) => {:?}", def_id, ty);
- self.lazy(&ty)
+ self.lazy(ty)
}
fn encode_enum_variant_info(
let enum_vis = &tcx.hir().expect_item(enum_id).vis;
Entry {
- kind: EntryKind::Variant(self.lazy(&data)),
- visibility: self.lazy(&ty::Visibility::from_hir(enum_vis, enum_id, tcx)),
- span: self.lazy(&tcx.def_span(def_id)),
+ kind: EntryKind::Variant(self.lazy(data)),
+ visibility: self.lazy(ty::Visibility::from_hir(enum_vis, enum_id, tcx)),
+ span: self.lazy(tcx.def_span(def_id)),
attributes: self.encode_attributes(&tcx.get_attrs(def_id)),
- children: self.lazy_seq(variant.fields.iter().map(|f| {
+ children: self.lazy(variant.fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
})),
deprecation: self.encode_deprecation(def_id),
ty: Some(self.encode_item_type(def_id)),
- inherent_impls: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
variances: if variant.ctor_kind == CtorKind::Fn {
self.encode_variances_of(def_id)
} else {
- LazySeq::empty()
+ Lazy::empty()
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,
mir: self.encode_optimized_mir(def_id),
+ promoted_mir: self.encode_promoted_mir(def_id),
}
}
discr: variant.discr,
ctor: Some(def_id.index),
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
- Some(self.lazy(&tcx.fn_sig(def_id)))
+ Some(self.lazy(tcx.fn_sig(def_id)))
} else {
None
}
}
Entry {
- kind: EntryKind::Variant(self.lazy(&data)),
- visibility: self.lazy(&ctor_vis),
- span: self.lazy(&tcx.def_span(def_id)),
- attributes: LazySeq::empty(),
- children: LazySeq::empty(),
+ kind: EntryKind::Variant(self.lazy(data)),
+ visibility: self.lazy(ctor_vis),
+ span: self.lazy(tcx.def_span(def_id)),
+ attributes: Lazy::empty(),
+ children: Lazy::empty(),
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
ty: Some(self.encode_item_type(def_id)),
- inherent_impls: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
variances: if variant.ctor_kind == CtorKind::Fn {
self.encode_variances_of(def_id)
} else {
- LazySeq::empty()
+ Lazy::empty()
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,
mir: self.encode_optimized_mir(def_id),
+ promoted_mir: self.encode_promoted_mir(def_id),
}
}
let data = ModData {
reexports: match tcx.module_exports(def_id) {
- Some(exports) => self.lazy_seq_ref(exports),
- _ => LazySeq::empty(),
+ Some(exports) => self.lazy(exports),
+ _ => Lazy::empty(),
},
};
Entry {
- kind: EntryKind::Mod(self.lazy(&data)),
- visibility: self.lazy(&ty::Visibility::from_hir(vis, id, tcx)),
- span: self.lazy(&tcx.def_span(def_id)),
+ kind: EntryKind::Mod(self.lazy(data)),
+ visibility: self.lazy(ty::Visibility::from_hir(vis, id, tcx)),
+ span: self.lazy(tcx.def_span(def_id)),
attributes: self.encode_attributes(attrs),
- children: self.lazy_seq(md.item_ids.iter().map(|item_id| {
+ children: self.lazy(md.item_ids.iter().map(|item_id| {
tcx.hir().local_def_id(item_id.id).index
})),
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
ty: None,
- inherent_impls: LazySeq::empty(),
- variances: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
+ variances: Lazy::empty(),
generics: None,
predicates: None,
predicates_defined_on: None,
- mir: None
+ mir: None,
+ promoted_mir: None,
}
}
Entry {
kind: EntryKind::Field,
- visibility: self.lazy(&field.vis),
- span: self.lazy(&tcx.def_span(def_id)),
+ visibility: self.lazy(field.vis),
+ span: self.lazy(tcx.def_span(def_id)),
attributes: self.encode_attributes(&variant_data.fields()[field_index].attrs),
- children: LazySeq::empty(),
+ children: Lazy::empty(),
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
ty: Some(self.encode_item_type(def_id)),
- inherent_impls: LazySeq::empty(),
- variances: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
+ variances: Lazy::empty(),
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,
mir: None,
+ promoted_mir: None,
}
}
discr: variant.discr,
ctor: Some(def_id.index),
ctor_sig: if variant.ctor_kind == CtorKind::Fn {
- Some(self.lazy(&tcx.fn_sig(def_id)))
+ Some(self.lazy(tcx.fn_sig(def_id)))
} else {
None
}
let repr_options = get_repr_options(tcx, adt_def_id);
Entry {
- kind: EntryKind::Struct(self.lazy(&data), repr_options),
- visibility: self.lazy(&ctor_vis),
- span: self.lazy(&tcx.def_span(def_id)),
- attributes: LazySeq::empty(),
- children: LazySeq::empty(),
+ kind: EntryKind::Struct(self.lazy(data), repr_options),
+ visibility: self.lazy(ctor_vis),
+ span: self.lazy(tcx.def_span(def_id)),
+ attributes: Lazy::empty(),
+ children: Lazy::empty(),
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
ty: Some(self.encode_item_type(def_id)),
- inherent_impls: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
variances: if variant.ctor_kind == CtorKind::Fn {
self.encode_variances_of(def_id)
} else {
- LazySeq::empty()
+ Lazy::empty()
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,
mir: self.encode_optimized_mir(def_id),
+ promoted_mir: self.encode_promoted_mir(def_id),
}
}
fn encode_predicates(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
debug!("EncodeContext::encode_predicates({:?})", def_id);
let tcx = self.tcx;
- self.lazy(&tcx.predicates_of(def_id))
+ self.lazy(&*tcx.predicates_of(def_id))
}
fn encode_predicates_defined_on(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id);
let tcx = self.tcx;
- self.lazy(&tcx.predicates_defined_on(def_id))
+ self.lazy(&*tcx.predicates_defined_on(def_id))
}
fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
let rendered =
hir::print::to_string(self.tcx.hir(), |s| s.print_trait_item(ast_item));
- let rendered_const = self.lazy(&RenderedConst(rendered));
+ let rendered_const = self.lazy(RenderedConst(rendered));
EntryKind::AssocConst(container, const_qualif, rendered_const)
}
FnData {
constness: hir::Constness::NotConst,
arg_names,
- sig: self.lazy(&tcx.fn_sig(def_id)),
+ sig: self.lazy(tcx.fn_sig(def_id)),
}
} else {
bug!()
};
- EntryKind::Method(self.lazy(&MethodData {
+ EntryKind::Method(self.lazy(MethodData {
fn_data,
container,
has_self: trait_item.method_has_self_argument,
Entry {
kind,
- visibility: self.lazy(&trait_item.vis),
- span: self.lazy(&ast_item.span),
+ visibility: self.lazy(trait_item.vis),
+ span: self.lazy(ast_item.span),
attributes: self.encode_attributes(&ast_item.attrs),
- children: LazySeq::empty(),
+ children: Lazy::empty(),
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
}
ty::AssocKind::OpaqueTy => unreachable!(),
},
- inherent_impls: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
variances: if trait_item.kind == ty::AssocKind::Method {
self.encode_variances_of(def_id)
} else {
- LazySeq::empty()
+ Lazy::empty()
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,
mir: self.encode_optimized_mir(def_id),
+ promoted_mir: self.encode_promoted_mir(def_id),
}
}
FnData {
constness: sig.header.constness,
arg_names: self.encode_fn_arg_names_for_body(body),
- sig: self.lazy(&tcx.fn_sig(def_id)),
+ sig: self.lazy(tcx.fn_sig(def_id)),
}
} else {
bug!()
};
- EntryKind::Method(self.lazy(&MethodData {
+ EntryKind::Method(self.lazy(MethodData {
fn_data,
container,
has_self: impl_item.method_has_self_argument,
Entry {
kind,
- visibility: self.lazy(&impl_item.vis),
- span: self.lazy(&ast_item.span),
+ visibility: self.lazy(impl_item.vis),
+ span: self.lazy(ast_item.span),
attributes: self.encode_attributes(&ast_item.attrs),
- children: LazySeq::empty(),
+ children: Lazy::empty(),
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
ty: Some(self.encode_item_type(def_id)),
- inherent_impls: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
variances: if impl_item.kind == ty::AssocKind::Method {
self.encode_variances_of(def_id)
} else {
- LazySeq::empty()
+ Lazy::empty()
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,
mir: if mir { self.encode_optimized_mir(def_id) } else { None },
+ promoted_mir: if mir { self.encode_promoted_mir(def_id) } else { None },
}
}
fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId)
- -> LazySeq<ast::Name> {
+ -> Lazy<[ast::Name]> {
self.tcx.dep_graph.with_ignore(|| {
let body = self.tcx.hir().body(body_id);
- self.lazy_seq(body.arguments.iter().map(|arg| {
+ self.lazy(body.arguments.iter().map(|arg| {
match arg.pat.node {
PatKind::Binding(_, _, ident, _) => ident.name,
_ => kw::Invalid,
})
}
- fn encode_fn_arg_names(&mut self, param_names: &[ast::Ident]) -> LazySeq<ast::Name> {
- self.lazy_seq(param_names.iter().map(|ident| ident.name))
+ fn encode_fn_arg_names(&mut self, param_names: &[ast::Ident]) -> Lazy<[ast::Name]> {
+ self.lazy(param_names.iter().map(|ident| ident.name))
}
fn encode_optimized_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Body<'tcx>>> {
debug!("EntryBuilder::encode_mir({:?})", def_id);
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
let mir = self.tcx.optimized_mir(def_id);
- Some(self.lazy(&mir))
+ Some(self.lazy(mir))
+ } else {
+ None
+ }
+ }
+
+ fn encode_promoted_mir(&mut self, def_id: DefId) ->
+ Option<Lazy<IndexVec<mir::Promoted, mir::Body<'tcx>>>> {
+ debug!("EncodeContext::encode_promoted_mir({:?})", def_id);
+ if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
+ let promoted = self.tcx.promoted_mir(def_id);
+ Some(self.lazy(promoted))
} else {
None
}
}
// Encodes the inherent implementations of a structure, enumeration, or trait.
- fn encode_inherent_implementations(&mut self, def_id: DefId) -> LazySeq<DefIndex> {
+ fn encode_inherent_implementations(&mut self, def_id: DefId) -> Lazy<[DefIndex]> {
debug!("EncodeContext::encode_inherent_implementations({:?})", def_id);
let implementations = self.tcx.inherent_impls(def_id);
if implementations.is_empty() {
- LazySeq::empty()
+ Lazy::empty()
} else {
- self.lazy_seq(implementations.iter().map(|&def_id| {
+ self.lazy(implementations.iter().map(|&def_id| {
assert!(def_id.is_local());
def_id.index
}))
fn encode_deprecation(&mut self, def_id: DefId) -> Option<Lazy<attr::Deprecation>> {
debug!("EncodeContext::encode_deprecation({:?})", def_id);
- self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr))
+ self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(depr))
}
fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> Lazy<RenderedConst> {
let data = FnData {
constness: header.constness,
arg_names: self.encode_fn_arg_names_for_body(body),
- sig: self.lazy(&tcx.fn_sig(def_id)),
+ sig: self.lazy(tcx.fn_sig(def_id)),
};
- EntryKind::Fn(self.lazy(&data))
+ EntryKind::Fn(self.lazy(data))
}
hir::ItemKind::Mod(ref m) => {
return self.encode_info_for_mod((item.hir_id, m, &item.attrs, &item.vis));
let repr_options = get_repr_options(tcx, def_id);
- EntryKind::Struct(self.lazy(&VariantData {
+ EntryKind::Struct(self.lazy(VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
ctor,
let variant = tcx.adt_def(def_id).non_enum_variant();
let repr_options = get_repr_options(tcx, def_id);
- EntryKind::Union(self.lazy(&VariantData {
+ EntryKind::Union(self.lazy(VariantData {
ctor_kind: variant.ctor_kind,
discr: variant.discr,
ctor: None,
defaultness,
parent_impl: parent,
coerce_unsized_info,
- trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)),
+ trait_ref: trait_ref.map(|trait_ref| self.lazy(trait_ref)),
};
- EntryKind::Impl(self.lazy(&data))
+ EntryKind::Impl(self.lazy(data))
}
hir::ItemKind::Trait(..) => {
let trait_def = tcx.trait_def(def_id);
paren_sugar: trait_def.paren_sugar,
has_auto_impl: tcx.trait_is_auto(def_id),
is_marker: trait_def.is_marker,
- super_predicates: self.lazy(&tcx.super_predicates_of(def_id)),
+ super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)),
};
- EntryKind::Trait(self.lazy(&data))
+ EntryKind::Trait(self.lazy(data))
}
hir::ItemKind::TraitAlias(..) => {
let data = TraitAliasData {
- super_predicates: self.lazy(&tcx.super_predicates_of(def_id)),
+ super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)),
};
- EntryKind::TraitAlias(self.lazy(&data))
+ EntryKind::TraitAlias(self.lazy(data))
}
hir::ItemKind::ExternCrate(_) |
hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item),
};
+ let mir = match item.node {
+ hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true,
+ hir::ItemKind::Fn(_, header, ..) => {
+ let generics = tcx.generics_of(def_id);
+ let needs_inline =
+ (generics.requires_monomorphization(tcx) ||
+ tcx.codegen_fn_attrs(def_id).requests_inline()) &&
+ !self.metadata_output_only();
+ let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
+ needs_inline || header.constness == hir::Constness::Const || always_encode_mir
+ }
+ _ => false,
+ };
+
Entry {
kind,
- visibility: self.lazy(&ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)),
- span: self.lazy(&item.span),
+ visibility: self.lazy(ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)),
+ span: self.lazy(item.span),
attributes: self.encode_attributes(&item.attrs),
children: match item.node {
hir::ItemKind::ForeignMod(ref fm) => {
- self.lazy_seq(fm.items
+ self.lazy(fm.items
.iter()
.map(|foreign_item| tcx.hir().local_def_id(
foreign_item.hir_id).index))
}
hir::ItemKind::Enum(..) => {
let def = self.tcx.adt_def(def_id);
- self.lazy_seq(def.variants.iter().map(|v| {
+ self.lazy(def.variants.iter().map(|v| {
assert!(v.def_id.is_local());
v.def_id.index
}))
hir::ItemKind::Struct(..) |
hir::ItemKind::Union(..) => {
let def = self.tcx.adt_def(def_id);
- self.lazy_seq(def.non_enum_variant().fields.iter().map(|f| {
+ self.lazy(def.non_enum_variant().fields.iter().map(|f| {
assert!(f.did.is_local());
f.did.index
}))
}
hir::ItemKind::Impl(..) |
hir::ItemKind::Trait(..) => {
- self.lazy_seq(tcx.associated_item_def_ids(def_id).iter().map(|&def_id| {
+ self.lazy(tcx.associated_item_def_ids(def_id).iter().map(|&def_id| {
assert!(def_id.is_local());
def_id.index
}))
}
- _ => LazySeq::empty(),
+ _ => Lazy::empty(),
},
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
hir::ItemKind::Struct(..) |
hir::ItemKind::Union(..) |
hir::ItemKind::Fn(..) => self.encode_variances_of(def_id),
- _ => LazySeq::empty(),
+ _ => Lazy::empty(),
},
generics: match item.node {
hir::ItemKind::Static(..) |
_ => None, // not *wrong* for other kinds of items, but not needed
},
- mir: match item.node {
- hir::ItemKind::Static(..) => {
- self.encode_optimized_mir(def_id)
- }
- hir::ItemKind::Const(..) => self.encode_optimized_mir(def_id),
- hir::ItemKind::Fn(_, header, ..) => {
- let generics = tcx.generics_of(def_id);
- let needs_inline =
- (generics.requires_monomorphization(tcx) ||
- tcx.codegen_fn_attrs(def_id).requests_inline()) &&
- !self.metadata_output_only();
- let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
- if needs_inline
- || header.constness == hir::Constness::Const
- || always_encode_mir
- {
- self.encode_optimized_mir(def_id)
- } else {
- None
- }
- }
- _ => None,
- },
+ mir: if mir { self.encode_optimized_mir(def_id) } else { None },
+ promoted_mir: if mir { self.encode_promoted_mir(def_id) } else { None },
}
}
use syntax::print::pprust;
let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
Entry {
- kind: EntryKind::MacroDef(self.lazy(&MacroDef {
+ kind: EntryKind::MacroDef(self.lazy(MacroDef {
body: pprust::tokens_to_string(macro_def.body.clone()),
legacy: macro_def.legacy,
})),
- visibility: self.lazy(&ty::Visibility::Public),
- span: self.lazy(¯o_def.span),
+ visibility: self.lazy(ty::Visibility::Public),
+ span: self.lazy(macro_def.span),
attributes: self.encode_attributes(¯o_def.attrs),
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
- children: LazySeq::empty(),
+ children: Lazy::empty(),
ty: None,
- inherent_impls: LazySeq::empty(),
- variances: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
+ variances: Lazy::empty(),
generics: None,
predicates: None,
predicates_defined_on: None,
mir: None,
+ promoted_mir: None,
}
}
let tcx = self.tcx;
Entry {
kind: entry_kind,
- visibility: self.lazy(&ty::Visibility::Public),
- span: self.lazy(&tcx.def_span(def_id)),
- attributes: LazySeq::empty(),
- children: LazySeq::empty(),
+ visibility: self.lazy(ty::Visibility::Public),
+ span: self.lazy(tcx.def_span(def_id)),
+ attributes: Lazy::empty(),
+ children: Lazy::empty(),
stability: None,
deprecation: None,
ty: if encode_type { Some(self.encode_item_type(def_id)) } else { None },
- inherent_impls: LazySeq::empty(),
- variances: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
+ variances: Lazy::empty(),
generics: None,
predicates: None,
predicates_defined_on: None,
mir: None,
+ promoted_mir: None,
}
}
let data = GeneratorData {
layout: layout.clone(),
};
- EntryKind::Generator(self.lazy(&data))
+ EntryKind::Generator(self.lazy(data))
}
ty::Closure(def_id, substs) => {
let sig = substs.closure_sig(def_id, self.tcx);
- let data = ClosureData { sig: self.lazy(&sig) };
- EntryKind::Closure(self.lazy(&data))
+ let data = ClosureData { sig: self.lazy(sig) };
+ EntryKind::Closure(self.lazy(data))
}
_ => bug!("closure that is neither generator nor closure")
Entry {
kind,
- visibility: self.lazy(&ty::Visibility::Public),
- span: self.lazy(&tcx.def_span(def_id)),
+ visibility: self.lazy(ty::Visibility::Public),
+ span: self.lazy(tcx.def_span(def_id)),
attributes: self.encode_attributes(&tcx.get_attrs(def_id)),
- children: LazySeq::empty(),
+ children: Lazy::empty(),
stability: None,
deprecation: None,
ty: Some(self.encode_item_type(def_id)),
- inherent_impls: LazySeq::empty(),
- variances: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
+ variances: Lazy::empty(),
generics: Some(self.encode_generics(def_id)),
predicates: None,
predicates_defined_on: None,
mir: self.encode_optimized_mir(def_id),
+ promoted_mir: self.encode_promoted_mir(def_id),
}
}
Entry {
kind: EntryKind::Const(self.const_qualif(mir, body_id), const_data),
- visibility: self.lazy(&ty::Visibility::Public),
- span: self.lazy(&tcx.def_span(def_id)),
- attributes: LazySeq::empty(),
- children: LazySeq::empty(),
+ visibility: self.lazy(ty::Visibility::Public),
+ span: self.lazy(tcx.def_span(def_id)),
+ attributes: Lazy::empty(),
+ children: Lazy::empty(),
stability: None,
deprecation: None,
ty: Some(self.encode_item_type(def_id)),
- inherent_impls: LazySeq::empty(),
- variances: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
+ variances: Lazy::empty(),
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,
mir: self.encode_optimized_mir(def_id),
+ promoted_mir: self.encode_promoted_mir(def_id),
}
}
- fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> LazySeq<ast::Attribute> {
- self.lazy_seq_ref(attrs)
+ fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> Lazy<[ast::Attribute]> {
+ self.lazy(attrs)
}
- fn encode_native_libraries(&mut self) -> LazySeq<NativeLibrary> {
+ fn encode_native_libraries(&mut self) -> Lazy<[NativeLibrary]> {
let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
- self.lazy_seq(used_libraries.iter().cloned())
+ self.lazy(used_libraries.iter().cloned())
}
- fn encode_foreign_modules(&mut self) -> LazySeq<ForeignModule> {
+ fn encode_foreign_modules(&mut self) -> Lazy<[ForeignModule]> {
let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE);
- self.lazy_seq(foreign_modules.iter().cloned())
+ self.lazy(foreign_modules.iter().cloned())
+ }
+
+ fn encode_proc_macros(&mut self) -> Option<Lazy<[DefIndex]>> {
+ let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
+ if is_proc_macro {
+ let tcx = self.tcx;
+ Some(self.lazy(tcx.hir().krate().items.values().filter_map(|item| {
+ if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) {
+ Some(item.hir_id.owner)
+ } else {
+ None
+ }
+ })))
+ } else {
+ None
+ }
}
- fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> {
+ fn encode_crate_deps(&mut self) -> Lazy<[CrateDep]> {
let crates = self.tcx.crates();
let mut deps = crates
// the assumption that they are numbered 1 to n.
// FIXME (#2166): This is not nearly enough to support correct versioning
// but is enough to get transitive crate dependencies working.
- self.lazy_seq_ref(deps.iter().map(|&(_, ref dep)| dep))
+ self.lazy(deps.iter().map(|&(_, ref dep)| dep))
}
- fn encode_lib_features(&mut self) -> LazySeq<(ast::Name, Option<ast::Name>)> {
+ fn encode_lib_features(&mut self) -> Lazy<[(ast::Name, Option<ast::Name>)]> {
let tcx = self.tcx;
let lib_features = tcx.lib_features();
- self.lazy_seq(lib_features.to_vec())
+ self.lazy(lib_features.to_vec())
}
- fn encode_lang_items(&mut self) -> LazySeq<(DefIndex, usize)> {
+ fn encode_lang_items(&mut self) -> Lazy<[(DefIndex, usize)]> {
let tcx = self.tcx;
let lang_items = tcx.lang_items();
let lang_items = lang_items.items().iter();
- self.lazy_seq(lang_items.enumerate().filter_map(|(i, &opt_def_id)| {
+ self.lazy(lang_items.enumerate().filter_map(|(i, &opt_def_id)| {
if let Some(def_id) = opt_def_id {
if def_id.is_local() {
return Some((def_id.index, i));
}))
}
- fn encode_lang_items_missing(&mut self) -> LazySeq<lang_items::LangItem> {
+ fn encode_lang_items_missing(&mut self) -> Lazy<[lang_items::LangItem]> {
let tcx = self.tcx;
- self.lazy_seq_ref(&tcx.lang_items().missing)
+ self.lazy(&tcx.lang_items().missing)
}
/// Encodes an index, mapping each trait to its (local) implementations.
- fn encode_impls(&mut self) -> LazySeq<TraitImpls> {
+ fn encode_impls(&mut self) -> Lazy<[TraitImpls]> {
debug!("EncodeContext::encode_impls()");
let tcx = self.tcx;
let mut visitor = ImplVisitor {
TraitImpls {
trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
- impls: self.lazy_seq_ref(&impls),
+ impls: self.lazy(&impls),
}
})
.collect();
- self.lazy_seq_ref(&all_impls)
+ self.lazy(&all_impls)
}
// Encodes all symbols exported from this crate into the metadata.
// definition (as that's not defined in this crate).
fn encode_exported_symbols(&mut self,
exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportLevel)])
- -> LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)> {
+ -> Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]> {
// The metadata symbol name is special. It should not show up in
// downstream crates.
let metadata_symbol_name = SymbolName::new(&metadata_symbol_name(self.tcx));
- self.lazy_seq(exported_symbols
+ self.lazy(exported_symbols
.iter()
.filter(|&&(ref exported_symbol, _)| {
match *exported_symbol {
.cloned())
}
- fn encode_dylib_dependency_formats(&mut self) -> LazySeq<Option<LinkagePreference>> {
+ fn encode_dylib_dependency_formats(&mut self) -> Lazy<[Option<LinkagePreference>]> {
match self.tcx.sess.dependency_formats.borrow().get(&config::CrateType::Dylib) {
Some(arr) => {
- self.lazy_seq(arr.iter().map(|slot| {
+ self.lazy(arr.iter().map(|slot| {
match *slot {
Linkage::NotLinked |
Linkage::IncludedFromDylib => None,
}
}))
}
- None => LazySeq::empty(),
+ None => Lazy::empty(),
}
}
let data = FnData {
constness: hir::Constness::NotConst,
arg_names: self.encode_fn_arg_names(names),
- sig: self.lazy(&tcx.fn_sig(def_id)),
+ sig: self.lazy(tcx.fn_sig(def_id)),
};
- EntryKind::ForeignFn(self.lazy(&data))
+ EntryKind::ForeignFn(self.lazy(data))
}
hir::ForeignItemKind::Static(_, hir::MutMutable) => EntryKind::ForeignMutStatic,
hir::ForeignItemKind::Static(_, hir::MutImmutable) => EntryKind::ForeignImmStatic,
Entry {
kind,
- visibility: self.lazy(&ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, tcx)),
- span: self.lazy(&nitem.span),
+ visibility: self.lazy(ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, tcx)),
+ span: self.lazy(nitem.span),
attributes: self.encode_attributes(&nitem.attrs),
- children: LazySeq::empty(),
+ children: Lazy::empty(),
stability: self.encode_stability(def_id),
deprecation: self.encode_deprecation(def_id),
ty: Some(self.encode_item_type(def_id)),
- inherent_impls: LazySeq::empty(),
+ inherent_impls: Lazy::empty(),
variances: match nitem.node {
hir::ForeignItemKind::Fn(..) => self.encode_variances_of(def_id),
- _ => LazySeq::empty(),
+ _ => Lazy::empty(),
},
generics: Some(self.encode_generics(def_id)),
predicates: Some(self.encode_predicates(def_id)),
predicates_defined_on: None,
mir: None,
+ promoted_mir: None,
}
}
}
id: hir::HirId) {
intravisit::walk_variant(self, v, g, id);
- if let Some(ref discr) = v.node.disr_expr {
+ if let Some(ref discr) = v.disr_expr {
let def_id = self.tcx.hir().local_def_id(discr.hir_id);
self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
}