1
1
# Higher-ranked trait bounds
2
2
3
- One of the more subtle concepts at work are * higher-ranked trait
3
+ One of the more subtle concepts in trait resolution is * higher-ranked trait
4
4
bounds* . An example of such a bound is ` for<'a> MyTrait<&'a isize> ` .
5
5
Let's walk through how selection on higher-ranked trait references
6
6
works.
7
7
8
8
## Basic matching and skolemization leaks
9
9
10
- Let's walk through the test ` compile-fail/hrtb-just-for-static.rs ` to see
11
- how it works. The test starts with the trait ` Foo ` :
10
+ Suppose we have a trait ` Foo ` :
12
11
13
12
``` rust
14
13
trait Foo <X > {
@@ -33,25 +32,34 @@ impl<'a> Foo<&'a isize> for AnyInt { }
33
32
34
33
And the question is, does ` AnyInt : for<'a> Foo<&'a isize> ` ? We want the
35
34
answer to be yes. The algorithm for figuring it out is closely related
36
- to the subtyping for higher-ranked types (which is described in
37
- ` middle::infer::higher_ranked::doc ` , but also in a [ paper by SPJ] that
38
- I recommend you read).
35
+ to the subtyping for higher-ranked types (which is described in [ here ] [ hrsubtype ]
36
+ and also in a [ paper by SPJ] . If you wish to understand higher-ranked
37
+ subtyping, we recommend you read the paper). There are a few parts:
39
38
40
- 1 . Skolemize the obligation.
39
+ ** TODO** : We should define _ skolemize_ .
40
+
41
+ 1 . _ Skolemize_ the obligation.
41
42
2 . Match the impl against the skolemized obligation.
42
- 3 . Check for skolemization leaks .
43
+ 3 . Check for _ skolemization leaks _ .
43
44
45
+ [ hrsubtype ] : https://github.com/rust-lang/rust/tree/master/src/librustc/infer/higher_ranked/README.md
44
46
[ paper by SPJ ] : http://research.microsoft.com/en-us/um/people/simonpj/papers/higher-rank/
45
47
46
- So let's work through our example. The first thing we would do is to
48
+ So let's work through our example.
49
+
50
+ 1 . The first thing we would do is to
47
51
skolemize the obligation, yielding ` AnyInt : Foo<&'0 isize> ` (here ` '0 `
48
- represents skolemized region #0 ). Note that now have no quantifiers;
52
+ represents skolemized region #0 ). Note that we now have no quantifiers;
49
53
in terms of the compiler type, this changes from a ` ty::PolyTraitRef `
50
54
to a ` TraitRef ` . We would then create the ` TraitRef ` from the impl,
51
55
using fresh variables for it's bound regions (and thus getting
52
- ` Foo<&'$a isize> ` , where ` '$a ` is the inference variable for ` 'a ` ). Next
56
+ ` Foo<&'$a isize> ` , where ` '$a ` is the inference variable for ` 'a ` ).
57
+
58
+ 2 . Next
53
59
we relate the two trait refs, yielding a graph with the constraint
54
- that ` '0 == '$a ` . Finally, we check for skolemization "leaks" – a
60
+ that ` '0 == '$a ` .
61
+
62
+ 3 . Finally, we check for skolemization "leaks" – a
55
63
leak is basically any attempt to relate a skolemized region to another
56
64
skolemized region, or to any region that pre-existed the impl match.
57
65
The leak check is done by searching from the skolemized region to find
@@ -75,6 +83,8 @@ skolemized to `'0` and the impl trait reference is instantiated to
75
83
like ` 'static == '0 ` . This means that the taint set for ` '0 ` is `{'0,
76
84
'static}`, which fails the leak check.
77
85
86
+ ** TODO** : This is because ` 'static ` is not a region variable but is in the taint set, right?
87
+
78
88
## Higher-ranked trait obligations
79
89
80
90
Once the basic matching is done, we get to another interesting topic:
@@ -96,9 +106,9 @@ impl<X,F> Foo<X> for F
96
106
}
97
107
```
98
108
99
- Now let's say we have a obligation ` for<'a> Foo<&'a isize> ` and we match
109
+ Now let's say we have a obligation ` Baz: for<'a> Foo<&'a isize>` and we match
100
110
this impl. What obligation is generated as a result? We want to get
101
- ` for<'a> Bar<&'a isize> ` , but how does that happen?
111
+ ` Baz: for<'a> Bar<&'a isize>` , but how does that happen?
102
112
103
113
After the matching, we are in a position where we have a skolemized
104
114
substitution like ` X => &'0 isize ` . If we apply this substitution to the
@@ -112,5 +122,4 @@ from. (This is done in `higher_ranked::plug_leaks`). We know that the
112
122
leak check passed, so this taint set consists solely of the skolemized
113
123
region itself plus various intermediate region variables. We then walk
114
124
the trait-reference and convert every region in that taint set back to
115
- a late-bound region, so in this case we'd wind up with `for<'a> F :
116
- Bar<&'a isize>`.
125
+ a late-bound region, so in this case we'd wind up with ` Baz: for<'a> Bar<&'a isize> ` .
0 commit comments