diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadingConflictResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadingConflictResolver.java index ce0193e11ae..243f30baab7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadingConflictResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadingConflictResolver.java @@ -158,18 +158,18 @@ public class OverloadingConflictResolver { } } - // Check the non-matching parameters of one function against the vararg parameter of the other funciton + // Check the non-matching parameters of one function against the vararg parameter of the other function // Example: - // f(a : A, vararg vf : T) - // g(vararg vg : T) - // here we check that typeof(a) < typeof(vg) and elementTypeOf(vf) < elementTypeOf(vg) + // f(vararg vf : T) + // g(a : A, vararg vg : T) + // here we check that typeOf(a) < elementTypeOf(vf) and elementTypeOf(vg) < elementTypeOf(vf) if (fSize < gSize) { ValueParameterDescriptor fParam = fParams.get(fSize - 1); JetType fParamType = fParam.getVarargElementType(); assert fParamType != null : "fIsVararg guarantees this"; for (int i = fSize - 1; i < gSize; i++) { ValueParameterDescriptor gParam = gParams.get(i); - if (!typeMoreSpecific(fParamType, gParam.getType())) { + if (!typeMoreSpecific(fParamType, getVarargElementTypeOrType(gParam))) { return false; } } @@ -180,7 +180,7 @@ public class OverloadingConflictResolver { assert gParamType != null : "gIsVararg guarantees this"; for (int i = gSize - 1; i < fSize; i++) { ValueParameterDescriptor fParam = fParams.get(i); - if (!typeMoreSpecific(fParam.getType(), gParamType)) { + if (!typeMoreSpecific(getVarargElementTypeOrType(fParam), gParamType)) { return false; } } @@ -190,6 +190,15 @@ public class OverloadingConflictResolver { return true; } + @NotNull + private static JetType getVarargElementTypeOrType(@NotNull ValueParameterDescriptor parameterDescriptor) { + JetType varargElementType = parameterDescriptor.getVarargElementType(); + if (varargElementType != null) { + return varargElementType; + } + return parameterDescriptor.getType(); + } + private boolean isVariableArity(List fParams) { int fSize = fParams.size(); return fSize > 0 && fParams.get(fSize - 1).getVarargElementType() != null; diff --git a/compiler/testData/diagnostics/tests/varargs/kt422.kt b/compiler/testData/diagnostics/tests/varargs/kt422.kt new file mode 100644 index 00000000000..c363fcd1839 --- /dev/null +++ b/compiler/testData/diagnostics/tests/varargs/kt422.kt @@ -0,0 +1,17 @@ +// KT-422 Tune literal typing rules so that varargs overloaded by primitive types work + +fun foo(vararg t : T) = t +fun foo(vararg a: Int) = a +fun foo(vararg a: Long) = a + +fun test() { + foo(1, 2, 3) // Error, but should be foo of ints +} + +fun array(vararg elements : T) = elements +fun array(vararg elements : Int) = elements + +fun test1() { + array("A", "A") + array(1, 1) +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 5eaf3379aff..ccbca8c9593 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4257,6 +4257,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/varargs/kt1838-val.kt"); } + @TestMetadata("kt422.kt") + public void testKt422() throws Exception { + doTest("compiler/testData/diagnostics/tests/varargs/kt422.kt"); + } + @TestMetadata("MoreSpecificVarargsOfEqualLength.kt") public void testMoreSpecificVarargsOfEqualLength() throws Exception { doTest("compiler/testData/diagnostics/tests/varargs/MoreSpecificVarargsOfEqualLength.kt");