@@ -174,6 +174,80 @@ we must show that `WellFormed(TraitRef)`. This in turn justifies the
174
174
implied bounds rules that allow us to extend the set of ` FromEnv `
175
175
items.
176
176
177
+ ## Lowering type definitions
178
+
179
+ We also want to have some rules which define when a type is well-formed.
180
+ For example, given this type:
181
+
182
+ ``` rust,ignore
183
+ struct Set<K> where K: Hash { ... }
184
+ ```
185
+
186
+ then ` Set<i32> ` is well-formed because ` i32 ` implements ` Hash ` , but
187
+ ` Set<NotHash> ` would not be well-formed. Basically, a type is well-formed
188
+ if its parameters verify the where clauses written on the type definition.
189
+
190
+ Hence, for every type definition:
191
+
192
+ ``` rust, ignore
193
+ struct Type<P1..Pn> where WC { ... }
194
+ ```
195
+
196
+ we produce the following rule:
197
+
198
+ ``` text
199
+ // Rule WellFormed-Type
200
+ forall<P1..Pn> {
201
+ WellFormed(Type<P1..Pn>) :- WC
202
+ }
203
+ ```
204
+
205
+ Note that we use ` struct ` for defining a type, but this should be understood
206
+ as a general type definition (it could be e.g. a generic ` enum ` ).
207
+
208
+ Conversely, we define rules which say that if we assume that a type is
209
+ well-formed, we can also assume that its where clauses hold. That is,
210
+ we produce the following family of rules:
211
+
212
+ ``` text
213
+ // Rule FromEnv-Type
214
+ //
215
+ // For each where clause `WC`
216
+ forall<P1..Pn> {
217
+ FromEnv(WC) :- FromEnv(Type<P1..Pn>)
218
+ }
219
+ ```
220
+
221
+ As for the implied bounds RFC, functions will * assume* that their arguments
222
+ are well-formed. For example, suppose we have the following bit of code:
223
+
224
+ ``` rust,ignore
225
+ trait Hash: Eq { }
226
+ struct Set<K: Hash> { ... }
227
+
228
+ fn foo<K>(collection: Set<K>, x: K, y: K) {
229
+ // `x` and `y` can be equalized even if we did not explicitly write
230
+ // `where K: Eq`
231
+ if x == y {
232
+ ...
233
+ }
234
+ }
235
+ ```
236
+
237
+ in the ` foo ` function, we assume that ` Set<K> ` is well-formed, i.e. we have
238
+ ` FromEnv(Set<K>) ` in our environment. Because of the previous rule, we get
239
+ ` FromEnv(K: Hash) ` without needing an explicit where clause. And because
240
+ of the ` Hash ` trait definition, there also exists a rule which says:
241
+
242
+ ``` text
243
+ forall<K> {
244
+ FromEnv(K: Eq) :- FromEnv(K: Hash)
245
+ }
246
+ ```
247
+
248
+ which means that we finally get ` FromEnv(K: Eq) ` and then can compare ` x `
249
+ and ` y ` without needing an explicit where clause.
250
+
177
251
<a name =" trait-items " ></a >
178
252
179
253
## Lowering trait items
@@ -333,4 +407,4 @@ Chalk didn't model functions and constants, but I would eventually
333
407
like to treat them exactly like normalization. This presumably
334
408
involves adding a new kind of parameter (constant), and then having a
335
409
` NormalizeValue ` domain goal. This is * to be written* because the
336
- details are a bit up in the air.
410
+ details are a bit up in the air.
0 commit comments