diff --git a/compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt b/compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt index 29ceac5cdec..9ce13d9435a 100644 --- a/compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt +++ b/compiler/testData/diagnostics/tests/inference/typeInferenceExpectedTypeMismatch.kt @@ -3,9 +3,39 @@ package typeInferenceExpectedTypeMismatch import java.util.* fun test() { - val s : Set = newList() + val s : Set = newList() + use(s) } fun newList() : ArrayList { return ArrayList() } + +trait Out +trait In + +trait Two + +trait A +trait B: A +trait C: A + +fun foo(o: Out, i: In): Two = throw Exception("$o $i") + +fun test1(outA: Out, inB: In) { + foo(outA, inB) + + val b: Two = foo(outA, inB) + use(b) +} + +fun bar(o: Out, i: In): Two = throw Exception("$o $i") + +fun test2(outA: Out, inC: In) { + bar(outA, inC) + + val b: Two = bar(outA, inC) + use(b) +} + +fun use(vararg a: Any?) = a \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java index 4f0a027201e..dad8cfbe66d 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java @@ -39,6 +39,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition.EXPECTED_TYPE_POSITION; import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.EQUAL; import static org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl.ConstraintKind.SUB_TYPE; import static org.jetbrains.jet.lang.resolve.calls.inference.TypeBoundsImpl.BoundKind.*; @@ -58,9 +59,6 @@ public class ConstraintSystemImpl implements ConstraintSystem { private final TypeSubstitutor currentSubstitutor; private boolean hasErrorInConstrainingTypes; - @Nullable - private ConstraintSystem systemWithoutExpectedTypeConstraint; - private final ConstraintSystemStatus constraintSystemStatus = new ConstraintSystemStatus() { @Override public boolean isSuccessful() { @@ -109,14 +107,12 @@ public class ConstraintSystemImpl implements ConstraintSystem { @Override public boolean hasOnlyExpectedTypeMismatch() { - if (systemWithoutExpectedTypeConstraint == null) { - // the expected type constraint isn't added, there can't be an error with it - return false; - } - if (!isSuccessful() && systemWithoutExpectedTypeConstraint.getStatus().isSuccessful()) { + if (isSuccessful()) return false; + ConstraintSystem systemWithoutExpectedTypeConstraint = filterConstraintsOut(EXPECTED_TYPE_POSITION); + if (systemWithoutExpectedTypeConstraint.getStatus().isSuccessful()) { return true; } - if (errorConstraintPositions.size() == 1 && errorConstraintPositions.contains(ConstraintPosition.EXPECTED_TYPE_POSITION)) { + if (errorConstraintPositions.size() == 1 && errorConstraintPositions.contains(EXPECTED_TYPE_POSITION)) { // if systemWithoutExpectedTypeConstraint has unknown type parameters, it's not successful, // but there can be expected type mismatch after expected type is added return true; @@ -215,6 +211,17 @@ public class ConstraintSystemImpl implements ConstraintSystem { Conditions.alwaysTrue()); } + @NotNull + public ConstraintSystem filterConstraintsOut(@NotNull ConstraintPosition... excludePositions) { + final Set positions = Sets.newHashSet(excludePositions); + return filterConstraints(new Condition() { + @Override + public boolean value(ConstraintPosition constraintPosition) { + return !positions.contains(constraintPosition); + } + }); + } + @NotNull public ConstraintSystem filterConstraints(@NotNull final Condition condition) { return replaceTypeVariables(Functions.identity(), @@ -273,9 +280,6 @@ public class ConstraintSystemImpl implements ConstraintSystem { ) { if (constrainingType != null && TypeUtils.noExpectedType(constrainingType)) return; - if (constraintPosition == ConstraintPosition.EXPECTED_TYPE_POSITION) { - systemWithoutExpectedTypeConstraint = copy(); - } addConstraint(SUB_TYPE, subjectType, constrainingType, constraintPosition); } @@ -483,8 +487,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { @Override public TypeSubstitutor getResultingSubstitutor() { if (getStatus().hasOnlyExpectedTypeMismatch()) { - assert systemWithoutExpectedTypeConstraint != null; - return systemWithoutExpectedTypeConstraint.getResultingSubstitutor(); + return filterConstraintsOut(EXPECTED_TYPE_POSITION).getResultingSubstitutor(); } return resultingSubstitutor; }