1
1
# Caching and subtle considerations therewith
2
2
3
- In general we attempt to cache the results of trait selection. This
3
+ In general, we attempt to cache the results of trait selection. This
4
4
is a somewhat complex process. Part of the reason for this is that we
5
5
want to be able to cache results even when all the types in the trait
6
6
reference are not fully known. In that case, it may happen that the
@@ -12,37 +12,43 @@ but *replay* its effects on the type variables.
12
12
13
13
The high-level idea of how the cache works is that we first replace
14
14
all unbound inference variables with skolemized versions. Therefore,
15
- if we had a trait reference ` usize : Foo<$1> ` , where ` $n ` is an unbound
16
- inference variable, we might replace it with ` usize : Foo<%0> ` , where
17
- ` %n ` is a skolemized type. We would then look this up in the cache.
15
+ if we had a trait reference ` usize : Foo<$t> ` , where ` $t ` is an unbound
16
+ inference variable, we might replace it with ` usize : Foo<$0> ` , where
17
+ ` $0 ` is a skolemized type. We would then look this up in the cache.
18
+
18
19
If we found a hit, the hit would tell us the immediate next step to
19
- take in the selection process: i.e. apply impl #22 , or apply where
20
- clause ` X : Foo<Y> ` . Let's say in this case there is no hit.
21
- Therefore, we search through impls and where clauses and so forth, and
22
- we come to the conclusion that the only possible impl is this one,
23
- with def-id 22:
20
+ take in the selection process (e.g. apply impl #22 , or apply where
21
+ clause ` X : Foo<Y> ` ).
22
+
23
+ On the other hand, if there is no hit, we need to go through the [ selection
24
+ process] from scratch. Suppose, we come to the conclusion that the only
25
+ possible impl is this one, with def-id 22:
26
+
27
+ [ selection process ] : ./trait-resolution.html#selection
24
28
25
29
``` rust
26
30
impl Foo <isize > for usize { ... } // Impl #22
27
31
```
28
32
29
- We would then record in the cache `usize : Foo<%0> ==>
30
- ImplCandidate(22)` . Next we would confirm ` ImplCandidate(22)`, which
31
- would (as a side-effect) unify ` $1 ` with ` isize ` .
33
+ We would then record in the cache ` usize : Foo<$0> => ImplCandidate(22) ` . Next
34
+ we would [ confirm] ` ImplCandidate(22) ` , which would (as a side-effect) unify
35
+ ` $t ` with ` isize ` .
36
+
37
+ [ confirm ] : ./trait-resolution.html#confirmation
32
38
33
39
Now, at some later time, we might come along and see a `usize :
34
- Foo<$3 >` . When skolemized, this would yield ` usize : Foo<% 0>`, just as
40
+ Foo<$u >` . When skolemized, this would yield ` usize : Foo<$ 0>`, just as
35
41
before, and hence the cache lookup would succeed, yielding
36
42
` ImplCandidate(22) ` . We would confirm ` ImplCandidate(22) ` which would
37
- (as a side-effect) unify ` $3 ` with ` isize ` .
43
+ (as a side-effect) unify ` $u ` with ` isize ` .
38
44
39
45
## Where clauses and the local vs global cache
40
46
41
47
One subtle interaction is that the results of trait lookup will vary
42
48
depending on what where clauses are in scope. Therefore, we actually
43
49
have * two* caches, a local and a global cache. The local cache is
44
- attached to the ` ParamEnv ` and the global cache attached to the
45
- ` tcx ` . We use the local cache whenever the result might depend on the
50
+ attached to the [ ` ParamEnv ` ] , and the global cache attached to the
51
+ [ ` tcx ` ] . We use the local cache whenever the result might depend on the
46
52
where clauses that are in scope. The determination of which cache to
47
53
use is done by the method ` pick_candidate_cache ` in ` select.rs ` . At
48
54
the moment, we use a very simple, conservative rule: if there are any
@@ -51,3 +57,9 @@ and draw finer-grained distinctions, but that led to a serious of
51
57
annoying and weird bugs like #22019 and #18290 . This simple rule seems
52
58
to be pretty clearly safe and also still retains a very high hit rate
53
59
(~ 95% when compiling rustc).
60
+
61
+ ** TODO** : it looks like ` pick_candidate_cache ` no longer exists. In
62
+ general, is this section still accurate at all?
63
+
64
+ [ `ParamEnv` ] : ./param_env.html
65
+ [ `tcx` ] : ./ty.html
0 commit comments