You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/md/kotlin.core/declarations.md
+121-31
Original file line number
Diff line number
Diff line change
@@ -1784,56 +1784,142 @@ Only type parameters of [inline functions][Inlining] can be declared `reified`.
1784
1784
1785
1785
#### Type parameter variance
1786
1786
1787
-
The [declaration-site variance][Mixed-site variance] of a particular type parameter for a classifier declaration is specified using special keywords `in` (forcovariant parameters) and `out` (forcontravariant parameters).
1787
+
The [declaration-site variance][Mixed-site variance] of a particular type parameter for a classifier declaration is specified using special keywords `in` (forcontravariant parameters) and `out` (forcovariant parameters).
1788
1788
If the variance isnot specified, the parameter is implicitly declared invariant.
1789
1789
See [the type system section][Mixed-site variance] for details.
1790
1790
1791
-
Atype parameter is**usedincovariant position**inthe following cases:
1791
+
We would consider a type expression `E` to be **covariant**intype parameter `X` iffor every concrete type expressions `T1` and `T2` such that `T1<:T2` it holds that `E[T1/X] <:E[T2/X]`. One could also say, that the *position* `X` takes in`E` is**covariant**.
1792
1792
1793
-
-Itis used as an argument in another generic type and the corresponding parameter in that type is covariant;
1794
-
-Itis the return type of a function;
1795
-
-Itis a type of a property.
1793
+
Base covariant cases are the following:
1796
1794
1797
-
A type parameter is**used in contravariant position**in the following cases:
1795
+
-A type expression is covariant in type parameter `X`, ifthis parameter is explicitly declared as `out` either [in the expression itself][Use-site variance] or [in the type declaration][Declaration-site variance];
1796
+
-Types of functions are covariant in their return type parameter, since functions have [types of kind][Function types] `FN<inA1, ..., inAN, outR>`);
1797
+
-Types of read-only properties are effectively in covariant position;
1798
1798
1799
-
-Itis used as an argument in another generic type and the corresponding parameter in that type is contravariant;
1800
-
-Itis a type of an parameter of a function;
1801
-
-Itis a type of a mutable property.
1799
+
In the same way, we would consider a type expression `E` to be **contravariant**in type parameter `X` iffor every concrete type expressions `T1` and `T2` such that `T1<:T2` it holds that `E[T2/X] <:E[T1/X]`.
1802
1800
1803
-
A type parameter is used in an invariant position if it is used as an argument in another generic type and the corresponding parameter in that type is invariant.
1801
+
Base contravariant cases are the following:
1802
+
1803
+
-A type expression is contravariant in type parameter `X`, ifthis parameter is explicitly declared as `in` either [in the expression itself][Use-site variance] or [in the type declaration][Declaration-site variance];
1804
+
-Types of functions are contravariant in their argument types, since functions have [types of kind][Function types] `FN<inA1, ..., inAN, outR>`;
1805
+
1806
+
Lastly, we would consider a type expression `E` to be **invariant**in type parameter `X` iffor every concrete type expressions `T1` and `T2`, `E[T1/X] <:E[T2/X]` holds ifand only if `T1=T2` (`T1<:T2` and `T2<:T1`).
1807
+
1808
+
Base invariant cases are the following:
1809
+
1810
+
-A type expression is invariant in type parameter `X`, ifthis parameter isnot declared as either `in` or `out` [in the expression itself][Use-site variance] or [in the type declaration][Declaration-site variance];
1811
+
-Types of mutable properties are effectively in invariant position;
1812
+
1813
+
We will use `+` as a symbol denoting covariance, `-` as a symbol denoting contravariance and `o` as a symbol denoting invariance.
1814
+
1815
+
To infer variance of a complex type expression in a type parameter, variance composition is used, which is defined as follows:
1816
+
1817
+
-Given two type expressions, `A<X>` and `B<Y>`, if variance of `A<X>` in `X` is `v1`, and variance of `B<Y>` in `Y` is `v2`, then the variance of `A<B<Y>>` in `Y` is $\texttt{v1} \otimes \texttt{v2} = \texttt{v3}$, which is defined in the following table:
1818
+
1819
+
\begin{align*}
1820
+
\texttt{+} \otimes x &= x \text{, where $x$ is any variance} \\
1821
+
\texttt{-} \otimes \texttt{+} &= \texttt{-} \\
1822
+
\texttt{-} \otimes \texttt{-} &= \texttt{+} \\
1823
+
\texttt{o} \otimes x &= \texttt{o} \text{, where $x$ is any variance} \\
1824
+
x \otimes \texttt{o} &= \texttt{o} \text{, where $x$ is any variance}
1825
+
\end{align*}
1826
+
1827
+
This can be interpreted in the following way:
1828
+
1829
+
-Covariance*preserves* the given variance
1830
+
-Contravariance*inverses* the given variance
1831
+
-Invariance*absorbs* the given variance
1832
+
1833
+
Further reasoning and formalization behind this system is available in the ["Taming the Wildcards" paper][declarations.references].
Using the base not-nested cases and the rules for combining variance, we can iteratively define for every type expression its variance in a given type parameter.
1838
+
1839
+
When a type parameter has declared variance, andis used in a position of a different variance, a **variance conflict** may occure. The specific cases are:
1840
+
1841
+
-A non-invariant type parameter is used as an argument to an invariant position;
1842
+
-A covariant type parameter is used as an argument to a contravariant position;
1843
+
-A contravariant type parameter is used as an argument to a covariant position;
1844
+
1845
+
>Important remark: variance conflict does not occur if the containing declaration isprivate to the type parameter owner (in which case its visibility is restricted, see the [visibility][Declaration visibility] section for details).
1804
1846
1805
-
A usage of a contravariant type parameter in a covariant or invariant position, as well as usage of a covariant type parameter in a contravariant or invariant position, results in**variance conflict**and a compiler error, unless the containing declaration isprivate to the type parameter owner (in which case its visibility is restricted, see the [visibility][Declaration visibility] section for details).
1806
1847
This applies only to member declarations of the corresponding class, extensions are not subject to this limitation.
1807
1848
1808
-
This restrictions may be lifted in particular cases by [annotating][Annotations] the corresponding type parameter usage with a special built-inannotation `kotlin.UnsafeVariance`.
1849
+
These restrictions may be lifted in particular cases by [annotating][Annotations] the corresponding type parameter usage with a special built-inannotation `kotlin.UnsafeVariance`.
1809
1850
By supplying thisannotation the author of the code explicitly declares that safety features that variance checks provide are not needed inthis particular declarations.
>// Variance of F1<in Foo<S>, out Unit> in S -- covariance
1907
+
> }
1908
+
>
1909
+
>classIn<inT>() // T is contravariant
1910
+
>classOut<outT>() // T is covariant
1911
+
>
1912
+
>classTest<inI, outO> {
1913
+
>funtest(a:In<In<I>>) {} // Ok, contravariant parameter in contravariant usage
1914
+
>// test has type F1<in In<In<I>>, out Unit>
1915
+
>// Need to find variance of F1<in In<In<I>>, out Unit> in I
1916
+
>// In<I> is contravariant (-) in I
1917
+
>// In<In<I>> is covariant in I, since - ⊗ - = + (covariance)
1918
+
>// F1<in In<In<I>>> is contravariant in I, since - ⊗ + = - (contravariance)
1919
+
> }
1920
+
> ```
1921
+
>
1922
+
>Remark: cases `e`, `f`, `f2`, `g`, `g2` in"Basic examples" are also examples of variance composition, since they are read-only fields. However, since read-only fields are of covariance (`+`) andfor any variance $x$, $\texttt{+} \otimes x = x$, it was omitted at that point.
1837
1923
>
1838
1924
>Any of these restrictions may be lifted using `@UnsafeVariance` annotation on the type argument:
1839
1925
>
@@ -1989,3 +2075,7 @@ There is a partial order of *weakness* between different visibility modifiers:
1989
2075
> ```
1990
2076
>
1991
2077
2078
+
### References {#declarations.references}
2079
+
2080
+
1. John Altidor, Shan Shan Huang, and Yannis Smaragdakis. "Taming the wildcards: combining definition- and use-site variance." 2011 (\url{https://yanniss.github.io/variance-pldi11.pdf})
0 commit comments