about summary refs log tree commit diff
path: root/src/doc/rustc-dev-guide
diff options
context:
space:
mode:
authorscalexm <martin.alex32@hotmail.fr>2018-06-07 12:13:40 +0200
committerWho? Me?! <mark-i-m@users.noreply.github.com>2018-06-12 18:20:35 -0500
commit08dfae74c71706bbf1ff7e08e7e7e81f3750710b (patch)
treeff77f1040ab93e6de54642c0b9d20057265940a6 /src/doc/rustc-dev-guide
parent79b4ec2639d4f86eb3c5828003bc0aa7118c9928 (diff)
downloadrust-08dfae74c71706bbf1ff7e08e7e7e81f3750710b.tar.gz
rust-08dfae74c71706bbf1ff7e08e7e7e81f3750710b.zip
Add chalk rules for type defs
Diffstat (limited to 'src/doc/rustc-dev-guide')
-rw-r--r--src/doc/rustc-dev-guide/src/traits/lowering-rules.md76
1 files changed, 75 insertions, 1 deletions
diff --git a/src/doc/rustc-dev-guide/src/traits/lowering-rules.md b/src/doc/rustc-dev-guide/src/traits/lowering-rules.md
index f635ee85769..e3febd9f27a 100644
--- a/src/doc/rustc-dev-guide/src/traits/lowering-rules.md
+++ b/src/doc/rustc-dev-guide/src/traits/lowering-rules.md
@@ -174,6 +174,80 @@ we must show that `WellFormed(TraitRef)`. This in turn justifies the
 implied bounds rules that allow us to extend the set of `FromEnv`
 items.
 
+## Lowering type definitions
+
+We also want to have some rules which define when a type is well-formed.
+For example, given this type:
+
+```rust,ignore
+struct Set<K> where K: Hash { ... }
+```
+
+then `Set<i32>` is well-formed because `i32` implements `Hash`, but
+`Set<NotHash>` would not be well-formed. Basically, a type is well-formed
+if its parameters verify the where clauses written on the type definition.
+
+Hence, for every type definition:
+
+```rust, ignore
+struct Type<P1..Pn> where WC { ... }
+```
+
+we produce the following rule:
+
+```text
+// Rule WellFormed-Type
+forall<P1..Pn> {
+  WellFormed(Type<P1..Pn>) :- WC
+}
+```
+
+Note that we use `struct` for defining a type, but this should be understood
+as a general type definition (it could be e.g. a generic `enum`).
+
+Conversely, we define rules which say that if we assume that a type is
+well-formed, we can also assume that its where clauses hold. That is,
+we produce the following family of rules:
+
+```text
+// Rule FromEnv-Type
+//
+// For each where clause `WC`
+forall<P1..Pn> {
+  FromEnv(WC) :- FromEnv(Type<P1..Pn>)
+}
+```
+
+As for the implied bounds RFC, functions will *assume* that their arguments
+are well-formed. For example, suppose we have the following bit of code:
+
+```rust,ignore
+trait Hash: Eq { }
+struct Set<K: Hash> { ... }
+
+fn foo<K>(collection: Set<K>, x: K, y: K) {
+    // `x` and `y` can be equalized even if we did not explicitly write
+    // `where K: Eq`
+    if x == y {
+        ...
+    }
+}
+```
+
+in the `foo` function, we assume that `Set<K>` is well-formed, i.e. we have
+`FromEnv(Set<K>)` in our environment. Because of the previous rule, we get
+ `FromEnv(K: Hash)` without needing an explicit where clause. And because
+of the `Hash` trait definition, there also exists a rule which says:
+
+```text
+forall<K> {
+  FromEnv(K: Eq) :- FromEnv(K: Hash)
+}
+```
+
+which means that we finally get `FromEnv(K: Eq)` and then can compare `x`
+and `y` without needing an explicit where clause.
+
 <a name="trait-items"></a>
 
 ## Lowering trait items
@@ -333,4 +407,4 @@ Chalk didn't model functions and constants, but I would eventually
 like to treat them exactly like normalization. This presumably
 involves adding a new kind of parameter (constant), and then having a
 `NormalizeValue` domain goal. This is *to be written* because the
-details are a bit up in the air.
+details are a bit up in the air.
\ No newline at end of file