diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index c09270c5cd0..cb2850ae44d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -378,9 +378,7 @@ public class CallResolver { if (!constraintSystem.isSuccessful()) { - if (constraintSystemWithoutExpectedTypeConstraint.isSuccessful()) { - resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor()); - } + resolvedCall.setResultingSubstitutor(constraintSystemWithoutExpectedTypeConstraint.getResultingSubstitutor()); List argumentTypes = checkValueArgumentTypes(context, resolvedCall, resolvedCall.getTrace()).argumentTypes; JetType receiverType = resolvedCall.getReceiverArgument().exists() ? resolvedCall.getReceiverArgument().getType() : null; context.tracing.typeInferenceFailed(resolvedCall.getTrace(), diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java index 2072152fa58..7bc898a29b1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemImpl.java @@ -40,6 +40,7 @@ import static org.jetbrains.jet.lang.types.Variance.*; public class ConstraintSystemImpl implements ConstraintSystem { public static final JetType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE"); + private static final JetType CANT_INFER = ErrorUtils.createErrorType("CANT_INFER"); private final Map typeParameterConstraints = Maps.newLinkedHashMap(); private final Set errorConstraintPositions = Sets.newHashSet(); @@ -48,7 +49,7 @@ public class ConstraintSystemImpl implements ConstraintSystem { private boolean hasErrorInConstrainingTypes; public ConstraintSystemImpl() { - this.resultingSubstitutor = createTypeSubstitutorWithDefaultForUnknownTypeParameter(null); + this.resultingSubstitutor = createTypeSubstitutorWithDefaultForUnknownTypeParameter(new TypeProjection(CANT_INFER)); this.currentSubstitutor = createTypeSubstitutorWithDefaultForUnknownTypeParameter(new TypeProjection(DONT_CARE)); } @@ -154,16 +155,20 @@ public class ConstraintSystemImpl implements ConstraintSystem { @Nullable JetType constrainingType, @NotNull ConstraintPosition constraintPosition) { - if (constrainingType == null || (ErrorUtils.isErrorType(constrainingType) && constrainingType != DONT_CARE)) { + if (constrainingType == TypeUtils.NO_EXPECTED_TYPE + || TypeUtils.identityEqualsOrContainsAsArgument(constrainingType, DONT_CARE) + || TypeUtils.identityEqualsOrContainsAsArgument(constrainingType, CANT_INFER)) { + return; + } + + if (constrainingType == null || ErrorUtils.containsErrorType(constrainingType)) { hasErrorInConstrainingTypes = true; return; } assert subjectType != TypeUtils.NO_EXPECTED_TYPE : "Subject type shouldn't be NO_EXPECTED_TYPE (in position " + constraintPosition + " )"; + if (ErrorUtils.isErrorType(subjectType)) return; - if (constrainingType == DONT_CARE || ErrorUtils.isErrorType(subjectType) || constrainingType == TypeUtils.NO_EXPECTED_TYPE) { - return; - } DeclarationDescriptor constrainingTypeDescriptor = constrainingType.getConstructor().getDeclarationDescriptor(); DeclarationDescriptor subjectTypeDescriptor = subjectType.getConstructor().getDeclarationDescriptor(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java index 150b8280db5..380f13377b5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -472,4 +472,14 @@ public class TypeUtils { } return false; } + + public static boolean identityEqualsOrContainsAsArgument(@Nullable JetType type, @NotNull JetType argumentType) { + if (type == null) return false; + if (type == argumentType) return true; + if (type instanceof NamespaceType) return false; + for (TypeProjection projection : type.getArguments()) { + if (identityEqualsOrContainsAsArgument(projection.getType(), argumentType)) return true; + } + return false; + } } diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2841.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2841.kt new file mode 100644 index 00000000000..c96ce4a16ca --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2841.kt @@ -0,0 +1,15 @@ +package a + +trait Closeable {} +class C : Closeable {} + +public inline fun T.use1(block: (T)-> R) : R { + return block(this) +} + +fun main(args: Array) { + C().use1 { + w -> // ERROR here + x + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2841_it.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2841_it.kt new file mode 100644 index 00000000000..4ba463002ad --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2841_it.kt @@ -0,0 +1,18 @@ +package a + +trait Closeable { + fun close() {} +} + +class C : Closeable + +public inline fun T.use(block: (t: T)-> R) : R { + return block(this) +} + +fun test() { + C().use { + it.close() + x + } +} diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2841_it_this.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2841_it_this.kt new file mode 100644 index 00000000000..533b0884b5c --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2841_it_this.kt @@ -0,0 +1,19 @@ +package a + +trait Closeable { + fun close() {} +} + +class C : Closeable + +public inline fun use(t: T, block: T.(T)-> R) : R { + return t.block(t) +} + +fun test() { + use(C()) { + this.close() + it.close() + xx + } +} diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2841_this.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2841_this.kt new file mode 100644 index 00000000000..cdc9faa55cb --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2841_this.kt @@ -0,0 +1,18 @@ +package a + +trait Closeable { + fun close() {} +} + +class C : Closeable + +public inline fun T.use(block: T.()-> R) : R { + return this.block() +} + +fun test() { + C().use { + this.close() + x + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 36506f78444..f91af9c00ef 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -13,16 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.jetbrains.jet.checkers; +import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestSuite; + +import java.io.File; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import java.io.File; +import org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve; /** This class is generated by {@link org.jetbrains.jet.checkers.AbstractDiagnosticsTestWithEagerResolve}. DO NOT MODIFY MANUALLY */ @InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class}) @@ -1889,6 +1891,26 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2514.kt"); } + @TestMetadata("kt2841.kt") + public void testKt2841() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2841.kt"); + } + + @TestMetadata("kt2841_it.kt") + public void testKt2841_it() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2841_it.kt"); + } + + @TestMetadata("kt2841_it_this.kt") + public void testKt2841_it_this() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2841_it_this.kt"); + } + + @TestMetadata("kt2841_this.kt") + public void testKt2841_this() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2841_this.kt"); + } + @TestMetadata("kt2842.kt") public void testKt2842() throws Exception { doTest("compiler/testData/diagnostics/tests/inference/regressions/kt2842.kt");