@@ -5,7 +5,7 @@ Most everything in the IR is parameterized by the [`Interner`] trait:
5
5
[ `Interner` ] : http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html
6
6
7
7
``` rust,ignore
8
- trait Interner: Copy + Clone + Debug + Eq + Ord {
8
+ trait Interner: Copy + Clone + Debug + Eq + Ord {
9
9
..
10
10
}
11
11
```
@@ -16,3 +16,72 @@ the interner is defined by the embedded and can be used to control
16
16
other things in memory. For example, the ` Interner ` trait could be
17
17
used to intern all the types, as rustc does, or it could be used to
18
18
` Box ` them instead, as the chalk testing harness currently does.
19
+
20
+ ### Controlling representation with ` Interner `
21
+
22
+ The purpose of the [ ` Interner ` ] trait is to give control over how
23
+ types and other bits of chalk-ir are represented in memory. This is
24
+ done via an "indirection" strategy. We'll explain that strategy here
25
+ in terms of [ ` Ty ` ] and [ ` TyData ` ] , the two types used to represent
26
+ Rust types, but the same pattern is repeated for many other things.
27
+
28
+ [ `Interner` ] : http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html
29
+ [ `Ty` ] : http://rust-lang.github.io/chalk/chalk_ir/struct.Ty.html
30
+ [ `TyData` ] : http://rust-lang.github.io/chalk/chalk_ir/enum.TyData.html
31
+
32
+ Types are represented by a [ ` Ty<I> ` ] type and the [ ` TyData<I> ` ] enum.
33
+ There is no * direct* connection between them. The link is rather made
34
+ by the [ ` Interner ` ] trait, via the [ ` InternedTy ` ] associated type:
35
+
36
+ [ `Ty<I>` ] : http://rust-lang.github.io/chalk/chalk_ir/struct.Ty.html
37
+ [ `TyData<I>` ] : http://rust-lang.github.io/chalk/chalk_ir/enum.TyData.html
38
+ [ `InternedTy` ] : http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html#associatedtype.InternedType
39
+
40
+ ``` rust,ignore
41
+ struct Ty<I: Interner>(I::InternedTy);
42
+ enum TyData<I: Interner> { .. }
43
+ ```
44
+
45
+ The way this works is that the [ ` Interner ` ] trait has an associated
46
+ type [ ` InternedTy ` ] and two related methods, [ ` intern_ty ` ] and [ ` ty_data ` ] :
47
+
48
+ [ `intern_ty` ] : http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html#tymethod.intern_ty
49
+ [ `ty_data` ] : http://rust-lang.github.io/chalk/chalk_ir/interner/trait.Interner.html#tymethod.ty_data
50
+
51
+ ``` rust,ignore
52
+ trait Interner {
53
+ type InternedTy;
54
+
55
+ fn intern_ty(&self, data: &TyData<Self>) -> Self::InternedTy;
56
+ fn ty_data(data: &Self::InternedTy) -> &TyData<Self>;
57
+ }
58
+ ```
59
+
60
+ However, as a user you are not meant to use these directly. Rather,
61
+ they are encapsulated in methods on the [ ` Ty ` ] and [ ` TyData ` ] types:
62
+
63
+ ``` rust,ignore
64
+ impl<I: Interner> Ty<I> {
65
+ fn data(&self) -> &TyData<I> {
66
+ I::lookup_ty(self)
67
+ }
68
+ }
69
+ ```
70
+
71
+ and
72
+
73
+ ``` rust,ignore
74
+ impl<I: Interner> TyData<I> {
75
+ fn intern(&self, I: &I) -> Ty<I> {
76
+ Ty(i.intern_ty(self))
77
+ }
78
+ }
79
+ ```
80
+
81
+ Note that there is an assumption here that [ ` ty_data ` ] needs no
82
+ context. This effectively constrains the [ ` InternedTy ` ] representation
83
+ to be a ` Box ` or ` & ` type. To be more general, at the cost of some
84
+ convenience, we could make that a method as well, so that one would
85
+ invoke ` ty.data(i) ` instead of just ` ty.data() ` . This would permit us
86
+ to use (for example) integers to represent interned types, which might
87
+ be nice (e.g., to permit using generational indices).
0 commit comments