Star projection information preserved in substitutions

#KT-6700 Fixed
This commit is contained in:
Andrey Breslav
2015-01-30 19:53:04 +03:00
parent da639039bd
commit fecf6f9fdf
38 changed files with 412 additions and 216 deletions
@@ -72,6 +72,7 @@ private fun TypeProjection.toTypeArgument(typeParameter: TypeParameterDescriptor
public fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?): TypeProjection? {
if (typeProjection == null) return null
if (typeProjection.isStarProjection()) return typeProjection
val type = typeProjection.getType()
if (!TypeUtils.containsSpecialType(type, { it.isCaptured() })) {
@@ -165,6 +165,8 @@ public class TypeSubstitutor {
private TypeProjection unsafeSubstitute(@NotNull TypeProjection originalProjection, int recursionDepth) throws SubstitutionException {
assertRecursionDepth(recursionDepth, originalProjection, substitution);
if (originalProjection.isStarProjection()) return originalProjection;
// The type is within the substitution range, i.e. T or T?
JetType type = originalProjection.getType();
Variance originalProjectionKind = originalProjection.getProjectionKind();
@@ -278,7 +280,7 @@ public class TypeSubstitutor {
switch (conflictType(typeParameter.getVariance(), substitutedTypeArgument.getProjectionKind())) {
case NO_CONFLICT:
// if the corresponding type parameter is already co/contra-variant, there's not need for an explicit projection
if (typeParameter.getVariance() != Variance.INVARIANT) {
if (typeParameter.getVariance() != Variance.INVARIANT && !substitutedTypeArgument.isStarProjection()) {
substitutedTypeArgument = new TypeProjectionImpl(Variance.INVARIANT, substitutedTypeArgument.getType());
}
break;
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.utils.toReadOnlyList
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.types.isDynamic
import org.jetbrains.kotlin.types.TypeProjection
import org.jetbrains.kotlin.types.TypeProjectionImpl
fun JetType.getContainedTypeParameters(): Collection<TypeParameterDescriptor> {
val declarationDescriptor = getConstructor().getDeclarationDescriptor()
@@ -66,4 +68,8 @@ public fun JetType.isSubtypeOf(superType: JetType): Boolean = JetTypeChecker.DEF
public fun JetType.cannotBeReified(): Boolean = KotlinBuiltIns.isNothingOrNullableNothing(this) || this.isDynamic()
fun TypeProjection.substitute(doSubstitute: (JetType) -> JetType): TypeProjection {
return if (isStarProjection())
this
else TypeProjectionImpl(getProjectionKind(), doSubstitute(getType()))
}