KT-10460: use unsubstituted descriptors
while comparing overloaded generic functions for specificity.
This commit is contained in:
+6
@@ -87,6 +87,12 @@ public abstract class DelegatingResolvedCall<D extends CallableDescriptor> imple
|
|||||||
return resolvedCall.getValueArguments();
|
return resolvedCall.getValueArguments();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Map<ValueParameterDescriptor, ResolvedValueArgument> getUnsubstitutedValueArguments() {
|
||||||
|
return resolvedCall.getUnsubstitutedValueArguments();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ArgumentMapping getArgumentMapping(@NotNull ValueArgument valueArgument) {
|
public ArgumentMapping getArgumentMapping(@NotNull ValueArgument valueArgument) {
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ public interface ResolvedCall<D extends CallableDescriptor> {
|
|||||||
@NotNull
|
@NotNull
|
||||||
Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments();
|
Map<ValueParameterDescriptor, ResolvedValueArgument> getValueArguments();
|
||||||
|
|
||||||
|
/** Values (arguments) for value parameters, no type parameter substitution */
|
||||||
|
@NotNull
|
||||||
|
Map<ValueParameterDescriptor, ResolvedValueArgument> getUnsubstitutedValueArguments();
|
||||||
|
|
||||||
/** Values (arguments) for value parameters indexed by parameter index */
|
/** Values (arguments) for value parameters indexed by parameter index */
|
||||||
@Nullable
|
@Nullable
|
||||||
List<ResolvedValueArgument> getValueArgumentsByIndex();
|
List<ResolvedValueArgument> getValueArgumentsByIndex();
|
||||||
|
|||||||
+11
-2
@@ -84,6 +84,7 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
|
|||||||
|
|
||||||
private final Map<TypeParameterDescriptor, KotlinType> typeArguments = Maps.newLinkedHashMap();
|
private final Map<TypeParameterDescriptor, KotlinType> typeArguments = Maps.newLinkedHashMap();
|
||||||
private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap();
|
private final Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = Maps.newLinkedHashMap();
|
||||||
|
private Map<ValueParameterDescriptor, ResolvedValueArgument> valueArgumentsBeforeSubstitution;
|
||||||
private final MutableDataFlowInfoForArguments dataFlowInfoForArguments;
|
private final MutableDataFlowInfoForArguments dataFlowInfoForArguments;
|
||||||
private final Map<ValueArgument, ArgumentMatchImpl> argumentToParameterMap = Maps.newHashMap();
|
private final Map<ValueArgument, ArgumentMatchImpl> argumentToParameterMap = Maps.newHashMap();
|
||||||
|
|
||||||
@@ -199,9 +200,9 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
|
|||||||
substitutedParametersMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
|
substitutedParametersMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<ValueParameterDescriptor, ResolvedValueArgument> originalValueArguments = Maps.newLinkedHashMap(valueArguments);
|
valueArgumentsBeforeSubstitution = Maps.newLinkedHashMap(valueArguments);
|
||||||
valueArguments.clear();
|
valueArguments.clear();
|
||||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : originalValueArguments.entrySet()) {
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : valueArgumentsBeforeSubstitution.entrySet()) {
|
||||||
ValueParameterDescriptor substitutedVersion = substitutedParametersMap.get(entry.getKey().getOriginal());
|
ValueParameterDescriptor substitutedVersion = substitutedParametersMap.get(entry.getKey().getOriginal());
|
||||||
assert substitutedVersion != null : entry.getKey();
|
assert substitutedVersion != null : entry.getKey();
|
||||||
valueArguments.put(substitutedVersion, entry.getValue());
|
valueArguments.put(substitutedVersion, entry.getValue());
|
||||||
@@ -263,6 +264,14 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
|
|||||||
return valueArguments;
|
return valueArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public Map<ValueParameterDescriptor, ResolvedValueArgument> getUnsubstitutedValueArguments() {
|
||||||
|
// TODO We need unsubstituted value arguments to compare signatures for specificity when explicit type arguments are provided.
|
||||||
|
// Current implementation is questionable (mostly due to lack of well-defined contract for MutableResolvedCall).
|
||||||
|
return valueArgumentsBeforeSubstitution != null ? valueArgumentsBeforeSubstitution : valueArguments;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public List<ResolvedValueArgument> getValueArgumentsByIndex() {
|
public List<ResolvedValueArgument> getValueArgumentsByIndex() {
|
||||||
|
|||||||
+13
-13
@@ -17,15 +17,12 @@
|
|||||||
package org.jetbrains.kotlin.resolve.calls.results
|
package org.jetbrains.kotlin.resolve.calls.results
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtElement
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument
|
||||||
import org.jetbrains.kotlin.types.BoundsSubstitutor
|
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
|
|
||||||
|
|
||||||
class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constructor(
|
class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constructor(
|
||||||
val resolvedCall: MutableResolvedCall<D>,
|
val resolvedCall: MutableResolvedCall<D>,
|
||||||
@@ -35,8 +32,14 @@ class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constr
|
|||||||
override fun toString(): String =
|
override fun toString(): String =
|
||||||
"${resolvedCall.call}: $parametersWithDefaultValuesCount defaults in ${resolvedCall.candidateDescriptor}"
|
"${resolvedCall.call}: $parametersWithDefaultValuesCount defaults in ${resolvedCall.candidateDescriptor}"
|
||||||
|
|
||||||
val resultingDescriptor: D
|
val candidateDescriptor: D
|
||||||
get() = resolvedCall.resultingDescriptor
|
get() = resolvedCall.candidateDescriptor
|
||||||
|
|
||||||
|
val hasVarargs: Boolean
|
||||||
|
get() = candidateDescriptor.valueParameters.any { it.varargElementType != null }
|
||||||
|
|
||||||
|
val typeParameters: List<TypeParameterDescriptor>
|
||||||
|
get() = candidateDescriptor.original.typeParameters
|
||||||
|
|
||||||
val argumentsCount: Int
|
val argumentsCount: Int
|
||||||
get() = argumentsToParameters.size
|
get() = argumentsToParameters.size
|
||||||
@@ -44,13 +47,10 @@ class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constr
|
|||||||
val argumentKeys: Collection<K>
|
val argumentKeys: Collection<K>
|
||||||
get() = argumentsToParameters.keys
|
get() = argumentsToParameters.keys
|
||||||
|
|
||||||
val callElement: KtElement
|
val isGeneric: Boolean = typeParameters.isNotEmpty()
|
||||||
get() = resolvedCall.call.callElement
|
|
||||||
|
|
||||||
val isGeneric: Boolean = resolvedCall.resultingDescriptor.original.typeParameters.isNotEmpty()
|
|
||||||
|
|
||||||
val extensionReceiverType: KotlinType?
|
val extensionReceiverType: KotlinType?
|
||||||
get() = resultingDescriptor.extensionReceiverParameter?.type
|
get() = candidateDescriptor.extensionReceiverParameter?.type
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type of a value that can be used in place of the corresponding parameter.
|
* Returns the type of a value that can be used in place of the corresponding parameter.
|
||||||
@@ -69,14 +69,14 @@ class CandidateCallWithArgumentMapping<D : CallableDescriptor, K> private constr
|
|||||||
val argumentsToParameters = hashMapOf<K, ValueParameterDescriptor>()
|
val argumentsToParameters = hashMapOf<K, ValueParameterDescriptor>()
|
||||||
var parametersWithDefaultValuesCount = 0
|
var parametersWithDefaultValuesCount = 0
|
||||||
|
|
||||||
for ((valueParameterDescriptor, resolvedValueArgument) in call.valueArguments.entries) {
|
for ((valueParameterDescriptor, resolvedValueArgument) in call.unsubstitutedValueArguments.entries) {
|
||||||
if (resolvedValueArgument is DefaultValueArgument) {
|
if (resolvedValueArgument is DefaultValueArgument) {
|
||||||
parametersWithDefaultValuesCount++
|
parametersWithDefaultValuesCount++
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val keys = resolvedArgumentToKeys(resolvedValueArgument)
|
val keys = resolvedArgumentToKeys(resolvedValueArgument)
|
||||||
for (argumentKey in keys) {
|
for (argumentKey in keys) {
|
||||||
argumentsToParameters[argumentKey] = valueParameterDescriptor
|
argumentsToParameters[argumentKey] = valueParameterDescriptor.original
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -136,7 +136,7 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
call2: CandidateCallWithArgumentMapping<D, K>,
|
call2: CandidateCallWithArgumentMapping<D, K>,
|
||||||
discriminateGenerics: Boolean
|
discriminateGenerics: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return tryCompareDescriptorsFromScripts(call1.resultingDescriptor, call2.resultingDescriptor) ?:
|
return tryCompareDescriptorsFromScripts(call1.candidateDescriptor, call2.candidateDescriptor) ?:
|
||||||
compareCallsByUsedArguments(call1, call2, discriminateGenerics)
|
compareCallsByUsedArguments(call1, call2, discriminateGenerics)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
if (isGeneric1 && isGeneric2) return false
|
if (isGeneric1 && isGeneric2) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val typeParameters = call2.resolvedCall.resultingDescriptor.typeParameters
|
val typeParameters = call2.typeParameters
|
||||||
val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl()
|
val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl()
|
||||||
var hasConstraints = false
|
var hasConstraints = false
|
||||||
val typeSubstitutor = constraintSystemBuilder.registerTypeVariables(call1.resolvedCall.call.toHandle(), typeParameters)
|
val typeSubstitutor = constraintSystemBuilder.registerTypeVariables(call1.resolvedCall.call.toHandle(), typeParameters)
|
||||||
@@ -219,8 +219,8 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
|||||||
call1: CandidateCallWithArgumentMapping<D, K>,
|
call1: CandidateCallWithArgumentMapping<D, K>,
|
||||||
call2: CandidateCallWithArgumentMapping<D, K>
|
call2: CandidateCallWithArgumentMapping<D, K>
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val hasVarargs1 = call1.resultingDescriptor.hasVarargs
|
val hasVarargs1 = call1.hasVarargs
|
||||||
val hasVarargs2 = call2.resultingDescriptor.hasVarargs
|
val hasVarargs2 = call2.hasVarargs
|
||||||
if (hasVarargs1 && !hasVarargs2) return false
|
if (hasVarargs1 && !hasVarargs2) return false
|
||||||
if (!hasVarargs1 && hasVarargs2) return true
|
if (!hasVarargs1 && hasVarargs2) return true
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Inv<T>() {
|
|||||||
fun testInOut() {
|
fun testInOut() {
|
||||||
In<String>().f("1");
|
In<String>().f("1");
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<<!REDUNDANT_PROJECTION!>in<!> String>).f("1")
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<<!REDUNDANT_PROJECTION!>in<!> String>).f("1")
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<*>).f(<!TYPE_MISMATCH!>"1"<!>) // Wrong Arg
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<*>).<!NONE_APPLICABLE!>f<!>("1") // Wrong Arg
|
||||||
|
|
||||||
In<String>().f(1);
|
In<String>().f(1);
|
||||||
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<<!REDUNDANT_PROJECTION!>in<!> String>).f(1)
|
(null <!CAST_NEVER_SUCCEEDS!>as<!> In<<!REDUNDANT_PROJECTION!>in<!> String>).f(1)
|
||||||
|
|||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -REDUNDANT_PROJECTION
|
||||||
|
|
||||||
|
class In<in T>() {
|
||||||
|
fun f(t : T) {}
|
||||||
|
fun f(t : Int) = t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test1(x: In<String>): Unit = x.f("1")
|
||||||
|
fun test2(x: In<in String>): Unit = x.f("1")
|
||||||
|
fun test3(x: In<<!CONFLICTING_PROJECTION!>out<!> String>): Unit = x.<!NONE_APPLICABLE!>f<!>("1")
|
||||||
|
fun test4(x: In<*>): Unit = x.<!NONE_APPLICABLE!>f<!>("1")
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test1(/*0*/ x: In<kotlin.String>): kotlin.Unit
|
||||||
|
public fun test2(/*0*/ x: In<in kotlin.String>): kotlin.Unit
|
||||||
|
public fun test3(/*0*/ x: In<out kotlin.String>): kotlin.Unit
|
||||||
|
public fun test4(/*0*/ x: In<*>): kotlin.Unit
|
||||||
|
|
||||||
|
public final class In</*0*/ in T> {
|
||||||
|
public constructor In</*0*/ in T>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun f(/*0*/ t: T): kotlin.Unit
|
||||||
|
public final fun f(/*0*/ t: kotlin.Int): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
interface AutoCloseable
|
||||||
|
interface Closeable : AutoCloseable
|
||||||
|
|
||||||
|
fun <T1 : AutoCloseable, R1> T1.myUse(f: (T1) -> R1): R1 = f(this)
|
||||||
|
fun <T2 : Closeable, R2> T2.myUse(f: (T2) -> R2): R2 = f(this)
|
||||||
|
|
||||||
|
fun test1(x: Closeable) = x.myUse { 42 }
|
||||||
|
fun test2(x: Closeable) = x.myUse<Closeable, Int> { 42 }
|
||||||
|
fun test3(x: Closeable) = x.myUse<<!UPPER_BOUND_VIOLATED!>AutoCloseable<!>, Int> { 42 } // TODO KT-10681
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test1(/*0*/ x: Closeable): kotlin.Int
|
||||||
|
public fun test2(/*0*/ x: Closeable): kotlin.Int
|
||||||
|
public fun test3(/*0*/ x: Closeable): kotlin.Int
|
||||||
|
public fun </*0*/ T1 : AutoCloseable, /*1*/ R1> T1.myUse(/*0*/ f: (T1) -> R1): R1
|
||||||
|
public fun </*0*/ T2 : Closeable, /*1*/ R2> T2.myUse(/*0*/ f: (T2) -> R2): R2
|
||||||
|
|
||||||
|
public interface AutoCloseable {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Closeable : AutoCloseable {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+2
-2
@@ -17,8 +17,8 @@ val y2: B<Int> = B("")
|
|||||||
val y3: B<Int> = B<Int>(1)
|
val y3: B<Int> = B<Int>(1)
|
||||||
val y4: B<Int> = B<Int>("")
|
val y4: B<Int> = B<Int>("")
|
||||||
|
|
||||||
val y5: B<String> = <!NONE_APPLICABLE!>B<!><String>(1)
|
val y5: B<String> = B<String>(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
||||||
val y6: B<String> = <!OVERLOAD_RESOLUTION_AMBIGUITY!>B<!><String>("") // TODO: doesn't work here but ok on y8
|
val y6: B<String> = B<String>("")
|
||||||
val y7: B<String> = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>B(1)<!>
|
val y7: B<String> = <!TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>B(1)<!>
|
||||||
val y8: B<String> = B("")
|
val y8: B<String> = B("")
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ class A0<T1, T2> {
|
|||||||
|
|
||||||
constructor(x: T1, y: T2, z: T2): this(x, 1) // ok, delegates to constructor(x: T1, y: Int)
|
constructor(x: T1, y: T2, z: T2): this(x, 1) // ok, delegates to constructor(x: T1, y: Int)
|
||||||
|
|
||||||
constructor(x: T1, y: Int): <!NONE_APPLICABLE!>this<!>(x, "")
|
constructor(x: T1, y: Int): this(x, <!TYPE_MISMATCH!>""<!>)
|
||||||
constructor(x: T1): this(x, 1)
|
constructor(x: T1): this(x, 1)
|
||||||
constructor(x: T1, y: T2, z: String): <!NONE_APPLICABLE!>this<!>(y, x)
|
constructor(x: T1, y: T2, z: String): this(<!TYPE_MISMATCH!>y<!>, <!TYPE_MISMATCH!>x<!>)
|
||||||
}
|
}
|
||||||
|
|
||||||
class A1<T1, T2> : B<T1, T2> {
|
class A1<T1, T2> : B<T1, T2> {
|
||||||
|
|||||||
+2
-2
@@ -18,8 +18,8 @@ class Inv<T>() {
|
|||||||
fun testInOut() {
|
fun testInOut() {
|
||||||
In<String>().`In.f:T->Unit`f("1");
|
In<String>().`In.f:T->Unit`f("1");
|
||||||
(return as In<in String>).`In.f:T->Unit`f("1");
|
(return as In<in String>).`In.f:T->Unit`f("1");
|
||||||
(return as In<out String>).`In.f:T->Unit`f("1")
|
(return as In<out String>).`!null`f("1")
|
||||||
(return as In<*>).`In.f:T->Unit`f("1");
|
(return as In<*>).`!null`f("1");
|
||||||
|
|
||||||
In<String>().`In.f:Int->Int`f(1);
|
In<String>().`In.f:Int->Int`f(1);
|
||||||
(return as In<in String>).`In.f:Int->Int`f(1);
|
(return as In<in String>).`In.f:Int->Int`f(1);
|
||||||
|
|||||||
@@ -13952,12 +13952,24 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("genericWithProjection.kt")
|
||||||
|
public void testGenericWithProjection() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/genericWithProjection.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt10472.kt")
|
@TestMetadata("kt10472.kt")
|
||||||
public void testKt10472() throws Exception {
|
public void testKt10472() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/kt10472.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/kt10472.kt");
|
||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt10640.kt")
|
||||||
|
public void testKt10640() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/kt10640.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("numberOfDefaults.kt")
|
@TestMetadata("numberOfDefaults.kt")
|
||||||
public void testNumberOfDefaults() throws Exception {
|
public void testNumberOfDefaults() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/numberOfDefaults.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/numberOfDefaults.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user