]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_metadata/encoder.rs
Rollup merge of #61273 - RalfJung:maybe-uninit, r=Centril
[rust.git] / src / librustc_metadata / encoder.rs
index 7f0993e799f5424031d143c432de3e0624cda489..588682a2420a94b38437a7a6f8ad0e4b54db2dfb 100644 (file)
@@ -1,6 +1,4 @@
 use crate::index::Index;
-use crate::index_builder::{FromId, IndexBuilder, Untracked};
-use crate::isolated_encoder::IsolatedEncoder;
 use crate::schema::*;
 
 use rustc::middle::cstore::{LinkagePreference, NativeLibrary,
@@ -33,7 +31,7 @@
 use syntax::ast;
 use syntax::attr;
 use syntax::source_map::Spanned;
-use syntax::symbol::{keywords, sym};
+use syntax::symbol::{kw, sym};
 use syntax_pos::{self, FileName, SourceFile, Span};
 use log::{debug, trace};
 
@@ -46,6 +44,8 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
     opaque: opaque::Encoder,
     pub tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
+    entries_index: Index<'tcx>,
+
     lazy_state: LazyState,
     type_shorthands: FxHashMap<Ty<'tcx>, usize>,
     predicate_shorthands: FxHashMap<ty::Predicate<'tcx>, usize>,
@@ -300,28 +300,34 @@ pub fn lazy_seq_ref<'b, I, T>(&mut self, iter: I) -> LazySeq<T>
         })
     }
 
-    // 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,
-                                op: fn(&mut IsolatedEncoder<'x, 'a, 'tcx>, DATA) -> R,
-                                data: DATA)
-                                -> R {
-        op(&mut IsolatedEncoder::new(self), data)
+    /// Emit the data for a `DefId` to the metadata. The function to
+    /// emit the data is `op`, and it will be given `data` as
+    /// arguments. This `record` function will call `op` to generate
+    /// the `Entry` (which may point to other encoded information)
+    /// and will then record the `Lazy<Entry>` for use in the index.
+    // FIXME(eddyb) remove this.
+    pub fn record<DATA>(&mut self,
+                        id: DefId,
+                        op: impl FnOnce(&mut Self, DATA) -> Entry<'tcx>,
+                        data: DATA)
+    {
+        assert!(id.is_local());
+
+        let entry = op(self, data);
+        let entry = self.lazy(&entry);
+        self.entries_index.record(id, entry);
     }
 
-    fn encode_info_for_items(&mut self) -> Index {
+    fn encode_info_for_items(&mut self) {
         let krate = self.tcx.hir().krate();
-        let mut index = IndexBuilder::new(self);
         let vis = Spanned { span: syntax_pos::DUMMY_SP, node: hir::VisibilityKind::Public };
-        index.record(DefId::local(CRATE_DEF_INDEX),
-                     IsolatedEncoder::encode_info_for_mod,
-                     FromId(hir::CRATE_HIR_ID, (&krate.module, &krate.attrs, &vis)));
-        let mut visitor = EncodeVisitor { index };
-        krate.visit_all_item_likes(&mut visitor.as_deep_visitor());
+        self.record(DefId::local(CRATE_DEF_INDEX),
+                     EncodeContext::encode_info_for_mod,
+                     (hir::CRATE_HIR_ID, &krate.module, &krate.attrs, &vis));
+        krate.visit_all_item_likes(&mut self.as_deep_visitor());
         for macro_def in &krate.exported_macros {
-            visitor.visit_macro_def(macro_def);
+            self.visit_macro_def(macro_def);
         }
-        visitor.index.into_items()
     }
 
     fn encode_def_path_table(&mut self) -> Lazy<DefPathTable> {
@@ -371,38 +377,30 @@ fn encode_source_map(&mut self) -> LazySeq<syntax_pos::SourceFile> {
         self.lazy_seq_ref(adapted.iter().map(|rc| &**rc))
     }
 
-    fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
+    fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> {
         let mut i = self.position();
 
-        let crate_deps = self.tracked(IsolatedEncoder::encode_crate_deps, ());
-        let dylib_dependency_formats = self.tracked(
-            IsolatedEncoder::encode_dylib_dependency_formats,
-            ());
+        let crate_deps = self.encode_crate_deps();
+        let dylib_dependency_formats = self.encode_dylib_dependency_formats();
         let dep_bytes = self.position() - i;
 
         // Encode the lib features.
         i = self.position();
-        let lib_features = self.tracked(IsolatedEncoder::encode_lib_features, ());
+        let lib_features = self.encode_lib_features();
         let lib_feature_bytes = self.position() - i;
 
         // Encode the language items.
         i = self.position();
-        let lang_items = self.tracked(IsolatedEncoder::encode_lang_items, ());
-        let lang_items_missing = self.tracked(
-            IsolatedEncoder::encode_lang_items_missing,
-            ());
+        let lang_items = self.encode_lang_items();
+        let lang_items_missing = self.encode_lang_items_missing();
         let lang_item_bytes = self.position() - i;
 
         // Encode the native libraries used
         i = self.position();
-        let native_libraries = self.tracked(
-            IsolatedEncoder::encode_native_libraries,
-            ());
+        let native_libraries = self.encode_native_libraries();
         let native_lib_bytes = self.position() - i;
 
-        let foreign_modules = self.tracked(
-            IsolatedEncoder::encode_foreign_modules,
-            ());
+        let foreign_modules = self.encode_foreign_modules();
 
         // Encode source_map
         i = self.position();
@@ -416,22 +414,20 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
 
         // Encode the def IDs of impls, for coherence checking.
         i = self.position();
-        let impls = self.tracked(IsolatedEncoder::encode_impls, ());
+        let impls = self.encode_impls();
         let impl_bytes = self.position() - i;
 
         // Encode exported symbols info.
         i = self.position();
         let exported_symbols = self.tcx.exported_symbols(LOCAL_CRATE);
-        let exported_symbols = self.tracked(
-            IsolatedEncoder::encode_exported_symbols,
-            &exported_symbols);
+        let exported_symbols = self.encode_exported_symbols(&exported_symbols);
         let exported_symbols_bytes = self.position() - i;
 
         let tcx = self.tcx;
 
         // Encode the items.
         i = self.position();
-        let items = self.encode_info_for_items();
+        self.encode_info_for_items();
         let item_bytes = self.position() - i;
 
         // Encode the allocation index
@@ -462,10 +458,9 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             self.lazy_seq(interpret_alloc_index)
         };
 
-        // Index the items
         i = self.position();
-        let index = items.write_index(&mut self.opaque);
-        let index_bytes = self.position() - i;
+        let entries_index = self.entries_index.write_index(&mut self.opaque);
+        let entries_index_bytes = self.position() - i;
 
         let attrs = tcx.hir().krate_attrs();
         let is_proc_macro = tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro);
@@ -516,7 +511,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             impls,
             exported_symbols,
             interpret_alloc_index,
-            index,
+            entries_index,
         });
 
         let total_bytes = self.position();
@@ -539,7 +534,7 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
             println!("    exp. symbols bytes: {}", exported_symbols_bytes);
             println!("  def-path table bytes: {}", def_path_table_bytes);
             println!("            item bytes: {}", item_bytes);
-            println!("           index bytes: {}", index_bytes);
+            println!("   entries index bytes: {}", entries_index_bytes);
             println!("            zero bytes: {}", zero_bytes);
             println!("           total bytes: {}", total_bytes);
         }
@@ -548,40 +543,29 @@ fn encode_crate_root(&mut self) -> Lazy<CrateRoot> {
     }
 }
 
-// These are methods for encoding various things. They are meant to be used with
-// IndexBuilder::record() and EncodeContext::tracked(). They actually
-// would not have to be methods of IsolatedEncoder (free standing functions
-// taking IsolatedEncoder as first argument would be just fine) but by making
-// them methods we don't have to repeat the lengthy `<'a, 'b: 'a, 'tcx: 'b>`
-// clause again and again.
-impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
+impl EncodeContext<'_, 'tcx> {
     fn encode_variances_of(&mut self, def_id: DefId) -> LazySeq<ty::Variance> {
-        debug!("IsolatedEncoder::encode_variances_of({:?})", def_id);
+        debug!("EncodeContext::encode_variances_of({:?})", def_id);
         let tcx = self.tcx;
-        self.lazy_seq_from_slice(&tcx.variances_of(def_id))
+        self.lazy_seq_ref(&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!("IsolatedEncoder::encode_item_type({:?}) => {:?}", def_id, ty);
+        debug!("EncodeContext::encode_item_type({:?}) => {:?}", def_id, ty);
         self.lazy(&ty)
     }
 
-    /// Encode data for the given variant of the given ADT. The
-    /// index of the variant is untracked: this is ok because we
-    /// will have to lookup the adt-def by its id, and that gives us
-    /// the right to access any information in the adt-def (including,
-    /// e.g., the length of the various vectors).
     fn encode_enum_variant_info(
         &mut self,
-        (enum_did, Untracked(index)): (DefId, Untracked<VariantIdx>),
+        (enum_did, index): (DefId, VariantIdx),
     ) -> Entry<'tcx> {
         let tcx = self.tcx;
         let def = tcx.adt_def(enum_did);
         let variant = &def.variants[index];
         let def_id = variant.def_id;
-        debug!("IsolatedEncoder::encode_enum_variant_info({:?})", def_id);
+        debug!("EncodeContext::encode_enum_variant_info({:?})", def_id);
 
         let data = VariantData {
             ctor_kind: variant.ctor_kind,
@@ -625,17 +609,15 @@ fn encode_enum_variant_info(
         }
     }
 
-    /// Encode the constructor for the given variant of the given ADT. See
-    /// `encode_enum_variant_info` for an explanation about why the index is untracked.
     fn encode_enum_variant_ctor(
         &mut self,
-        (enum_did, Untracked(index)): (DefId, Untracked<VariantIdx>),
+        (enum_did, index): (DefId, VariantIdx),
     ) -> Entry<'tcx> {
         let tcx = self.tcx;
         let def = tcx.adt_def(enum_did);
         let variant = &def.variants[index];
         let def_id = variant.ctor_def_id.unwrap();
-        debug!("IsolatedEncoder::encode_enum_variant_ctor({:?})", def_id);
+        debug!("EncodeContext::encode_enum_variant_ctor({:?})", def_id);
 
         let data = VariantData {
             ctor_kind: variant.ctor_kind,
@@ -681,18 +663,17 @@ fn encode_enum_variant_ctor(
         }
     }
 
-    fn encode_info_for_mod(&mut self,
-                           FromId(id, (md, attrs, vis)): FromId<(&hir::Mod,
-                                                                 &[ast::Attribute],
-                                                                 &hir::Visibility)>)
-                           -> Entry<'tcx> {
+    fn encode_info_for_mod(
+        &mut self,
+        (id, md, attrs, vis): (hir::HirId, &hir::Mod, &[ast::Attribute], &hir::Visibility),
+    ) -> Entry<'tcx> {
         let tcx = self.tcx;
         let def_id = tcx.hir().local_def_id_from_hir_id(id);
-        debug!("IsolatedEncoder::encode_info_for_mod({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_mod({:?})", def_id);
 
         let data = ModData {
             reexports: match tcx.module_exports(def_id) {
-                Some(ref exports) => self.lazy_seq_from_slice(exports.as_slice()),
+                Some(exports) => self.lazy_seq_ref(exports),
                 _ => LazySeq::empty(),
             },
         };
@@ -719,23 +700,16 @@ fn encode_info_for_mod(&mut self,
         }
     }
 
-    /// Encode data for the given field of the given variant of the
-    /// given ADT. The indices of the variant/field are untracked:
-    /// this is ok because we will have to lookup the adt-def by its
-    /// id, and that gives us the right to access any information in
-    /// the adt-def (including, e.g., the length of the various
-    /// vectors).
-    fn encode_field(&mut self,
-                    (adt_def_id, Untracked((variant_index, field_index))): (DefId,
-                                                                            Untracked<(VariantIdx,
-                                                                                       usize)>))
-                    -> Entry<'tcx> {
+    fn encode_field(
+        &mut self,
+        (adt_def_id, variant_index, field_index): (DefId, VariantIdx, usize),
+    ) -> Entry<'tcx> {
         let tcx = self.tcx;
         let variant = &tcx.adt_def(adt_def_id).variants[variant_index];
         let field = &variant.fields[field_index];
 
         let def_id = field.did;
-        debug!("IsolatedEncoder::encode_field({:?})", def_id);
+        debug!("EncodeContext::encode_field({:?})", def_id);
 
         let variant_id = tcx.hir().as_local_hir_id(variant.def_id).unwrap();
         let variant_data = tcx.hir().expect_variant_data(variant_id);
@@ -761,7 +735,7 @@ fn encode_field(&mut self,
     }
 
     fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_struct_ctor({:?})", def_id);
+        debug!("EncodeContext::encode_struct_ctor({:?})", def_id);
         let tcx = self.tcx;
         let adt_def = tcx.adt_def(adt_def_id);
         let variant = adt_def.non_enum_variant();
@@ -821,25 +795,25 @@ fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<
     }
 
     fn encode_generics(&mut self, def_id: DefId) -> Lazy<ty::Generics> {
-        debug!("IsolatedEncoder::encode_generics({:?})", def_id);
+        debug!("EncodeContext::encode_generics({:?})", def_id);
         let tcx = self.tcx;
         self.lazy(tcx.generics_of(def_id))
     }
 
     fn encode_predicates(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
-        debug!("IsolatedEncoder::encode_predicates({:?})", def_id);
+        debug!("EncodeContext::encode_predicates({:?})", def_id);
         let tcx = self.tcx;
         self.lazy(&tcx.predicates_of(def_id))
     }
 
     fn encode_predicates_defined_on(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> {
-        debug!("IsolatedEncoder::encode_predicates_defined_on({:?})", def_id);
+        debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id);
         let tcx = self.tcx;
         self.lazy(&tcx.predicates_defined_on(def_id))
     }
 
     fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_trait_item({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_trait_item({:?})", def_id);
         let tcx = self.tcx;
 
         let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -848,15 +822,15 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
 
         let container = match trait_item.defaultness {
             hir::Defaultness::Default { has_value: true } =>
-                AssociatedContainer::TraitWithDefault,
+                AssocContainer::TraitWithDefault,
             hir::Defaultness::Default { has_value: false } =>
-                AssociatedContainer::TraitRequired,
+                AssocContainer::TraitRequired,
             hir::Defaultness::Final =>
                 span_bug!(ast_item.span, "traits cannot have final items"),
         };
 
         let kind = match trait_item.kind {
-            ty::AssociatedKind::Const => {
+            ty::AssocKind::Const => {
                 let const_qualif =
                     if let hir::TraitItemKind::Const(_, Some(body)) = ast_item.node {
                         self.const_qualif(0, body)
@@ -868,9 +842,9 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
                     hir::print::to_string(self.tcx.hir(), |s| s.print_trait_item(ast_item));
                 let rendered_const = self.lazy(&RenderedConst(rendered));
 
-                EntryKind::AssociatedConst(container, const_qualif, rendered_const)
+                EntryKind::AssocConst(container, const_qualif, rendered_const)
             }
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 let fn_data = if let hir::TraitItemKind::Method(_, ref m) = ast_item.node {
                     let arg_names = match *m {
                         hir::TraitMethod::Required(ref names) => {
@@ -894,8 +868,8 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
                     has_self: trait_item.method_has_self_argument,
                 }))
             }
-            ty::AssociatedKind::Type => EntryKind::AssociatedType(container),
-            ty::AssociatedKind::Existential =>
+            ty::AssocKind::Type => EntryKind::AssocType(container),
+            ty::AssocKind::Existential =>
                 span_bug!(ast_item.span, "existential type in trait"),
         };
 
@@ -909,21 +883,21 @@ fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> {
             deprecation: self.encode_deprecation(def_id),
 
             ty: match trait_item.kind {
-                ty::AssociatedKind::Const |
-                ty::AssociatedKind::Method => {
+                ty::AssocKind::Const |
+                ty::AssocKind::Method => {
                     Some(self.encode_item_type(def_id))
                 }
-                ty::AssociatedKind::Type => {
+                ty::AssocKind::Type => {
                     if trait_item.defaultness.has_value() {
                         Some(self.encode_item_type(def_id))
                     } else {
                         None
                     }
                 }
-                ty::AssociatedKind::Existential => unreachable!(),
+                ty::AssocKind::Existential => unreachable!(),
             },
             inherent_impls: LazySeq::empty(),
-            variances: if trait_item.kind == ty::AssociatedKind::Method {
+            variances: if trait_item.kind == ty::AssocKind::Method {
                 self.encode_variances_of(def_id)
             } else {
                 LazySeq::empty()
@@ -949,7 +923,7 @@ fn const_qualif(&self, mir: u8, body_id: hir::BodyId) -> ConstQualif {
     }
 
     fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_impl_item({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_impl_item({:?})", def_id);
         let tcx = self.tcx;
 
         let hir_id = self.tcx.hir().as_local_hir_id(def_id).unwrap();
@@ -957,25 +931,25 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
         let impl_item = self.tcx.associated_item(def_id);
 
         let container = match impl_item.defaultness {
-            hir::Defaultness::Default { has_value: true } => AssociatedContainer::ImplDefault,
-            hir::Defaultness::Final => AssociatedContainer::ImplFinal,
+            hir::Defaultness::Default { has_value: true } => AssocContainer::ImplDefault,
+            hir::Defaultness::Final => AssocContainer::ImplFinal,
             hir::Defaultness::Default { has_value: false } =>
                 span_bug!(ast_item.span, "impl items always have values (currently)"),
         };
 
         let kind = match impl_item.kind {
-            ty::AssociatedKind::Const => {
+            ty::AssocKind::Const => {
                 if let hir::ImplItemKind::Const(_, body_id) = ast_item.node {
                     let mir = self.tcx.at(ast_item.span).mir_const_qualif(def_id).0;
 
-                    EntryKind::AssociatedConst(container,
+                    EntryKind::AssocConst(container,
                         self.const_qualif(mir, body_id),
                         self.encode_rendered_const_for_body(body_id))
                 } else {
                     bug!()
                 }
             }
-            ty::AssociatedKind::Method => {
+            ty::AssocKind::Method => {
                 let fn_data = if let hir::ImplItemKind::Method(ref sig, body) = ast_item.node {
                     FnData {
                         constness: sig.header.constness,
@@ -991,8 +965,8 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
                     has_self: impl_item.method_has_self_argument,
                 }))
             }
-            ty::AssociatedKind::Existential => EntryKind::AssociatedExistential(container),
-            ty::AssociatedKind::Type => EntryKind::AssociatedType(container)
+            ty::AssocKind::Existential => EntryKind::AssocExistential(container),
+            ty::AssocKind::Type => EntryKind::AssocType(container)
         };
 
         let mir =
@@ -1022,7 +996,7 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> {
 
             ty: Some(self.encode_item_type(def_id)),
             inherent_impls: LazySeq::empty(),
-            variances: if impl_item.kind == ty::AssociatedKind::Method {
+            variances: if impl_item.kind == ty::AssocKind::Method {
                 self.encode_variances_of(def_id)
             } else {
                 LazySeq::empty()
@@ -1042,7 +1016,7 @@ fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId)
             self.lazy_seq(body.arguments.iter().map(|arg| {
                 match arg.pat.node {
                     PatKind::Binding(_, _, ident, _) => ident.name,
-                    _ => keywords::Invalid.name(),
+                    _ => kw::Invalid,
                 }
             }))
         })
@@ -1052,7 +1026,7 @@ fn encode_fn_arg_names(&mut self, param_names: &[ast::Ident]) -> LazySeq<ast::Na
         self.lazy_seq(param_names.iter().map(|ident| ident.name))
     }
 
-    fn encode_optimized_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
+    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);
@@ -1064,7 +1038,7 @@ fn encode_optimized_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>
 
     // Encodes the inherent implementations of a structure, enumeration, or trait.
     fn encode_inherent_implementations(&mut self, def_id: DefId) -> LazySeq<DefIndex> {
-        debug!("IsolatedEncoder::encode_inherent_implementations({:?})", def_id);
+        debug!("EncodeContext::encode_inherent_implementations({:?})", def_id);
         let implementations = self.tcx.inherent_impls(def_id);
         if implementations.is_empty() {
             LazySeq::empty()
@@ -1077,12 +1051,12 @@ fn encode_inherent_implementations(&mut self, def_id: DefId) -> LazySeq<DefIndex
     }
 
     fn encode_stability(&mut self, def_id: DefId) -> Option<Lazy<attr::Stability>> {
-        debug!("IsolatedEncoder::encode_stability({:?})", def_id);
+        debug!("EncodeContext::encode_stability({:?})", def_id);
         self.tcx.lookup_stability(def_id).map(|stab| self.lazy(stab))
     }
 
     fn encode_deprecation(&mut self, def_id: DefId) -> Option<Lazy<attr::Deprecation>> {
-        debug!("IsolatedEncoder::encode_deprecation({:?})", def_id);
+        debug!("EncodeContext::encode_deprecation({:?})", def_id);
         self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr))
     }
 
@@ -1096,7 +1070,7 @@ fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> Lazy<Rende
     fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) -> Entry<'tcx> {
         let tcx = self.tcx;
 
-        debug!("IsolatedEncoder::encode_info_for_item({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_item({:?})", def_id);
 
         let kind = match item.node {
             hir::ItemKind::Static(_, hir::MutMutable, _) => EntryKind::MutStatic,
@@ -1118,7 +1092,7 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                 EntryKind::Fn(self.lazy(&data))
             }
             hir::ItemKind::Mod(ref m) => {
-                return self.encode_info_for_mod(FromId(item.hir_id, (m, &item.attrs, &item.vis)));
+                return self.encode_info_for_mod((item.hir_id, m, &item.attrs, &item.vis));
             }
             hir::ItemKind::ForeignMod(_) => EntryKind::ForeignMod,
             hir::ItemKind::GlobalAsm(..) => EntryKind::GlobalAsm,
@@ -1391,9 +1365,9 @@ fn encode_info_for_generic_param(
 
     fn encode_info_for_ty_param(
         &mut self,
-        (def_id, Untracked(encode_type)): (DefId, Untracked<bool>),
+        (def_id, encode_type): (DefId, bool),
     ) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_ty_param({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_ty_param({:?})", def_id);
         self.encode_info_for_generic_param(def_id, EntryKind::TypeParam, encode_type)
     }
 
@@ -1401,12 +1375,12 @@ fn encode_info_for_const_param(
         &mut self,
         def_id: DefId,
     ) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_const_param({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_const_param({:?})", def_id);
         self.encode_info_for_generic_param(def_id, EntryKind::ConstParam, true)
     }
 
     fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_closure({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_closure({:?})", def_id);
         let tcx = self.tcx;
 
         let tables = self.tcx.typeck_tables_of(def_id);
@@ -1450,7 +1424,7 @@ fn encode_info_for_closure(&mut self, def_id: DefId) -> Entry<'tcx> {
     }
 
     fn encode_info_for_anon_const(&mut self, def_id: DefId) -> Entry<'tcx> {
-        debug!("IsolatedEncoder::encode_info_for_anon_const({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_anon_const({:?})", def_id);
         let tcx = self.tcx;
         let id = tcx.hir().as_local_hir_id(def_id).unwrap();
         let body_id = tcx.hir().body_owned_by(id);
@@ -1478,23 +1452,20 @@ fn encode_info_for_anon_const(&mut self, def_id: DefId) -> Entry<'tcx> {
     }
 
     fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> LazySeq<ast::Attribute> {
-        // NOTE: This must use lazy_seq_from_slice(), not lazy_seq() because
-        //       we rely on the HashStable specialization for [Attribute]
-        //       to properly filter things out.
-        self.lazy_seq_from_slice(attrs)
+        self.lazy_seq_ref(attrs)
     }
 
-    fn encode_native_libraries(&mut self, _: ()) -> LazySeq<NativeLibrary> {
+    fn encode_native_libraries(&mut self) -> LazySeq<NativeLibrary> {
         let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
         self.lazy_seq(used_libraries.iter().cloned())
     }
 
-    fn encode_foreign_modules(&mut self, _: ()) -> LazySeq<ForeignModule> {
+    fn encode_foreign_modules(&mut self) -> LazySeq<ForeignModule> {
         let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE);
         self.lazy_seq(foreign_modules.iter().cloned())
     }
 
-    fn encode_crate_deps(&mut self, _: ()) -> LazySeq<CrateDep> {
+    fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> {
         let crates = self.tcx.crates();
 
         let mut deps = crates
@@ -1528,13 +1499,13 @@ fn encode_crate_deps(&mut self, _: ()) -> LazySeq<CrateDep> {
         self.lazy_seq_ref(deps.iter().map(|&(_, ref dep)| dep))
     }
 
-    fn encode_lib_features(&mut self, _: ()) -> LazySeq<(ast::Name, Option<ast::Name>)> {
+    fn encode_lib_features(&mut self) -> LazySeq<(ast::Name, Option<ast::Name>)> {
         let tcx = self.tcx;
         let lib_features = tcx.lib_features();
         self.lazy_seq(lib_features.to_vec())
     }
 
-    fn encode_lang_items(&mut self, _: ()) -> LazySeq<(DefIndex, usize)> {
+    fn encode_lang_items(&mut self) -> LazySeq<(DefIndex, usize)> {
         let tcx = self.tcx;
         let lang_items = tcx.lang_items();
         let lang_items = lang_items.items().iter();
@@ -1548,14 +1519,14 @@ fn encode_lang_items(&mut self, _: ()) -> LazySeq<(DefIndex, usize)> {
         }))
     }
 
-    fn encode_lang_items_missing(&mut self, _: ()) -> LazySeq<lang_items::LangItem> {
+    fn encode_lang_items_missing(&mut self) -> LazySeq<lang_items::LangItem> {
         let tcx = self.tcx;
         self.lazy_seq_ref(&tcx.lang_items().missing)
     }
 
     /// Encodes an index, mapping each trait to its (local) implementations.
-    fn encode_impls(&mut self, _: ()) -> LazySeq<TraitImpls> {
-        debug!("IsolatedEncoder::encode_impls()");
+    fn encode_impls(&mut self) -> LazySeq<TraitImpls> {
+        debug!("EncodeContext::encode_impls()");
         let tcx = self.tcx;
         let mut visitor = ImplVisitor {
             tcx,
@@ -1580,12 +1551,12 @@ fn encode_impls(&mut self, _: ()) -> LazySeq<TraitImpls> {
 
                 TraitImpls {
                     trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
-                    impls: self.lazy_seq_from_slice(&impls[..]),
+                    impls: self.lazy_seq_ref(&impls),
                 }
             })
             .collect();
 
-        self.lazy_seq_from_slice(&all_impls[..])
+        self.lazy_seq_ref(&all_impls)
     }
 
     // Encodes all symbols exported from this crate into the metadata.
@@ -1595,13 +1566,13 @@ fn encode_impls(&mut self, _: ()) -> LazySeq<TraitImpls> {
     // symbol associated with them (they weren't translated) or if they're an FFI
     // definition (as that's not defined in this crate).
     fn encode_exported_symbols(&mut self,
-                               exported_symbols: &[(ExportedSymbol<'_>, SymbolExportLevel)])
-                               -> EncodedExportedSymbols {
+                               exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportLevel)])
+                               -> LazySeq<(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));
 
-        let lazy_seq = self.lazy_seq(exported_symbols
+        self.lazy_seq(exported_symbols
             .iter()
             .filter(|&&(ref exported_symbol, _)| {
                 match *exported_symbol {
@@ -1611,15 +1582,10 @@ fn encode_exported_symbols(&mut self,
                     _ => true,
                 }
             })
-            .cloned());
-
-        EncodedExportedSymbols {
-            len: lazy_seq.len,
-            position: lazy_seq.position,
-        }
+            .cloned())
     }
 
-    fn encode_dylib_dependency_formats(&mut self, _: ()) -> LazySeq<Option<LinkagePreference>> {
+    fn encode_dylib_dependency_formats(&mut self) -> LazySeq<Option<LinkagePreference>> {
         match self.tcx.sess.dependency_formats.borrow().get(&config::CrateType::Dylib) {
             Some(arr) => {
                 self.lazy_seq(arr.iter().map(|slot| {
@@ -1641,7 +1607,7 @@ fn encode_info_for_foreign_item(&mut self,
                                     -> Entry<'tcx> {
         let tcx = self.tcx;
 
-        debug!("IsolatedEncoder::encode_info_for_foreign_item({:?})", def_id);
+        debug!("EncodeContext::encode_info_for_foreign_item({:?})", def_id);
 
         let kind = match nitem.node {
             hir::ForeignItemKind::Fn(_, ref names, _) => {
@@ -1681,33 +1647,29 @@ fn encode_info_for_foreign_item(&mut self,
     }
 }
 
-struct EncodeVisitor<'a, 'b: 'a, 'tcx: 'b> {
-    index: IndexBuilder<'a, 'b, 'tcx>,
-}
-
-impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
+impl Visitor<'tcx> for EncodeContext<'_, 'tcx> {
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-        NestedVisitorMap::OnlyBodies(&self.index.tcx.hir())
+        NestedVisitorMap::OnlyBodies(&self.tcx.hir())
     }
     fn visit_expr(&mut self, ex: &'tcx hir::Expr) {
         intravisit::walk_expr(self, ex);
-        self.index.encode_info_for_expr(ex);
+        self.encode_info_for_expr(ex);
     }
     fn visit_item(&mut self, item: &'tcx hir::Item) {
         intravisit::walk_item(self, item);
-        let def_id = self.index.tcx.hir().local_def_id_from_hir_id(item.hir_id);
+        let def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id);
         match item.node {
             hir::ItemKind::ExternCrate(_) |
-            hir::ItemKind::Use(..) => (), // ignore these
-            _ => self.index.record(def_id, IsolatedEncoder::encode_info_for_item, (def_id, item)),
+            hir::ItemKind::Use(..) => {} // ignore these
+            _ => self.record(def_id, EncodeContext::encode_info_for_item, (def_id, item)),
         }
-        self.index.encode_addl_info_for_item(item);
+        self.encode_addl_info_for_item(item);
     }
     fn visit_foreign_item(&mut self, ni: &'tcx hir::ForeignItem) {
         intravisit::walk_foreign_item(self, ni);
-        let def_id = self.index.tcx.hir().local_def_id_from_hir_id(ni.hir_id);
-        self.index.record(def_id,
-                          IsolatedEncoder::encode_info_for_foreign_item,
+        let def_id = self.tcx.hir().local_def_id_from_hir_id(ni.hir_id);
+        self.record(def_id,
+                          EncodeContext::encode_info_for_foreign_item,
                           (def_id, ni));
     }
     fn visit_variant(&mut self,
@@ -1717,32 +1679,32 @@ fn visit_variant(&mut self,
         intravisit::walk_variant(self, v, g, id);
 
         if let Some(ref discr) = v.node.disr_expr {
-            let def_id = self.index.tcx.hir().local_def_id_from_hir_id(discr.hir_id);
-            self.index.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id);
+            let def_id = self.tcx.hir().local_def_id_from_hir_id(discr.hir_id);
+            self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
         }
     }
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
         intravisit::walk_generics(self, generics);
-        self.index.encode_info_for_generics(generics);
+        self.encode_info_for_generics(generics);
     }
     fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
         intravisit::walk_ty(self, ty);
-        self.index.encode_info_for_ty(ty);
+        self.encode_info_for_ty(ty);
     }
     fn visit_macro_def(&mut self, macro_def: &'tcx hir::MacroDef) {
-        let def_id = self.index.tcx.hir().local_def_id_from_hir_id(macro_def.hir_id);
-        self.index.record(def_id, IsolatedEncoder::encode_info_for_macro_def, macro_def);
+        let def_id = self.tcx.hir().local_def_id_from_hir_id(macro_def.hir_id);
+        self.record(def_id, EncodeContext::encode_info_for_macro_def, macro_def);
     }
 }
 
-impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
+impl EncodeContext<'_, 'tcx> {
     fn encode_fields(&mut self, adt_def_id: DefId) {
         let def = self.tcx.adt_def(adt_def_id);
         for (variant_index, variant) in def.variants.iter_enumerated() {
             for (field_index, field) in variant.fields.iter().enumerate() {
                 self.record(field.did,
-                            IsolatedEncoder::encode_field,
-                            (adt_def_id, Untracked((variant_index, field_index))));
+                            EncodeContext::encode_field,
+                            (adt_def_id, variant_index, field_index));
             }
         }
     }
@@ -1755,12 +1717,12 @@ fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
                 GenericParamKind::Type { ref default, .. } => {
                     self.record(
                         def_id,
-                        IsolatedEncoder::encode_info_for_ty_param,
-                        (def_id, Untracked(default.is_some())),
+                        EncodeContext::encode_info_for_ty_param,
+                        (def_id, default.is_some()),
                     );
                 }
                 GenericParamKind::Const { .. } => {
-                    self.record(def_id, IsolatedEncoder::encode_info_for_const_param, def_id);
+                    self.record(def_id, EncodeContext::encode_info_for_const_param, def_id);
                 }
             }
         }
@@ -1770,7 +1732,7 @@ fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
         match ty.node {
             hir::TyKind::Array(_, ref length) => {
                 let def_id = self.tcx.hir().local_def_id_from_hir_id(length.hir_id);
-                self.record(def_id, IsolatedEncoder::encode_info_for_anon_const, def_id);
+                self.record(def_id, EncodeContext::encode_info_for_anon_const, def_id);
             }
             _ => {}
         }
@@ -1780,7 +1742,7 @@ fn encode_info_for_expr(&mut self, expr: &hir::Expr) {
         match expr.node {
             hir::ExprKind::Closure(..) => {
                 let def_id = self.tcx.hir().local_def_id_from_hir_id(expr.hir_id);
-                self.record(def_id, IsolatedEncoder::encode_info_for_closure, def_id);
+                self.record(def_id, EncodeContext::encode_info_for_closure, def_id);
             }
             _ => {}
         }
@@ -1812,13 +1774,13 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
                 let def = self.tcx.adt_def(def_id);
                 for (i, variant) in def.variants.iter_enumerated() {
                     self.record(variant.def_id,
-                                IsolatedEncoder::encode_enum_variant_info,
-                                (def_id, Untracked(i)));
+                                EncodeContext::encode_enum_variant_info,
+                                (def_id, i));
 
                     if let Some(ctor_def_id) = variant.ctor_def_id {
                         self.record(ctor_def_id,
-                                    IsolatedEncoder::encode_enum_variant_ctor,
-                                    (def_id, Untracked(i)));
+                                    EncodeContext::encode_enum_variant_ctor,
+                                    (def_id, i));
                     }
                 }
             }
@@ -1829,7 +1791,7 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
                 if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
                     let ctor_def_id = self.tcx.hir().local_def_id_from_hir_id(ctor_hir_id);
                     self.record(ctor_def_id,
-                                IsolatedEncoder::encode_struct_ctor,
+                                EncodeContext::encode_struct_ctor,
                                 (def_id, ctor_def_id));
                 }
             }
@@ -1839,14 +1801,14 @@ fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
             hir::ItemKind::Impl(..) => {
                 for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
                     self.record(trait_item_def_id,
-                                IsolatedEncoder::encode_info_for_impl_item,
+                                EncodeContext::encode_info_for_impl_item,
                                 trait_item_def_id);
                 }
             }
             hir::ItemKind::Trait(..) => {
                 for &item_def_id in self.tcx.associated_item_def_ids(def_id).iter() {
                     self.record(item_def_id,
-                                IsolatedEncoder::encode_info_for_trait_item,
+                                EncodeContext::encode_info_for_trait_item,
                                 item_def_id);
                 }
             }
@@ -1911,10 +1873,13 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
     // Will be filled with the root position after encoding everything.
     encoder.emit_raw_bytes(&[0, 0, 0, 0]);
 
-    let (root, mut result) = {
+    // Since encoding metadata is not in a query, and nothing is cached,
+    // there's no need to do dep-graph tracking for any of it.
+    let (root, mut result) = tcx.dep_graph.with_ignore(move || {
         let mut ecx = EncodeContext {
             opaque: encoder,
             tcx,
+            entries_index: Index::new(tcx.hir().definitions().def_index_count()),
             lazy_state: LazyState::NoNode,
             type_shorthands: Default::default(),
             predicate_shorthands: Default::default(),
@@ -1930,7 +1895,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>)
         // culminating in the `CrateRoot` which points to all of it.
         let root = ecx.encode_crate_root();
         (root, ecx.opaque.into_inner())
-    };
+    });
 
     // Encode the root position.
     let header = METADATA_HEADER.len();