1
1
# Subtyping and Variance
2
2
3
+ r[ subtype]
4
+
5
+ r[ subtype.intro]
3
6
Subtyping is implicit and can occur at any stage in type checking or
4
- inference. Subtyping is restricted to two cases:
7
+ inference.
8
+
9
+ r[ subtype.kinds]
10
+ Subtyping is restricted to two cases:
5
11
variance with respect to lifetimes and between types with higher ranked
6
12
lifetimes. If we were to erase lifetimes from types, then the only subtyping
7
13
would be due to type equality.
@@ -19,6 +25,7 @@ fn bar<'a>() {
19
25
Since ` 'static ` outlives the lifetime parameter ` 'a ` , ` &'static str ` is a
20
26
subtype of ` &'a str ` .
21
27
28
+ r[ subtype.higher-ranked]
22
29
[ Higher-ranked]   ; [ function pointers] and [ trait objects] have another
23
30
subtype relation. They are subtypes of types that are given by substitutions of
24
31
the higher-ranked lifetimes. Some examples:
@@ -39,17 +46,26 @@ let supertype: &for<'c> fn(&'c i32, &'c i32) = subtype;
39
46
40
47
## Variance
41
48
49
+ r[ subtyping.variance]
50
+
51
+ r[ subtyping.variance.intro]
42
52
Variance is a property that generic types have with respect to their arguments.
43
53
A generic type's * variance* in a parameter is how the subtyping of the
44
54
parameter affects the subtyping of the type.
45
55
56
+ r[ subtyping.variance.covariant]
46
57
* ` F<T> ` is * covariant* over ` T ` if ` T ` being a subtype of ` U ` implies that
47
58
` F<T> ` is a subtype of ` F<U> ` (subtyping "passes through")
59
+
60
+ r[ subtyping.variance.contravariant]
48
61
* ` F<T> ` is * contravariant* over ` T ` if ` T ` being a subtype of ` U ` implies that
49
62
` F<U> ` is a subtype of ` F<T> `
63
+
64
+ r[ subtyping.variance.invariant]
50
65
* ` F<T> ` is * invariant* over ` T ` otherwise (no subtyping relation can be
51
66
derived)
52
67
68
+ r[ subtyping.variance.builtin-types]
53
69
Variance of types is automatically determined as follows
54
70
55
71
| Type | Variance in ` 'a ` | Variance in ` T ` |
@@ -65,6 +81,7 @@ Variance of types is automatically determined as follows
65
81
| ` std::marker::PhantomData<T> ` | | covariant |
66
82
| ` dyn Trait<T> + 'a ` | covariant | invariant |
67
83
84
+ r[ subtyping.variance.user-composite-types]
68
85
The variance of other ` struct ` , ` enum ` , and ` union ` types is decided by
69
86
looking at the variance of the types of their fields. If the parameter is used
70
87
in positions with different variances then the parameter is invariant. For
@@ -85,6 +102,7 @@ struct Variance<'a, 'b, 'c, T, U: 'a> {
85
102
}
86
103
```
87
104
105
+ r[ subtyping.variance.builtin-composite-types]
88
106
When used outside of an ` struct ` , ` enum ` , or ` union ` , the variance for parameters is checked at each location separately.
89
107
90
108
``` rust
0 commit comments