about summary refs log tree commit diff
path: root/src/librustc_metadata
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-07-04 09:33:33 +0000
committerbors <bors@rust-lang.org>2018-07-04 09:33:33 +0000
commit8dd715ee5e462384668e3c83c17ee641e9776b64 (patch)
tree7174b02139c75cca14582615e9615758dd723971 /src/librustc_metadata
parenta739c51d108b1958a1c3e145588035c580e7973a (diff)
parent90ea49b891937eb7f121c1ded01ceacb66074e74 (diff)
downloadrust-8dd715ee5e462384668e3c83c17ee641e9776b64.tar.gz
rust-8dd715ee5e462384668e3c83c17ee641e9776b64.zip
Auto merge of #51895 - nikomatsakis:move-self-trait-predicate-to-items, r=scalexm
Move self trait predicate to items

This is a "reimagination" of @tmandry's PR #50183. The main effect is described in this comment from one of the commits:

---

Before we had the following results for `predicates_of`:

```rust
trait Foo { // predicates_of: Self: Foo
  fn bar(); // predicates_of: Self: Foo (inherited from trait)
}
```

Now we have removed the `Self: Foo` from the trait. However, we still
add it to the trait ITEM. This is because when people do things like
`<T as Foo>::bar()`, they still need to prove that `T: Foo`, and
having it in the `predicates_of` seems to be the cleanest way to
ensure that happens right now (otherwise, we'd need special case code
in various places):

```rust
trait Foo { // predicates_of: []
  fn bar(); // predicates_of: Self: Foo
}
```

However, we sometimes want to get the list of *just* the predicates
truly defined on a trait item (e.g., for chalk, but also for a few
other bits of code). For that, we define `predicates_defined_on`,
which does not contain the `Self: Foo` predicate yet, and we plumb
that through metadata and so forth.

---

I'm assigning @eddyb as the main reviewer, but I thought I might delegate to scalexm for this one in any case. I also want to post an alternative that I'll leave in the comments; it occurred to me as I was writing. =)

r? @eddyb
cc @scalexm @tmandry @leodasvacas
Diffstat (limited to 'src/librustc_metadata')
-rw-r--r--src/librustc_metadata/cstore_impl.rs1
-rw-r--r--src/librustc_metadata/decoder.rs7
-rw-r--r--src/librustc_metadata/encoder.rs27
-rw-r--r--src/librustc_metadata/schema.rs2
4 files changed, 37 insertions, 0 deletions
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 23da82f5a45..20d9121668b 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -107,6 +107,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
         tcx.alloc_generics(cdata.get_generics(def_id.index, tcx.sess))
     }
     predicates_of => { cdata.get_predicates(def_id.index, tcx) }
+    predicates_defined_on => { cdata.get_predicates_defined_on(def_id.index, tcx) }
     super_predicates_of => { cdata.get_super_predicates(def_id.index, tcx) }
     trait_def => {
         tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx.sess))
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 1985900b3e1..d604ac819b8 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -563,6 +563,13 @@ impl<'a, 'tcx> CrateMetadata {
         self.entry(item_id).predicates.unwrap().decode((self, tcx))
     }
 
+    pub fn get_predicates_defined_on(&self,
+                                   item_id: DefIndex,
+                                   tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                                   -> ty::GenericPredicates<'tcx> {
+        self.entry(item_id).predicates_defined_on.unwrap().decode((self, tcx))
+    }
+
     pub fn get_super_predicates(&self,
                                 item_id: DefIndex,
                                 tcx: TyCtxt<'a, 'tcx, 'tcx>)
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 3cfde7a8297..36f053e5aa9 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -629,6 +629,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             },
             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),
         }
@@ -666,6 +667,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             variances: LazySeq::empty(),
             generics: None,
             predicates: None,
+            predicates_defined_on: None,
 
             mir: None
         }
@@ -706,6 +708,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             variances: LazySeq::empty(),
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: None,
         }
@@ -763,6 +766,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             },
             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),
         }
@@ -780,6 +784,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, '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);
+        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);
         let tcx = self.tcx;
@@ -869,6 +879,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             },
             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),
         }
@@ -965,6 +976,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             },
             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 },
         }
@@ -1228,6 +1240,16 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                 _ => None,
             },
 
+            // The only time that `predicates_defined_on` is used (on
+            // an external item) is for traits, during chalk lowering,
+            // so only encode it in that case as an efficiency
+            // hack. (No reason not to expand it in the future if
+            // necessary.)
+            predicates_defined_on: match item.node {
+                hir::ItemTrait(..) => Some(self.encode_predicates_defined_on(def_id)),
+                _ => None, // not *wrong* for other kinds of items, but not needed
+            },
+
             mir: match item.node {
                 hir::ItemStatic(..) => {
                     self.encode_optimized_mir(def_id)
@@ -1278,6 +1300,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             variances: LazySeq::empty(),
             generics: None,
             predicates: None,
+            predicates_defined_on: None,
             mir: None,
         }
     }
@@ -1305,6 +1328,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             variances: LazySeq::empty(),
             generics: None,
             predicates: None,
+            predicates_defined_on: None,
 
             mir: None,
         }
@@ -1349,6 +1373,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             variances: LazySeq::empty(),
             generics: Some(self.encode_generics(def_id)),
             predicates: None,
+            predicates_defined_on: None,
 
             mir: self.encode_optimized_mir(def_id),
         }
@@ -1376,6 +1401,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             variances: LazySeq::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),
         }
@@ -1577,6 +1603,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
             },
             generics: Some(self.encode_generics(def_id)),
             predicates: Some(self.encode_predicates(def_id)),
+            predicates_defined_on: None,
 
             mir: None,
         }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 21d6d15457a..a0b21e63ac5 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -273,6 +273,7 @@ pub struct Entry<'tcx> {
     pub variances: LazySeq<ty::Variance>,
     pub generics: Option<Lazy<ty::Generics>>,
     pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
+    pub predicates_defined_on: Option<Lazy<ty::GenericPredicates<'tcx>>>,
 
     pub mir: Option<Lazy<mir::Mir<'tcx>>>,
 }
@@ -290,6 +291,7 @@ impl_stable_hash_for!(struct Entry<'tcx> {
     variances,
     generics,
     predicates,
+    predicates_defined_on,
     mir
 });