Files
kotlin-fork/compiler/testData/writeSignature/declarationSiteVariance/wildcardOptimization/argumentOverridability.kt
T
Denis Zharkov 406e31f54a Change default rules for declaration-site wildcards
Mostly this commit is about skipping wildcards that are redundant in some sense.
The motivation is that they looks `long` in Java code.

There are basically two important parts: return types and value parameters.

1. For return types default behaviour is skipping all declaration-site wildcards.
The intuition behind this rule is simple: return types are basically used in subtype position
(as an argument for another call), and here everything works well in case of 'out'-variance.
For example we have 'Out<Out<T>>>' as subtype both for 'Out<Out<T>>>' and 'Out<? extends Out<? extends T>>>',
so values of such type is more flexible in contrast to `Out<? extends Out<? extends T>>>` that could be used only
for the second case.

But we have choosen to treat `in`-variance in a different way: argument itself
should be rendered without wildcard while nested arguments are rendered by the rules
described further (see second part).

For example: 'In<Out<OpenClass>>' will have generic signature 'In<Out<? extends OpenClass>>'.
If we omit all wildcards here, then value of type 'In<Out<OpenClass>>'
will be impossible to use as argument for function expecting 'In<? super Out<? extends Derived>>'
where Derived <: OpenClass (you can check it manually :]).

And this exception should not be very inconvinient because in-variance is rather rare.

2. For value parameters we decided to skip wildcards if it doesn't make obtained signature weaker
in a sense of set of acceptable arguments.

More precisely:
    a. We write wildcard for 'Out<T>' iff T ``can have subtypes ignoring nullability''
    b. We write wildcard for 'In<T>' iff T is not equal to it's class upper bound (ignoring nullability again)

Definition of ``can have subtypes ignoring nullability'' is straightforward and you can see it in commit.

 #KT-9801 Fixed
 #KT-9890 Fixed
2015-12-01 08:20:59 +03:00

26 lines
1.0 KiB
Kotlin
Vendored
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class Out<out T>
class OutPair<out X, out Y>
class In<in Z>
class Final
open class Open
// For value parameters we decided to skip wildcards if it doesn't make obtained signature weaker
// in a sense of set of acceptable arguments.
// More precisely:
//    a. We write wildcard for 'Out<T>' iff T ``can have subtypes ignoring nullability''
//    b. We write wildcard for 'In<T>' iff T is not equal to it's class upper bound (ignoring nullability again)
// Definition of ``can have subtypes ignoring nullability'' is straightforward and you can see it in commit.
fun openClassArgument(x: Out<Open>, y: In<Open>) {}
// method: ArgumentOverridabilityKt::openClassArgument
// generic signature: (LOut<+LOpen;>;LIn<-LOpen;>;)V
fun finalClassArgument(x: Out<Final>, y: In<Final>) {}
// method: ArgumentOverridabilityKt::finalClassArgument
// generic signature: (LOut<LFinal;>;LIn<-LFinal;>;)V
fun oneArgumentFinal(x: OutPair<Final, Open>) {}
// method: ArgumentOverridabilityKt::oneArgumentFinal
// generic signature: (LOutPair<LFinal;+LOpen;>;)V