From 65e2f47bc3bd2ba2d9fc5c7f86622467c6df5eee Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 27 Sep 2013 13:53:27 +0400 Subject: [PATCH] try intersection of upper bounds as a suggestion not each bound itself while resolving constraint system --- .../upperBounds/intersectUpperBounds.kt | 30 +++++++++++++++++++ .../upperBounds/nonNullUpperBound.kt | 13 ++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 10 +++++++ .../calls/inference/TypeConstraintsImpl.java | 7 +++-- 4 files changed, 57 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inference/upperBounds/intersectUpperBounds.kt create mode 100644 compiler/testData/diagnostics/tests/inference/upperBounds/nonNullUpperBound.kt diff --git a/compiler/testData/diagnostics/tests/inference/upperBounds/intersectUpperBounds.kt b/compiler/testData/diagnostics/tests/inference/upperBounds/intersectUpperBounds.kt new file mode 100644 index 00000000000..df1f2c96524 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/upperBounds/intersectUpperBounds.kt @@ -0,0 +1,30 @@ +package s + +trait In + +trait A +trait B +trait C: A, B + +fun foo(in1: In, in2: In): T = throw Exception("$in1 $in2") + +fun test(inA: In, inB: In, inC: In) { + + foo(inA, inB) + + val r = foo(inA, inC) + r: C + + val c: C = foo(inA, inB) + + use(c) +} + +fun bar(in1: In): T = throw Exception("$in1") + +fun test(inA: In) { + val r = bar(inA) + r: C +} + +fun use(vararg a: Any?) = a \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/upperBounds/nonNullUpperBound.kt b/compiler/testData/diagnostics/tests/inference/upperBounds/nonNullUpperBound.kt new file mode 100644 index 00000000000..92dcd5508bf --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/upperBounds/nonNullUpperBound.kt @@ -0,0 +1,13 @@ +fun unescape(value: Any): R? = throw Exception("$value") + +fun foo(v: Any): T? = unescape(v) + +//-------------- + +trait A + +fun unescapeA(value: Any): R? = throw Exception("$value") + + +fun fooA(v: Any): T? = unescapeA(v) + diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 9d1ee1736f5..106514d9ffe 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3542,11 +3542,21 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inference/upperBounds/doNotInferFromBoundsOnly.kt"); } + @TestMetadata("intersectUpperBounds.kt") + public void testIntersectUpperBounds() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/upperBounds/intersectUpperBounds.kt"); + } + @TestMetadata("kt2856.kt") public void testKt2856() throws Exception { doTest("compiler/testData/diagnostics/tests/inference/upperBounds/kt2856.kt"); } + @TestMetadata("nonNullUpperBound.kt") + public void testNonNullUpperBound() throws Exception { + doTest("compiler/testData/diagnostics/tests/inference/upperBounds/nonNullUpperBound.kt"); + } + @TestMetadata("useBoundsIfUnknownParameters.kt") public void testUseBoundsIfUnknownParameters() throws Exception { doTest("compiler/testData/diagnostics/tests/inference/upperBounds/useBoundsIfUnknownParameters.kt"); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeConstraintsImpl.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeConstraintsImpl.java index a32fce90126..f3e3cefc452 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeConstraintsImpl.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/calls/inference/TypeConstraintsImpl.java @@ -186,9 +186,10 @@ public class TypeConstraintsImpl implements TypeConstraints { ContainerUtil.addIfNotNull(superTypeOfLowerBounds, values); Set upperBounds = filterBounds(constraints, BoundKind.UPPER_BOUND, values); - for (JetType upperBound : upperBounds) { - if (trySuggestion(upperBound, constraints)) { - return Collections.singleton(upperBound); + JetType intersectionOfUpperBounds = TypeUtils.intersect(JetTypeChecker.INSTANCE, upperBounds); + if (!upperBounds.isEmpty() && intersectionOfUpperBounds != null) { + if (trySuggestion(intersectionOfUpperBounds, constraints)) { + return Collections.singleton(intersectionOfUpperBounds); } } //todo