]> git.lizzy.rs Git - rust.git/commitdiff
remove `usize: DepGraphRead` and add `Untracked`
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 16 Aug 2016 15:42:30 +0000 (11:42 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Wed, 17 Aug 2016 19:21:59 +0000 (15:21 -0400)
The idea is that a `usize` is sort of ambiguous: in this case, it
represents indices that do not need tracking, but it could as easily be
some data read out from a tracked location, and hence represent tracked
data. Therefore, we add an `Untracked` type that lets user assert
that value is not tracked.

Also correct various typos.

src/librustc_metadata/encoder.rs
src/librustc_metadata/index_builder.rs

index 7f7b87fb880b4998ed7172faf8578dc018ed4028..791d090273ffca9ca3221a4999da39b1ecc92771 100644 (file)
@@ -53,7 +53,7 @@
 use rustc::hir::intravisit;
 use rustc::hir::map::DefKey;
 
-use super::index_builder::{FromId, IndexBuilder, ItemContentBuilder, XRef};
+use super::index_builder::{FromId, IndexBuilder, ItemContentBuilder, Untracked, XRef};
 
 pub struct EncodeContext<'a, 'tcx: 'a> {
     pub diag: &'a Handler,
@@ -206,15 +206,20 @@ fn encode_enum_variant_infos(&mut self,
         for (i, variant) in def.variants.iter().enumerate() {
             self.record(variant.did,
                         ItemContentBuilder::encode_enum_variant_info,
-                        (enum_did, i));
+                        (enum_did, Untracked(i)));
         }
     }
 }
 
 impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
+    /// 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, index):
-                                (DefId, usize)) {
+                                (enum_did, Untracked(index)):
+                                (DefId, Untracked<usize>)) {
         let ecx = self.ecx;
         let def = ecx.tcx.lookup_adt_def(enum_did);
         let variant = &def.variants[index];
@@ -420,16 +425,22 @@ fn encode_fields(&mut self,
             for (field_index, field) in variant.fields.iter().enumerate() {
                 self.record(field.did,
                             ItemContentBuilder::encode_field,
-                            (adt_def_id, variant_index, field_index));
+                            (adt_def_id, Untracked((variant_index, field_index))));
             }
         }
     }
 }
 
 impl<'a, 'tcx, 'encoder> ItemContentBuilder<'a, 'tcx, 'encoder> {
+    /// 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, variant_index, field_index):
-                    (DefId, usize, usize)) {
+                    (adt_def_id, Untracked((variant_index, field_index))):
+                    (DefId, Untracked<(usize, usize)>)) {
         let ecx = self.ecx();
         let def = ecx.tcx.lookup_adt_def(adt_def_id);
         let variant = &def.variants[variant_index];
index 37f29696808ef2f7a8dd81ce3a4c7cb0301124bf..1d3d09d6bc2d798871df777ef59f349240e7833f 100644 (file)
 //!
 //! In addition to the offset, we need to track the data that was used
 //! to generate the contents of each `data_item`. This is so that we
-//! can figure out which HIR nodes contributors to that data for
+//! can figure out which HIR nodes contributed to that data for
 //! incremental compilation purposes.
 //!
-//! The `IndexBuilder` facilitates with both of these. It is created
+//! The `IndexBuilder` facilitates both of these. It is created
 //! with an RBML encoder isntance (`rbml_w`) along with an
 //! `EncodingContext` (`ecx`), which it encapsulates. It has one main
 //! method, `record()`. You invoke `record` like so to create a new
@@ -166,10 +166,6 @@ pub trait DepGraphRead {
     fn read(&self, tcx: TyCtxt);
 }
 
-impl DepGraphRead for usize {
-    fn read(&self, _tcx: TyCtxt) { }
-}
-
 impl DepGraphRead for DefId {
     fn read(&self, _tcx: TyCtxt) { }
 }
@@ -229,6 +225,21 @@ fn read(&self, tcx: TyCtxt) {
 read_hir!(hir::TraitItem);
 read_hir!(hir::ForeignItem);
 
+/// Leaks access to a value of type T without any tracking. This is
+/// suitable for ambiguous types like `usize`, which *could* represent
+/// tracked data (e.g., if you read it out of a HIR node) or might not
+/// (e.g., if it's an index). Adding in an `Untracked` is an
+/// assertion, essentially, that the data does not need to be tracked
+/// (or that read edges will be added by some other way).
+///
+/// A good idea is to add to each use of `Untracked` an explanation of
+/// why this value is ok.
+pub struct Untracked<T>(pub T);
+
+impl<T> DepGraphRead for Untracked<T> {
+    fn read(&self, _tcx: TyCtxt) { }
+}
+
 /// Newtype that can be used to package up misc data extracted from a
 /// HIR node that doesn't carry its own id. This will allow an
 /// arbitrary `T` to be passed in, but register a read on the given