From 13a1777d39020aa9a4db63c08385be84aa7d7cfb Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 1 Dec 2011 22:33:43 +0300 Subject: [PATCH] KT-702 Type inference failed --- .../resolve/scopes/SubstitutingScope.java | 6 +- .../jet/lang/types/TypeSubstitutor.java | 27 ++- .../lang/types/checker/JetTypeChecker.java | 170 +++--------------- .../types/checker/TypeCheckingProcedure.java | 136 ++++++++++++++ .../lang/types/checker/TypingConstraints.java | 18 ++ .../types/inference/ConstraintSystemImpl.java | 49 +++-- .../diagnostics/tests/regressions/kt312.jet | 2 +- .../diagnostics/tests/regressions/kt701.jet | 18 ++ 8 files changed, 259 insertions(+), 167 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/checker/TypingConstraints.java create mode 100644 compiler/testData/diagnostics/tests/regressions/kt701.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java index a45bab80eda..c2e0ffbc177 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/SubstitutingScope.java @@ -116,8 +116,10 @@ public class SubstitutingScope implements JetScope { allDescriptors = Sets.newHashSet(); for (DeclarationDescriptor descriptor : workerScope.getAllDescriptors()) { DeclarationDescriptor substitute = substitute(descriptor); - assert substitute != null; - allDescriptors.add(substitute); +// assert substitute != null : descriptor; + if (substitute != null) { + allDescriptors.add(substitute); + } } } return allDescriptors; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java index dac071017cd..e0e2a35b24d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeSubstitutor.java @@ -125,22 +125,33 @@ public class TypeSubstitutor { private JetType unsafeSubstitute(@NotNull JetType type, @NotNull Variance howThisTypeIsUsed) throws SubstitutionException { if (ErrorUtils.isErrorType(type)) return type; - TypeConstructor constructor = type.getConstructor(); - TypeProjection value = substitution.get(constructor); + TypeProjection value = getValueWithCorrectNullability(substitution, type); if (value != null) { + TypeConstructor constructor = type.getConstructor(); assert constructor.getDeclarationDescriptor() instanceof TypeParameterDescriptor; - return TypeUtils.makeNullableIfNeeded(substitutionResult((TypeParameterDescriptor) constructor.getDeclarationDescriptor(), howThisTypeIsUsed, Variance.INVARIANT, value).getType(), type.isNullable()); + TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) constructor.getDeclarationDescriptor(); -// if (!allows(howThisTypeIsUsed, value.getProjectionKind())) { -// throw new SubstitutionException("!!" + value.toString()); -// } -// return value.getType(); + TypeProjection result = substitutionResult(typeParameterDescriptor, howThisTypeIsUsed, Variance.INVARIANT, value); + + return TypeUtils.makeNullableIfNeeded(result.getType(), type.isNullable()); } return specializeType(type, howThisTypeIsUsed); } + private TypeProjection getValueWithCorrectNullability(TypeSubstitution substitution, JetType type) { + TypeProjection typeProjection = substitution.get(type.getConstructor()); + if (typeProjection == null) return null; + + return type.isNullable() ? makeNullableProjection(typeProjection) : typeProjection; + } + + @NotNull + private static TypeProjection makeNullableProjection(@NotNull TypeProjection value) { + return new TypeProjection(value.getProjectionKind(), TypeUtils.makeNullable(value.getType())); + } + private JetType specializeType(JetType subjectType, Variance callSiteVariance) throws SubstitutionException { if (ErrorUtils.isErrorType(subjectType)) return subjectType; @@ -178,7 +189,7 @@ public class TypeSubstitutor { Variance effectiveProjectionKind = asymmetricOr(passedProjectionKind, parameterVariance); Variance effectiveContextVariance = contextCallSiteVariance.superpose(effectiveProjectionKind); - TypeProjection projectionValue = substitutionContext.get(typeToSubstituteIn.getConstructor()); + TypeProjection projectionValue = getValueWithCorrectNullability(substitutionContext, typeToSubstituteIn); if (projectionValue != null) { assert typeToSubstituteIn.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/JetTypeChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/JetTypeChecker.java index 378a7d2171f..7147158c66c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/JetTypeChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/JetTypeChecker.java @@ -3,16 +3,8 @@ package org.jetbrains.jet.lang.types.checker; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.types.*; -import java.util.List; - -import static org.jetbrains.jet.lang.types.Variance.INVARIANT; -import static org.jetbrains.jet.lang.types.Variance.IN_VARIANCE; -import static org.jetbrains.jet.lang.types.Variance.OUT_VARIANCE; - /** * @author abreslav */ @@ -30,156 +22,48 @@ public class JetTypeChecker { } public boolean equalTypes(@NotNull JetType a, @NotNull JetType b) { - return equalTypes(a, b, EMPTY_AXIOMS); + return TYPE_CHECKER.equalTypes(a, b); } - public boolean equalTypes(@NotNull JetType a, @NotNull JetType b, @NotNull BiMap equalityAxioms) { - return TYPE_CHECKER.equalTypes(a, b, equalityAxioms); - } - - // This method returns the supertype of the first parameter that has the same constructor - // as the second parameter, applying the substitution of type arguments to it - @Nullable - private static JetType findCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) { - TypeConstructor constructor = subtype.getConstructor(); - if (constructor.equals(supertype.getConstructor())) { - return subtype; - } - for (JetType immediateSupertype : constructor.getSupertypes()) { - JetType correspondingSupertype = findCorrespondingSupertype(immediateSupertype, supertype); - if (correspondingSupertype != null) { - return TypeSubstitutor.create(subtype).safeSubstitute(correspondingSupertype, Variance.INVARIANT); + public boolean equalTypes(@NotNull JetType a, @NotNull JetType b, @NotNull final BiMap equalityAxioms) { + return new TypeCheckingProcedure(new TypeCheckerTypingConstraints() { + @Override + public boolean assertEqualTypeConstructors(@NotNull TypeConstructor constructor1, @NotNull TypeConstructor constructor2) { + if (!constructor1.equals(constructor2)) { + TypeConstructor img1 = equalityAxioms.get(constructor1); + TypeConstructor img2 = equalityAxioms.get(constructor2); + if (!(img1 != null && img1.equals(constructor2)) && + !(img2 != null && img2.equals(constructor1))) { + return false; + } + } + return true; } - } - return null; + }).equalTypes(a, b); } - private static JetType getOutType(TypeParameterDescriptor parameter, TypeProjection argument) { - boolean isOutProjected = argument.getProjectionKind() == IN_VARIANCE || parameter.getVariance() == IN_VARIANCE; - return isOutProjected ? parameter.getUpperBoundsAsType() : argument.getType(); - } + private static final TypeCheckingProcedure TYPE_CHECKER = new TypeCheckingProcedure(new TypeCheckerTypingConstraints()); - private static JetType getInType(TypeParameterDescriptor parameter, TypeProjection argument) { - boolean isOutProjected = argument.getProjectionKind() == OUT_VARIANCE || parameter.getVariance() == OUT_VARIANCE; - return isOutProjected ? JetStandardClasses.getNothingType() : argument.getType(); - } - - /** - * Methods of this class return true to continue type checking and false to fail - */ - public interface TypingConstraintBuilder { - boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b); - boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype); - boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype); - } - - private static final TypeCheckingProcedure TYPE_CHECKER = new TypeCheckingProcedure(new TypingConstraintBuilder() { + private static class TypeCheckerTypingConstraints implements TypingConstraints { @Override - public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b) { - return TypeUtils.equalTypes(a, b); + public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b, TypeCheckingProcedure typeCheckingProcedure) { + return typeCheckingProcedure.equalTypes(a, b); +// return TypeUtils.equalTypes(a, b); } @Override - public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype) { - return INSTANCE.isSubtypeOf(subtype, supertype); + public boolean assertEqualTypeConstructors(@NotNull TypeConstructor a, @NotNull TypeConstructor b) { + return a.equals(b); + } + + @Override + public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype, TypeCheckingProcedure typeCheckingProcedure) { + return typeCheckingProcedure.isSubtypeOf(subtype, supertype); } @Override public boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) { return false; // type checking fails } - }); - - public static class TypeCheckingProcedure { - - private final TypingConstraintBuilder constraintBuilder; - - public TypeCheckingProcedure(TypingConstraintBuilder constraintBuilder) { - this.constraintBuilder = constraintBuilder; - } - - public boolean equalTypes(@NotNull JetType type1, @NotNull JetType type2, @NotNull BiMap equalityAxioms) { - if (type1.isNullable() != type2.isNullable()) { - return false; - } - TypeConstructor constructor1 = type1.getConstructor(); - TypeConstructor constructor2 = type2.getConstructor(); - if (!constructor1.equals(constructor2)) { - TypeConstructor img1 = equalityAxioms.get(constructor1); - TypeConstructor img2 = equalityAxioms.get(constructor2); - if (!(img1 != null && img1.equals(constructor2)) && - !(img2 != null && img2.equals(constructor1))) { - return false; - } - } - List type1Arguments = type1.getArguments(); - List type2Arguments = type2.getArguments(); - if (type1Arguments.size() != type2Arguments.size()) { - return false; - } - - for (int i = 0; i < type1Arguments.size(); i++) { - TypeProjection typeProjection1 = type1Arguments.get(i); - TypeProjection typeProjection2 = type2Arguments.get(i); - if (typeProjection1.getProjectionKind() != typeProjection2.getProjectionKind()) { - return false; - } - if (!equalTypes(typeProjection1.getType(), typeProjection2.getType(), equalityAxioms)) { - return false; - } - } - return true; - } - - public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) { - if (ErrorUtils.isErrorType(subtype) || ErrorUtils.isErrorType(supertype)) { - return true; - } - if (!supertype.isNullable() && subtype.isNullable()) { - return false; - } - subtype = TypeUtils.makeNotNullable(subtype); - supertype = TypeUtils.makeNotNullable(supertype); - if (JetStandardClasses.isNothingOrNullableNothing(subtype)) { - return true; - } - @Nullable JetType closestSupertype = findCorrespondingSupertype(subtype, supertype); - if (closestSupertype == null) { - return constraintBuilder.noCorrespondingSupertype(subtype, supertype); // if this returns true, there still isn't any supertype to continue with - } - - return checkSubtypeForTheSameConstructor(closestSupertype, supertype); - } - - private boolean checkSubtypeForTheSameConstructor(@NotNull JetType subtype, @NotNull JetType supertype) { - TypeConstructor constructor = subtype.getConstructor(); - assert constructor.equals(supertype.getConstructor()) : constructor + " is not " + supertype.getConstructor(); - - List subArguments = subtype.getArguments(); - List superArguments = supertype.getArguments(); - List parameters = constructor.getParameters(); - for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) { - TypeParameterDescriptor parameter = parameters.get(i); - - - TypeProjection subArgument = subArguments.get(i); - JetType subIn = getInType(parameter, subArgument); - JetType subOut = getOutType(parameter, subArgument); - - TypeProjection superArgument = superArguments.get(i); - JetType superIn = getInType(parameter, superArgument); - JetType superOut = getOutType(parameter, superArgument); - - if (parameter.getVariance() == INVARIANT && subArgument.getProjectionKind() == INVARIANT && superArgument.getProjectionKind() == INVARIANT) { - if (!constraintBuilder.assertEqualTypes(subArgument.getType(), superArgument.getType())) return false; - } - else { - if (!constraintBuilder.assertSubtype(subOut, superOut)) return false; - if (!constraintBuilder.assertSubtype(superIn, subIn)) return false; - } - } - return true; - } } - } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java new file mode 100644 index 00000000000..4d3a96bb62c --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/TypeCheckingProcedure.java @@ -0,0 +1,136 @@ +package org.jetbrains.jet.lang.types.checker; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.types.*; + +import java.util.List; + +import static org.jetbrains.jet.lang.types.Variance.*; + +/** +* @author abreslav +*/ +public class TypeCheckingProcedure { + + // This method returns the supertype of the first parameter that has the same constructor + // as the second parameter, applying the substitution of type arguments to it + @Nullable + private static JetType findCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) { + TypeConstructor constructor = subtype.getConstructor(); + if (constructor.equals(supertype.getConstructor())) { + return subtype; + } + for (JetType immediateSupertype : constructor.getSupertypes()) { + JetType correspondingSupertype = findCorrespondingSupertype(immediateSupertype, supertype); + if (correspondingSupertype != null) { + return TypeSubstitutor.create(subtype).safeSubstitute(correspondingSupertype, Variance.INVARIANT); + } + } + return null; + } + + private static JetType getOutType(TypeParameterDescriptor parameter, TypeProjection argument) { + boolean isOutProjected = argument.getProjectionKind() == IN_VARIANCE || parameter.getVariance() == IN_VARIANCE; + return isOutProjected ? parameter.getUpperBoundsAsType() : argument.getType(); + } + + private static JetType getInType(TypeParameterDescriptor parameter, TypeProjection argument) { + boolean isOutProjected = argument.getProjectionKind() == OUT_VARIANCE || parameter.getVariance() == OUT_VARIANCE; + return isOutProjected ? JetStandardClasses.getNothingType() : argument.getType(); + } + + private final TypingConstraints constraints; + + public TypeCheckingProcedure(TypingConstraints constraints) { + this.constraints = constraints; + } + + public boolean equalTypes(@NotNull JetType type1, @NotNull JetType type2) { + if (type1.isNullable() != type2.isNullable()) { + return false; + } + + if (type1.isNullable()) { + // Then type2 is nullable, too (see the previous condition + return constraints.assertEqualTypes(TypeUtils.makeNotNullable(type1), TypeUtils.makeNotNullable(type2), this); + } + + TypeConstructor constructor1 = type1.getConstructor(); + TypeConstructor constructor2 = type2.getConstructor(); + + if (!constraints.assertEqualTypeConstructors(constructor1, constructor2)) { + return false; + } + + List type1Arguments = type1.getArguments(); + List type2Arguments = type2.getArguments(); + if (type1Arguments.size() != type2Arguments.size()) { + return false; + } + + for (int i = 0; i < type1Arguments.size(); i++) { + TypeProjection typeProjection1 = type1Arguments.get(i); + TypeProjection typeProjection2 = type2Arguments.get(i); + if (typeProjection1.getProjectionKind() != typeProjection2.getProjectionKind()) { + return false; + } + + if (!constraints.assertEqualTypes(typeProjection1.getType(), typeProjection2.getType(), this)) { + return false; + } + } + return true; + } + + public boolean isSubtypeOf(@NotNull JetType subtype, @NotNull JetType supertype) { + if (ErrorUtils.isErrorType(subtype) || ErrorUtils.isErrorType(supertype)) { + return true; + } + if (!supertype.isNullable() && subtype.isNullable()) { + return false; + } + subtype = TypeUtils.makeNotNullable(subtype); + supertype = TypeUtils.makeNotNullable(supertype); + if (JetStandardClasses.isNothingOrNullableNothing(subtype)) { + return true; + } + @Nullable JetType closestSupertype = findCorrespondingSupertype(subtype, supertype); + if (closestSupertype == null) { + return constraints.noCorrespondingSupertype(subtype, supertype); // if this returns true, there still isn't any supertype to continue with + } + + return checkSubtypeForTheSameConstructor(closestSupertype, supertype); + } + + private boolean checkSubtypeForTheSameConstructor(@NotNull JetType subtype, @NotNull JetType supertype) { + TypeConstructor constructor = subtype.getConstructor(); + assert constructor.equals(supertype.getConstructor()) : constructor + " is not " + supertype.getConstructor(); + + List subArguments = subtype.getArguments(); + List superArguments = supertype.getArguments(); + List parameters = constructor.getParameters(); + for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) { + TypeParameterDescriptor parameter = parameters.get(i); + + + TypeProjection subArgument = subArguments.get(i); + JetType subIn = getInType(parameter, subArgument); + JetType subOut = getOutType(parameter, subArgument); + + TypeProjection superArgument = superArguments.get(i); + JetType superIn = getInType(parameter, superArgument); + JetType superOut = getOutType(parameter, superArgument); + + if (parameter.getVariance() == INVARIANT && subArgument.getProjectionKind() == INVARIANT && superArgument.getProjectionKind() == INVARIANT) { + if (!constraints.assertEqualTypes(subArgument.getType(), superArgument.getType(), this)) return false; + } + else { + if (!constraints.assertSubtype(subOut, superOut, this)) return false; + if (!constraints.assertSubtype(superIn, subIn, this)) return false; + } + } + return true; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/TypingConstraints.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/TypingConstraints.java new file mode 100644 index 00000000000..0276f816184 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/checker/TypingConstraints.java @@ -0,0 +1,18 @@ +package org.jetbrains.jet.lang.types.checker; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeConstructor; + +/** + * Methods of this class return true to continue type checking and false to fail + */ +public interface TypingConstraints { + boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b, TypeCheckingProcedure typeCheckingProcedure); + + boolean assertEqualTypeConstructors(@NotNull TypeConstructor a, @NotNull TypeConstructor b); + + boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype, TypeCheckingProcedure typeCheckingProcedure); + + boolean noCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java index 0102d57fa37..f5baf6d6e77 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/inference/ConstraintSystemImpl.java @@ -8,6 +8,8 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; +import org.jetbrains.jet.lang.types.checker.TypeCheckingProcedure; +import org.jetbrains.jet.lang.types.checker.TypingConstraints; import java.util.Collection; import java.util.Collections; @@ -224,7 +226,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { public boolean equate(TypeValue other) { if (other instanceof KnownType) { KnownType knownType = (KnownType) other; - return TypeUtils.equalTypes(type, knownType.getType()); + return constraintExpander.equalTypes(type, knownType.getType()); } return other.equate(this); } @@ -234,16 +236,16 @@ public class ConstraintSystemImpl implements ConstraintSystem { private final Map unknownTypes = Maps.newHashMap(); private final JetTypeChecker typeChecker = JetTypeChecker.INSTANCE; - private static final class TypeConstraintBuilderAdapter implements JetTypeChecker.TypingConstraintBuilder { - private final JetTypeChecker.TypingConstraintBuilder delegate; + private static final class TypeConstraintBuilderAdapter implements TypingConstraints { + private final TypingConstraints delegate; - private TypeConstraintBuilderAdapter(JetTypeChecker.TypingConstraintBuilder delegate) { + private TypeConstraintBuilderAdapter(TypingConstraints delegate) { this.delegate = delegate; } @Override - public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b) { - boolean result = delegate.assertEqualTypes(a, b); + public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b, TypeCheckingProcedure typeCheckingProcedure) { + boolean result = delegate.assertEqualTypes(a, b, typeCheckingProcedure); if (!result) { println("-- Failed to equate " + a + " and " + b); } @@ -251,8 +253,17 @@ public class ConstraintSystemImpl implements ConstraintSystem { } @Override - public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype) { - boolean result = delegate.assertSubtype(subtype, supertype); + public boolean assertEqualTypeConstructors(@NotNull TypeConstructor a, @NotNull TypeConstructor b) { + boolean result = delegate.assertEqualTypeConstructors(a, b); + if (!result) { + println("-- Type constructors are not equal: " + a + " and " + b); + } + return result; + } + + @Override + public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype, TypeCheckingProcedure typeCheckingProcedure) { + boolean result = delegate.assertSubtype(subtype, supertype, typeCheckingProcedure); if (!result) { println("-- " + subtype + " can't be a subtype of " + supertype); } @@ -269,9 +280,9 @@ public class ConstraintSystemImpl implements ConstraintSystem { } } - private final JetTypeChecker.TypeCheckingProcedure constraintExpander = new JetTypeChecker.TypeCheckingProcedure(new TypeConstraintBuilderAdapter(new JetTypeChecker.TypingConstraintBuilder() { + private final TypeCheckingProcedure constraintExpander = new TypeCheckingProcedure(new TypeConstraintBuilderAdapter(new TypingConstraints() { @Override - public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b) { + public boolean assertEqualTypes(@NotNull JetType a, @NotNull JetType b, TypeCheckingProcedure typeCheckingProcedure) { TypeValue aValue = getTypeValueFor(a); TypeValue bValue = getTypeValueFor(b); @@ -279,7 +290,14 @@ public class ConstraintSystemImpl implements ConstraintSystem { } @Override - public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype) { + public boolean assertEqualTypeConstructors(@NotNull TypeConstructor a, @NotNull TypeConstructor b) { + return a.equals(b) + || unknownTypes.containsKey(a.getDeclarationDescriptor()) + || unknownTypes.containsKey(b.getDeclarationDescriptor()); + } + + @Override + public boolean assertSubtype(@NotNull JetType subtype, @NotNull JetType supertype, TypeCheckingProcedure typeCheckingProcedure) { TypeValue subtypeValue = getTypeValueFor(subtype); TypeValue supertypeValue = getTypeValueFor(supertype); @@ -306,7 +324,8 @@ public class ConstraintSystemImpl implements ConstraintSystem { return subtypeValue instanceof UnknownType || supertypeValue instanceof UnknownType; } - })); + })) + ; public ConstraintSystemImpl() {} @@ -427,6 +446,10 @@ public class ConstraintSystemImpl implements ConstraintSystem { // TODO : check that all bounds are respected by solutions: // we have set some of them from equality constraints with known types // and thus the bounds may be violated if some of the constraints conflict + + println("===================================="); + println(""); + println(""); return solution; } @@ -566,6 +589,6 @@ public class ConstraintSystemImpl implements ConstraintSystem { } private static void println(String message) { - System.out.println(message); +// System.out.println(message); } } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/kt312.jet b/compiler/testData/diagnostics/tests/regressions/kt312.jet index 6701b24dbef..89085fbc485 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt312.jet +++ b/compiler/testData/diagnostics/tests/regressions/kt312.jet @@ -4,7 +4,7 @@ fun Array.safeGet(index : Int) : T? { return if (index < size) this[index] else null } -val args : Array = Array(1) +val args : Array = Array(1, {""}) val name : String = args.safeGet(0) // No error, must be type mismatch val name1 : String? = args.safeGet(0) diff --git a/compiler/testData/diagnostics/tests/regressions/kt701.jet b/compiler/testData/diagnostics/tests/regressions/kt701.jet new file mode 100644 index 00000000000..cd536d66aa8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/regressions/kt701.jet @@ -0,0 +1,18 @@ +// KT-702 Type inference failed +// +JDK +fun getJavaClass() : java.lang.Class { return "" as Class } + +public class Throwables() { + class object { + public fun propagateIfInstanceOf(throwable : Throwable?, declaredType : Class?) { + if (((throwable != null) && declaredType?.isInstance(throwable).sure())) + { + throw declaredType?.cast(throwable) + } + } + public fun propagateIfPossible(throwable : Throwable?) { + propagateIfInstanceOf(throwable, getJavaClass) //; Type inference failed: Mismatch while expanding constraints + propagateIfInstanceOf(throwable, getJavaClass) // Type inference failed: Mismatch while expanding constraints + } + } +} \ No newline at end of file