Approximate captured types only when necessary

This commit is contained in:
Svetlana Isakova
2015-01-19 16:52:21 +03:00
parent 6c814279fc
commit 9dbcd8b55f
10 changed files with 82 additions and 17 deletions
@@ -39,11 +39,6 @@ public class FunctionDescriptorUtil {
return null; return null;
} }
@Override
public boolean isEmpty() {
return false;
}
@Override @Override
public String toString() { public String toString() {
return "FunctionDescriptorUtil.MAKE_TYPE_PARAMETERS_FRESH"; return "FunctionDescriptorUtil.MAKE_TYPE_PARAMETERS_FRESH";
@@ -0,0 +1,7 @@
class Bar
fun Bar.foo() = 42
object MyObject {
fun foo(bar: Bar) = bar.foo()
}
@@ -0,0 +1,26 @@
package
internal fun Bar.foo(): kotlin.Int
internal final class Bar {
public constructor Bar()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal object MyObject {
private constructor MyObject()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final fun foo(/*0*/ bar: Bar): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
public class object <class-object-for-MyObject> : MyObject {
private constructor <class-object-for-MyObject>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final override /*1*/ /*fake_override*/ fun foo(/*0*/ bar: Bar): kotlin.Int
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
}
@@ -5208,6 +5208,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("notApproximateWhenCopyDescriptors.kt")
public void testNotApproximateWhenCopyDescriptors() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/notApproximateWhenCopyDescriptors.kt");
doTest(fileName);
}
@TestMetadata("overApproximationForInCaptured.kt") @TestMetadata("overApproximationForInCaptured.kt")
public void testOverApproximationForInCaptured() throws Exception { public void testOverApproximationForInCaptured() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/overApproximationForInCaptured.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/capturedTypes/overApproximationForInCaptured.kt");
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.CompoundC
import org.jetbrains.kotlin.types.getCustomTypeVariable import org.jetbrains.kotlin.types.getCustomTypeVariable
import org.jetbrains.kotlin.types.isFlexible import org.jetbrains.kotlin.types.isFlexible
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
import org.jetbrains.kotlin.types.TypeSubstitution
public class ConstraintSystemImpl : ConstraintSystem { public class ConstraintSystemImpl : ConstraintSystem {
@@ -437,9 +438,9 @@ public class ConstraintSystemImpl : ConstraintSystem {
return if (typeParameterDescriptor != null && isMyTypeVariable(typeParameterDescriptor)) typeParameterDescriptor else null return if (typeParameterDescriptor != null && isMyTypeVariable(typeParameterDescriptor)) typeParameterDescriptor else null
} }
override fun getResultingSubstitutor() = replaceUninferredBySpecialErrorType() override fun getResultingSubstitutor() = replaceUninferredBySpecialErrorType().setApproximateCapturedTypes()
override fun getCurrentSubstitutor() = replaceUninferredBy(TypeUtils.DONT_CARE) override fun getCurrentSubstitutor() = replaceUninferredBy(TypeUtils.DONT_CARE).setApproximateCapturedTypes()
private fun createCorrespondingExtensionFunctionType(functionType: JetType, receiverType: JetType): JetType { private fun createCorrespondingExtensionFunctionType(functionType: JetType, receiverType: JetType): JetType {
assert(KotlinBuiltIns.isFunctionType(functionType)) assert(KotlinBuiltIns.isFunctionType(functionType))
@@ -461,3 +462,13 @@ public class ConstraintSystemImpl : ConstraintSystem {
return KotlinBuiltIns.getInstance().getFunctionType(functionType.getAnnotations(), receiverType, arguments, returnType) return KotlinBuiltIns.getInstance().getFunctionType(functionType.getAnnotations(), receiverType, arguments, returnType)
} }
} }
private fun TypeSubstitutor.setApproximateCapturedTypes(): TypeSubstitutor {
return TypeSubstitutor.create(SubstitutionWithCapturedTypeApproximation(getSubstitution()))
}
private class SubstitutionWithCapturedTypeApproximation(val substitution: TypeSubstitution) : TypeSubstitution() {
override fun get(key: TypeConstructor?) = substitution[key]
override fun isEmpty() = substitution.isEmpty()
override fun approximateCapturedTypes() = true
}
@@ -74,8 +74,6 @@ public fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?):
if (typeProjection == null) return null if (typeProjection == null) return null
val type = typeProjection.getType() val type = typeProjection.getType()
//todo temporary hack to compile 'kotlin'
if (type is LazyType) return typeProjection
if (!TypeUtils.containsSpecialType(type, { it.isCaptured() })) { if (!TypeUtils.containsSpecialType(type, { it.isCaptured() })) {
return typeProjection return typeProjection
} }
@@ -89,11 +87,10 @@ public fun approximateCapturedTypesIfNecessary(typeProjection: TypeProjection?):
} }
private fun substituteCapturedTypes(typeProjection: TypeProjection): TypeProjection? { private fun substituteCapturedTypes(typeProjection: TypeProjection): TypeProjection? {
val typeSubstitutor = TypeSubstitutor.create(object : TypeSubstitution { val typeSubstitutor = TypeSubstitutor.create(object : TypeSubstitution() {
override fun get(typeConstructor: TypeConstructor?): TypeProjection? { override fun get(typeConstructor: TypeConstructor?): TypeProjection? {
return (typeConstructor as? CapturedTypeConstructor)?.typeProjection return (typeConstructor as? CapturedTypeConstructor)?.typeProjection
} }
override fun isEmpty() = false
}) })
return typeSubstitutor.substituteWithoutApproximation(typeProjection) return typeSubstitutor.substituteWithoutApproximation(typeProjection)
} }
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.types;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class CompositeTypeSubstitution implements TypeSubstitution { public class CompositeTypeSubstitution extends TypeSubstitution {
private final TypeSubstitution[] inner; private final TypeSubstitution[] inner;
public CompositeTypeSubstitution(@NotNull TypeSubstitution... inner) { public CompositeTypeSubstitution(@NotNull TypeSubstitution... inner) {
@@ -42,6 +42,14 @@ public class CompositeTypeSubstitution implements TypeSubstitution {
return true; return true;
} }
@Override
public boolean approximateCapturedTypes() {
for (TypeSubstitution substitution : inner) {
if (substitution.approximateCapturedTypes()) return true;
}
return false;
}
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
@@ -53,6 +53,11 @@ public class DescriptorSubstitutor {
return originalSubstitutor.isEmpty() && mutableSubstitution.isEmpty(); return originalSubstitutor.isEmpty() && mutableSubstitution.isEmpty();
} }
@Override
public boolean approximateCapturedTypes() {
return originalSubstitutor.getSubstitution().approximateCapturedTypes();
}
@Override @Override
public String toString() { public String toString() {
return "DescriptorSubstitutor.substituteTypeParameters(" + mutableSubstitution + " / " + originalSubstitutor.getSubstitution() + ")"; return "DescriptorSubstitutor.substituteTypeParameters(" + mutableSubstitution + " / " + originalSubstitutor.getSubstitution() + ")";
@@ -18,8 +18,8 @@ package org.jetbrains.kotlin.types;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public interface TypeSubstitution { public abstract class TypeSubstitution {
TypeSubstitution EMPTY = new TypeSubstitution() { public static final TypeSubstitution EMPTY = new TypeSubstitution() {
@Override @Override
public TypeProjection get(TypeConstructor key) { public TypeProjection get(TypeConstructor key) {
return null; return null;
@@ -37,6 +37,13 @@ public interface TypeSubstitution {
}; };
@Nullable @Nullable
TypeProjection get(TypeConstructor key); public abstract TypeProjection get(TypeConstructor key);
boolean isEmpty();
public boolean isEmpty() {
return false;
}
public boolean approximateCapturedTypes() {
return false;
}
} }
@@ -31,7 +31,7 @@ public class TypeSubstitutor {
private static final int MAX_RECURSION_DEPTH = 100; private static final int MAX_RECURSION_DEPTH = 100;
public static class MapToTypeSubstitutionAdapter implements TypeSubstitution { public static class MapToTypeSubstitutionAdapter extends TypeSubstitution {
private final @NotNull Map<TypeConstructor, TypeProjection> substitutionContext; private final @NotNull Map<TypeConstructor, TypeProjection> substitutionContext;
public MapToTypeSubstitutionAdapter(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) { public MapToTypeSubstitutionAdapter(@NotNull Map<TypeConstructor, TypeProjection> substitutionContext) {
@@ -142,6 +142,9 @@ public class TypeSubstitutor {
@Nullable @Nullable
public TypeProjection substitute(@NotNull TypeProjection typeProjection) { public TypeProjection substitute(@NotNull TypeProjection typeProjection) {
TypeProjection substitutedTypeProjection = substituteWithoutApproximation(typeProjection); TypeProjection substitutedTypeProjection = substituteWithoutApproximation(typeProjection);
if (!substitution.approximateCapturedTypes()) {
return substitutedTypeProjection;
}
return TypesApproximationPackage.approximateCapturedTypesIfNecessary(substitutedTypeProjection); return TypesApproximationPackage.approximateCapturedTypesIfNecessary(substitutedTypeProjection);
} }