@@ -12,10 +12,10 @@ reference to a trait. So, for example, if there is a generic function like:
12
12
13
13
and then a call to that function:
14
14
15
- let v: Vec<int > = clone_slice([1, 2, 3])
15
+ let v: Vec<isize > = clone_slice([1, 2, 3])
16
16
17
17
it is the job of trait resolution to figure out (in which case)
18
- whether there exists an impl of ` int : Clone`
18
+ whether there exists an impl of ` isize : Clone`
19
19
20
20
Note that in some cases, like generic functions, we may not be able to
21
21
find a specific impl, but we can figure out that the caller must
@@ -115,27 +115,27 @@ trait Convert<Target> {
115
115
116
116
This trait just has one method. It's about as simple as it gets. It
117
117
converts from the (implicit) ` Self ` type to the ` Target ` type. If we
118
- wanted to permit conversion between ` int ` and ` uint ` , we might
118
+ wanted to permit conversion between ` isize ` and ` usize ` , we might
119
119
implement ` Convert ` like so:
120
120
121
121
``` rust
122
- impl Convert <uint > for int { ... } // int -> uint
123
- impl Convert <int > for uint { ... } // uint -> int
122
+ impl Convert <usize > for isize { ... } // isize -> usize
123
+ impl Convert <isize > for usize { ... } // usize -> isize
124
124
```
125
125
126
126
Now imagine there is some code like the following:
127
127
128
128
``` rust
129
- let x : int = ... ;
129
+ let x : isize = ... ;
130
130
let y = x . convert ();
131
131
```
132
132
133
133
The call to convert will generate a trait reference `Convert<$Y> for
134
- int ` , where ` $Y` is the type variable representing the type of
134
+ isize ` , where ` $Y` is the type variable representing the type of
135
135
` y ` . When we match this against the two impls we can see, we will find
136
- that only one remains: ` Convert<uint > for int ` . Therefore, we can
136
+ that only one remains: ` Convert<usize > for isize ` . Therefore, we can
137
137
select this impl, which will cause the type of ` $Y ` to be unified to
138
- ` uint ` . (Note that while assembling candidates, we do the initial
138
+ ` usize ` . (Note that while assembling candidates, we do the initial
139
139
unifications in a transaction, so that they don't affect one another.)
140
140
141
141
There are tests to this effect in src/test/run-pass:
@@ -225,7 +225,7 @@ Confirmation unifies the output type parameters of the trait with the
225
225
values found in the obligation, possibly yielding a type error. If we
226
226
return to our example of the ` Convert ` trait from the previous
227
227
section, confirmation is where an error would be reported, because the
228
- impl specified that ` T ` would be ` uint ` , but the obligation reported
228
+ impl specified that ` T ` would be ` usize ` , but the obligation reported
229
229
` char ` . Hence the result of selection would be an error.
230
230
231
231
### Selection during translation
@@ -250,20 +250,20 @@ Here is an example:
250
250
trait Foo { ... }
251
251
impl<U,T:Bar<U>> Foo for Vec<T> { ... }
252
252
253
- impl Bar<uint > for int { ... }
253
+ impl Bar<usize > for isize { ... }
254
254
255
- After one shallow round of selection for an obligation like `Vec<int >
255
+ After one shallow round of selection for an obligation like `Vec<isize >
256
256
: Foo`, we would know which impl we want, and we would know that
257
- ` T=int ` , but we do not know the type of ` U ` . We must select the
258
- nested obligation ` int : Bar<U>` to find out that ` U=uint ` .
257
+ ` T=isize ` , but we do not know the type of ` U ` . We must select the
258
+ nested obligation ` isize : Bar<U>` to find out that ` U=usize ` .
259
259
260
260
It would be good to only do * just as much* nested resolution as
261
261
necessary. Currently, though, we just do a full resolution.
262
262
263
263
# Higher-ranked trait bounds
264
264
265
265
One of the more subtle concepts at work are * higher-ranked trait
266
- bounds* . An example of such a bound is ` for<'a> MyTrait<&'a int > ` .
266
+ bounds* . An example of such a bound is ` for<'a> MyTrait<&'a isize > ` .
267
267
Let's walk through how selection on higher-ranked trait references
268
268
works.
269
269
@@ -279,21 +279,21 @@ trait Foo<X> {
279
279
```
280
280
281
281
Let's say we have a function ` want_hrtb ` that wants a type which
282
- implements ` Foo<&'a int > ` for any ` 'a ` :
282
+ implements ` Foo<&'a isize > ` for any ` 'a ` :
283
283
284
284
``` rust
285
- fn want_hrtb <T >() where T : for <'a > Foo <& 'a int > { ... }
285
+ fn want_hrtb <T >() where T : for <'a > Foo <& 'a isize > { ... }
286
286
```
287
287
288
- Now we have a struct ` AnyInt ` that implements ` Foo<&'a int > ` for any
288
+ Now we have a struct ` AnyInt ` that implements ` Foo<&'a isize > ` for any
289
289
` 'a ` :
290
290
291
291
``` rust
292
292
struct AnyInt ;
293
- impl <'a > Foo <& 'a int > for AnyInt { }
293
+ impl <'a > Foo <& 'a isize > for AnyInt { }
294
294
```
295
295
296
- And the question is, does ` AnyInt : for<'a> Foo<&'a int > ` ? We want the
296
+ And the question is, does ` AnyInt : for<'a> Foo<&'a isize > ` ? We want the
297
297
answer to be yes. The algorithm for figuring it out is closely related
298
298
to the subtyping for higher-ranked types (which is described in
299
299
` middle::infer::higher_ranked::doc ` , but also in a [ paper by SPJ] that
@@ -306,12 +306,12 @@ I recommend you read).
306
306
[ paper by SPJ ] : http://research.microsoft.com/en-us/um/people/simonpj/papers/higher-rank/
307
307
308
308
So let's work through our example. The first thing we would do is to
309
- skolemize the obligation, yielding ` AnyInt : Foo<&'0 int > ` (here ` '0 `
309
+ skolemize the obligation, yielding ` AnyInt : Foo<&'0 isize > ` (here ` '0 `
310
310
represents skolemized region #0 ). Note that now have no quantifiers;
311
311
in terms of the compiler type, this changes from a ` ty::PolyTraitRef `
312
312
to a ` TraitRef ` . We would then create the ` TraitRef ` from the impl,
313
313
using fresh variables for it's bound regions (and thus getting
314
- ` Foo<&'$a int > ` , where ` '$a ` is the inference variable for ` 'a ` ). Next
314
+ ` Foo<&'$a isize > ` , where ` '$a ` is the inference variable for ` 'a ` ). Next
315
315
we relate the two trait refs, yielding a graph with the constraint
316
316
that ` '0 == '$a ` . Finally, we check for skolemization "leaks" -- a
317
317
leak is basically any attempt to relate a skolemized region to another
@@ -327,13 +327,13 @@ Let's consider a failure case. Imagine we also have a struct
327
327
328
328
``` rust
329
329
struct StaticInt ;
330
- impl Foo <& 'static int > for StaticInt ;
330
+ impl Foo <& 'static isize > for StaticInt ;
331
331
```
332
332
333
- We want the obligation ` StaticInt : for<'a> Foo<&'a int > ` to be
333
+ We want the obligation ` StaticInt : for<'a> Foo<&'a isize > ` to be
334
334
considered unsatisfied. The check begins just as before. ` 'a ` is
335
335
skolemized to ` '0 ` and the impl trait reference is instantiated to
336
- ` Foo<&'static int > ` . When we relate those two, we get a constraint
336
+ ` Foo<&'static isize > ` . When we relate those two, we get a constraint
337
337
like ` 'static == '0 ` . This means that the taint set for ` '0 ` is `{'0,
338
338
'static}`, which fails the leak check.
339
339
@@ -358,13 +358,13 @@ impl<X,F> Foo<X> for F
358
358
}
359
359
```
360
360
361
- Now let's say we have a obligation ` for<'a> Foo<&'a int > ` and we match
361
+ Now let's say we have a obligation ` for<'a> Foo<&'a isize > ` and we match
362
362
this impl. What obligation is generated as a result? We want to get
363
- ` for<'a> Bar<&'a int > ` , but how does that happen?
363
+ ` for<'a> Bar<&'a isize > ` , but how does that happen?
364
364
365
365
After the matching, we are in a position where we have a skolemized
366
- substitution like ` X => &'0 int ` . If we apply this substitution to the
367
- impl obligations, we get ` F : Bar<&'0 int > ` . Obviously this is not
366
+ substitution like ` X => &'0 isize ` . If we apply this substitution to the
367
+ impl obligations, we get ` F : Bar<&'0 isize > ` . Obviously this is not
368
368
directly usable because the skolemized region ` '0 ` cannot leak out of
369
369
our computation.
370
370
@@ -375,7 +375,7 @@ leak check passed, so this taint set consists solely of the skolemized
375
375
region itself plus various intermediate region variables. We then walk
376
376
the trait-reference and convert every region in that taint set back to
377
377
a late-bound region, so in this case we'd wind up with `for<'a> F :
378
- Bar<&'a int >`.
378
+ Bar<&'a isize >`.
379
379
380
380
# Caching and subtle considerations therewith
381
381
@@ -391,8 +391,8 @@ but *replay* its effects on the type variables.
391
391
392
392
The high-level idea of how the cache works is that we first replace
393
393
all unbound inference variables with skolemized versions. Therefore,
394
- if we had a trait reference ` uint : Foo<$1>` , where ` $n ` is an unbound
395
- inference variable, we might replace it with ` uint : Foo<%0>` , where
394
+ if we had a trait reference ` usize : Foo<$1>` , where ` $n ` is an unbound
395
+ inference variable, we might replace it with ` usize : Foo<%0>` , where
396
396
` %n ` is a skolemized type. We would then look this up in the cache.
397
397
If we found a hit, the hit would tell us the immediate next step to
398
398
take in the selection process: i.e., apply impl #22 , or apply where
@@ -401,17 +401,17 @@ Therefore, we search through impls and where clauses and so forth, and
401
401
we come to the conclusion that the only possible impl is this one,
402
402
with def-id 22:
403
403
404
- impl Foo<int > for uint { ... } // Impl #22
404
+ impl Foo<isize > for usize { ... } // Impl #22
405
405
406
- We would then record in the cache `uint : Foo<%0> ==>
406
+ We would then record in the cache `usize : Foo<%0> ==>
407
407
ImplCandidate(22)` . Next we would confirm ` ImplCandidate(22)`, which
408
- would (as a side-effect) unify ` $1 ` with ` int ` .
408
+ would (as a side-effect) unify ` $1 ` with ` isize ` .
409
409
410
- Now, at some later time, we might come along and see a `uint :
411
- Foo<$3>` . When skolemized, this would yield ` uint : Foo<%0>`, just as
410
+ Now, at some later time, we might come along and see a `usize :
411
+ Foo<$3>` . When skolemized, this would yield ` usize : Foo<%0>`, just as
412
412
before, and hence the cache lookup would succeed, yielding
413
413
` ImplCandidate(22) ` . We would confirm ` ImplCandidate(22) ` which would
414
- (as a side-effect) unify ` $3 ` with ` int ` .
414
+ (as a side-effect) unify ` $3 ` with ` isize ` .
415
415
416
416
## Where clauses and the local vs global cache
417
417
0 commit comments