mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-20 08:31:28 +00:00
Use constraint system for comparing for specificity against a generic signature.
Drop "discrimiate generics" mode where it's unneeded.
This commit is contained in:
@@ -24,43 +24,42 @@ import org.jetbrains.kotlin.descriptors.ScriptDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.toHandle
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionMutableResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Specificity
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.getSpecificityRelationTo
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||
|
||||
fun <D : CallableDescriptor> findMaximallySpecific(
|
||||
candidates: Set<MutableResolvedCall<D>>,
|
||||
discriminateGenericDescriptors: Boolean,
|
||||
checkArgumentsMode: CheckArgumentTypesMode
|
||||
checkArgumentsMode: CheckArgumentTypesMode,
|
||||
discriminateGenerics: Boolean
|
||||
): MutableResolvedCall<D>? =
|
||||
if (candidates.size <= 1)
|
||||
candidates.firstOrNull()
|
||||
else when (checkArgumentsMode) {
|
||||
CheckArgumentTypesMode.CHECK_CALLABLE_TYPE ->
|
||||
uniquifyCandidatesSet(candidates).filter {
|
||||
isMaxSpecific(it, candidates) {
|
||||
isDefinitelyMostSpecific(it, candidates) {
|
||||
call1, call2 ->
|
||||
isNotLessSpecificCallableReference(call1.resultingDescriptor, call2.resultingDescriptor)
|
||||
}
|
||||
}.singleOrNull()
|
||||
|
||||
CheckArgumentTypesMode.CHECK_VALUE_ARGUMENTS ->
|
||||
findMaximallySpecificCall(candidates, discriminateGenericDescriptors)
|
||||
findMaximallySpecificCall(candidates, discriminateGenerics)
|
||||
}
|
||||
|
||||
fun <D : CallableDescriptor> findMaximallySpecificVariableAsFunctionCalls(
|
||||
candidates: Set<MutableResolvedCall<D>>,
|
||||
discriminateGenericDescriptors: Boolean
|
||||
): Set<MutableResolvedCall<D>> {
|
||||
fun <D : CallableDescriptor> findMaximallySpecificVariableAsFunctionCalls(candidates: Set<MutableResolvedCall<D>>): Set<MutableResolvedCall<D>> {
|
||||
val variableCalls = candidates.mapTo(newResolvedCallSet<MutableResolvedCall<VariableDescriptor>>(candidates.size)) {
|
||||
if (it is VariableAsFunctionMutableResolvedCall)
|
||||
it.variableCall
|
||||
@@ -68,17 +67,14 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||
throw AssertionError("Regular call among variable-as-function calls: $it")
|
||||
}
|
||||
|
||||
val maxSpecificVariableCall = findMaximallySpecificCall(variableCalls, discriminateGenericDescriptors) ?: return emptySet()
|
||||
val maxSpecificVariableCall = findMaximallySpecificCall(variableCalls, false) ?: return emptySet()
|
||||
|
||||
return candidates.filterTo(newResolvedCallSet<MutableResolvedCall<D>>(2)) {
|
||||
it.resultingVariableDescriptor == maxSpecificVariableCall.resultingDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> findMaximallySpecificCall(
|
||||
candidates: Set<MutableResolvedCall<D>>,
|
||||
discriminateGenericDescriptors: Boolean
|
||||
): MutableResolvedCall<D>? {
|
||||
private fun <D : CallableDescriptor> findMaximallySpecificCall(candidates: Set<MutableResolvedCall<D>>, discriminateGenerics: Boolean): MutableResolvedCall<D>? {
|
||||
val filteredCandidates = uniquifyCandidatesSet(candidates)
|
||||
|
||||
if (filteredCandidates.size <= 1) return filteredCandidates.singleOrNull()
|
||||
@@ -88,29 +84,41 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||
CandidateCallWithArgumentMapping.create(candidateCall) { it.arguments.filter { it.getArgumentExpression() != null } }
|
||||
}
|
||||
|
||||
val mostSpecificCandidates = conflictingCandidates.selectMostSpecificCallsWithArgumentMapping(discriminateGenericDescriptors)
|
||||
val bestCandidatesByParameterTypes = conflictingCandidates.mapNotNull {
|
||||
candidate ->
|
||||
candidate.check {
|
||||
isMostSpecific(candidate, conflictingCandidates) {
|
||||
call1, call2 ->
|
||||
isNotLessSpecificCallWithArgumentMapping(call1, call2, discriminateGenerics)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mostSpecificCandidates.singleOrNull()
|
||||
return bestCandidatesByParameterTypes.exactMaxWith { call1, call2 -> isOfNotLessSpecificShape(call1, call2) }?.resolvedCall
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor, K> Collection<CandidateCallWithArgumentMapping<D, K>>.selectMostSpecificCallsWithArgumentMapping(
|
||||
discriminateGenericDescriptors: Boolean
|
||||
): Collection<MutableResolvedCall<D>> =
|
||||
this.mapNotNull {
|
||||
candidate ->
|
||||
candidate.check {
|
||||
isMaxSpecific(candidate, this) {
|
||||
call1, call2 ->
|
||||
isNotLessSpecificCallWithArgumentMapping(call1, call2, discriminateGenericDescriptors)
|
||||
}
|
||||
}?.resolvedCall
|
||||
private inline fun <C : Any> Collection<C>.exactMaxWith(isNotWorse: (C, C) -> Boolean): C? {
|
||||
var result: C? = null
|
||||
for (candidate in this) {
|
||||
if (result == null || isNotWorse(candidate, result)) {
|
||||
result = candidate
|
||||
}
|
||||
}
|
||||
if (result == null) return null
|
||||
if (any { it != result && isNotWorse(it, result!!) }) {
|
||||
return null
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private inline fun <C> isMostSpecific(candidate: C, candidates: Collection<C>, isNotLessSpecific: (C, C) -> Boolean): Boolean =
|
||||
candidates.all {
|
||||
other ->
|
||||
candidate === other ||
|
||||
isNotLessSpecific(candidate, other)
|
||||
}
|
||||
|
||||
private inline fun <C> isMaxSpecific(
|
||||
candidate: C,
|
||||
candidates: Collection<C>,
|
||||
isNotLessSpecific: (C, C) -> Boolean
|
||||
): Boolean =
|
||||
private inline fun <C> isDefinitelyMostSpecific(candidate: C, candidates: Collection<C>, isNotLessSpecific: (C, C) -> Boolean): Boolean =
|
||||
candidates.all {
|
||||
other ->
|
||||
candidate === other ||
|
||||
@@ -123,53 +131,90 @@ class OverloadingConflictResolver(private val builtIns: KotlinBuiltIns) {
|
||||
private fun <D : CallableDescriptor, K> isNotLessSpecificCallWithArgumentMapping(
|
||||
call1: CandidateCallWithArgumentMapping<D, K>,
|
||||
call2: CandidateCallWithArgumentMapping<D, K>,
|
||||
discriminateGenericDescriptors: Boolean
|
||||
discriminateGenerics: Boolean
|
||||
): Boolean {
|
||||
return tryCompareDescriptorsFromScripts(call1.resultingDescriptor, call2.resultingDescriptor) ?:
|
||||
compareCallsWithArgumentMapping(call1, call2, discriminateGenericDescriptors)
|
||||
compareCallsByUsedArguments(call1, call2, discriminateGenerics)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if `d1` is definitely not less specific than `d2`,
|
||||
* `false` otherwise.
|
||||
*/
|
||||
private fun <D : CallableDescriptor, K> compareCallsWithArgumentMapping(
|
||||
private fun <D : CallableDescriptor, K> compareCallsByUsedArguments(
|
||||
call1: CandidateCallWithArgumentMapping<D, K>,
|
||||
call2: CandidateCallWithArgumentMapping<D, K>,
|
||||
discriminateGenericDescriptors: Boolean
|
||||
discriminateGenerics: Boolean
|
||||
): Boolean {
|
||||
val substituteParameterTypes =
|
||||
if (discriminateGenericDescriptors) {
|
||||
if (!call1.isGeneric && call2.isGeneric) return true
|
||||
if (call1.isGeneric && !call2.isGeneric) return false
|
||||
call1.isGeneric && call2.isGeneric
|
||||
}
|
||||
else false
|
||||
|
||||
val extensionReceiverType1 = call1.getExtensionReceiverType(substituteParameterTypes)
|
||||
val extensionReceiverType2 = call2.getExtensionReceiverType(substituteParameterTypes)
|
||||
tryCompareExtensionReceiverType(extensionReceiverType1, extensionReceiverType2)?.let {
|
||||
return it
|
||||
if (discriminateGenerics) {
|
||||
val isGeneric1 = call1.isGeneric
|
||||
val isGeneric2 = call2.isGeneric
|
||||
if (isGeneric1 && !isGeneric2) return false
|
||||
if (!isGeneric1 && isGeneric2) return true
|
||||
if (isGeneric1 && isGeneric2) return false
|
||||
}
|
||||
|
||||
val hasVarargs1 = call1.resultingDescriptor.hasVarargs
|
||||
val hasVarargs2 = call2.resultingDescriptor.hasVarargs
|
||||
if (hasVarargs1 && !hasVarargs2) return false
|
||||
if (!hasVarargs1 && hasVarargs2) return true
|
||||
val typeParameters = call2.resolvedCall.resultingDescriptor.typeParameters
|
||||
val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl()
|
||||
var hasConstraints = false
|
||||
val typeSubstitutor = constraintSystemBuilder.registerTypeVariables(call1.resolvedCall.call.toHandle(), typeParameters)
|
||||
|
||||
fun compareTypesAndUpdateConstraints(type1: KotlinType?, type2: KotlinType?, constraintPosition: ConstraintPosition): Boolean {
|
||||
if (type1 == null || type2 == null) return true
|
||||
|
||||
if (typeParameters.isEmpty() || !TypeUtils.dependsOnTypeParameters(type2, typeParameters)) {
|
||||
if (!typeNotLessSpecific(type1, type2)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
else {
|
||||
val substitutedType2 = typeSubstitutor.safeSubstitute(type2, Variance.INVARIANT)
|
||||
constraintSystemBuilder.addSubtypeConstraint(type1, substitutedType2, constraintPosition)
|
||||
hasConstraints = true
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
val extensionReceiverType1 = call1.getExtensionReceiverType(false)
|
||||
val extensionReceiverType2 = call2.getExtensionReceiverType(false)
|
||||
if (!compareTypesAndUpdateConstraints(extensionReceiverType1, extensionReceiverType2, ConstraintPositionKind.RECEIVER_POSITION.position())) {
|
||||
return false
|
||||
}
|
||||
|
||||
assert(call1.argumentsCount == call2.argumentsCount) {
|
||||
"$call1 and $call2 have different number of explicit arguments"
|
||||
}
|
||||
|
||||
var index = 0
|
||||
for (argumentKey in call1.argumentKeys) {
|
||||
val type1 = call1.getValueParameterType(argumentKey, substituteParameterTypes) ?: continue
|
||||
val type2 = call2.getValueParameterType(argumentKey, substituteParameterTypes) ?: continue
|
||||
val type1 = call1.getValueParameterType(argumentKey, false)
|
||||
val type2 = call2.getValueParameterType(argumentKey, false)
|
||||
|
||||
if (!typeNotLessSpecific(type1, type2)) {
|
||||
if (!compareTypesAndUpdateConstraints(type1, type2, ConstraintPositionKind.VALUE_PARAMETER_POSITION.position(index++))) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (hasConstraints) {
|
||||
constraintSystemBuilder.fixVariables()
|
||||
val constraintSystem = constraintSystemBuilder.build()
|
||||
if (constraintSystem.status.hasContradiction()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun <D: CallableDescriptor, K> isOfNotLessSpecificShape(
|
||||
call1: CandidateCallWithArgumentMapping<D, K>,
|
||||
call2: CandidateCallWithArgumentMapping<D, K>
|
||||
): Boolean {
|
||||
val hasVarargs1 = call1.resultingDescriptor.hasVarargs
|
||||
val hasVarargs2 = call2.resultingDescriptor.hasVarargs
|
||||
if (hasVarargs1 && !hasVarargs2) return false
|
||||
if (!hasVarargs1 && hasVarargs2) return true
|
||||
|
||||
if (call1.parametersWithDefaultValuesCount > call2.parametersWithDefaultValuesCount) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ public class ResolutionResultsHandler {
|
||||
}
|
||||
|
||||
if (candidates.iterator().next() instanceof VariableAsFunctionResolvedCall) {
|
||||
candidates = overloadingConflictResolver.findMaximallySpecificVariableAsFunctionCalls(candidates, discriminateGenerics);
|
||||
candidates = overloadingConflictResolver.findMaximallySpecificVariableAsFunctionCalls(candidates);
|
||||
}
|
||||
|
||||
Set<MutableResolvedCall<D>> noOverrides = OverrideResolver.filterOutOverridden(candidates, MAP_TO_RESULT);
|
||||
@@ -203,14 +203,14 @@ public class ResolutionResultsHandler {
|
||||
return OverloadResolutionResultsImpl.success(noOverrides.iterator().next());
|
||||
}
|
||||
|
||||
MutableResolvedCall<D> maximallySpecific = overloadingConflictResolver.findMaximallySpecific(noOverrides, false, checkArgumentsMode);
|
||||
MutableResolvedCall<D> maximallySpecific = overloadingConflictResolver.findMaximallySpecific(noOverrides, checkArgumentsMode, false);
|
||||
if (maximallySpecific != null) {
|
||||
return OverloadResolutionResultsImpl.success(maximallySpecific);
|
||||
}
|
||||
|
||||
if (discriminateGenerics) {
|
||||
MutableResolvedCall<D> maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(
|
||||
noOverrides, true, checkArgumentsMode);
|
||||
noOverrides, checkArgumentsMode, true);
|
||||
if (maximallySpecificGenericsDiscriminated != null) {
|
||||
return OverloadResolutionResultsImpl.success(maximallySpecificGenericsDiscriminated);
|
||||
}
|
||||
|
||||
@@ -51,9 +51,9 @@ fun test() {
|
||||
h checkType { _<Int>() }
|
||||
|
||||
|
||||
<!OVERLOAD_RESOLUTION_AMBIGUITY!>wrongTwoDefault<!>(1)
|
||||
wrongTwoDefault(1)
|
||||
|
||||
<!CANNOT_COMPLETE_RESOLVE!>wrongWithDefaultGeneric<!>("")
|
||||
wrongWithDefaultGeneric("")
|
||||
|
||||
<!UNREACHABLE_CODE!><!OVERLOAD_RESOLUTION_AMBIGUITY!>wrong<!>(<!>null!!<!UNREACHABLE_CODE!>)<!>
|
||||
}
|
||||
9
compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.kt
vendored
Normal file
9
compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
object X1
|
||||
object X2
|
||||
|
||||
fun <T1> foo(x: T1, f: (T1) -> T1) = X1
|
||||
fun <T2> foo(xf: () -> T2, f: (T2) -> T2) = X2
|
||||
|
||||
val test: X2 = <!CANNOT_COMPLETE_RESOLVE!>foo<!>({ 0 }, { <!CANNOT_INFER_PARAMETER_TYPE!>it<!> -> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>it<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>+<!> 1 })
|
||||
19
compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.txt
vendored
Normal file
19
compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.txt
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
public val test: X2
|
||||
public fun </*0*/ T2> foo(/*0*/ xf: () -> T2, /*1*/ f: (T2) -> T2): X2
|
||||
public fun </*0*/ T1> foo(/*0*/ x: T1, /*1*/ f: (T1) -> T1): X1
|
||||
|
||||
public object X1 {
|
||||
private constructor X1()
|
||||
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 object X2 {
|
||||
private constructor X2()
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
object Foo1
|
||||
object Foo2
|
||||
|
||||
fun foo(vararg ss: String) = Foo1
|
||||
fun foo(x: Any) = Foo2
|
||||
|
||||
val test1: Foo1 = foo("")
|
||||
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
public val test1: Foo1
|
||||
public fun foo(/*0*/ x: kotlin.Any): Foo2
|
||||
public fun foo(/*0*/ vararg ss: kotlin.String /*kotlin.Array<out kotlin.String>*/): Foo1
|
||||
|
||||
public object Foo1 {
|
||||
private constructor Foo1()
|
||||
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 object Foo2 {
|
||||
private constructor Foo2()
|
||||
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
|
||||
}
|
||||
@@ -6,7 +6,7 @@ object X2
|
||||
fun overloadedFun5(vararg ss: String) = X1
|
||||
fun overloadedFun5(s: String, vararg ss: String) = X2
|
||||
|
||||
val test1: X1 = <!OVERLOAD_RESOLUTION_AMBIGUITY!>overloadedFun5<!>("")
|
||||
val test1 = <!OVERLOAD_RESOLUTION_AMBIGUITY!>overloadedFun5<!>("")
|
||||
val test2 = <!OVERLOAD_RESOLUTION_AMBIGUITY!>overloadedFun5<!>("", "")
|
||||
val test3: X2 = overloadedFun5(s = "", ss = "")
|
||||
val test4: X1 = overloadedFun5(ss = "")
|
||||
@@ -1,6 +1,6 @@
|
||||
package
|
||||
|
||||
public val test1: X1
|
||||
public val test1: [ERROR : Type for overloadedFun5("")]
|
||||
public val test2: [ERROR : Type for overloadedFun5("", "")]
|
||||
public val test3: X2
|
||||
public val test4: X1
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
import java.util.*
|
||||
|
||||
public class J {
|
||||
public static <E extends Enum<E>> String foo(E e) { return ""; }
|
||||
public static <E extends Enum<E>> String foo(E e1, E e2) { return ""; }
|
||||
public static <E extends Enum<E>> String foo(E s1, E s2, E s3) { return ""; }
|
||||
public static <E extends Enum<E>> int foo(E... ss) { return 0; }
|
||||
public static <E1 extends Enum<E1>> String foo(E1 e) { return ""; }
|
||||
public static <E2 extends Enum<E2>> String foo(E2 e1, E2 e2) { return ""; }
|
||||
public static <E3 extends Enum<E3>> String foo(E3 s1, E3 s2, E3 s3) { return ""; }
|
||||
public static <E4 extends Enum<E4>> int foo(E4... ss) { return 0; }
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
@@ -15,10 +15,10 @@ public open class J {
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public open fun </*0*/ E : kotlin.Enum<E!>!> foo(/*0*/ e: E!): kotlin.String!
|
||||
public open fun </*0*/ E : kotlin.Enum<E!>!> foo(/*0*/ e1: E!, /*1*/ e2: E!): kotlin.String!
|
||||
public open fun </*0*/ E : kotlin.Enum<E!>!> foo(/*0*/ s1: E!, /*1*/ s2: E!, /*2*/ s3: E!): kotlin.String!
|
||||
public open fun </*0*/ E : kotlin.Enum<E!>!> foo(/*0*/ vararg ss: E! /*kotlin.Array<(out) E!>!*/): kotlin.Int
|
||||
public open fun </*0*/ E1 : kotlin.Enum<E1!>!> foo(/*0*/ e: E1!): kotlin.String!
|
||||
public open fun </*0*/ E2 : kotlin.Enum<E2!>!> foo(/*0*/ e1: E2!, /*1*/ e2: E2!): kotlin.String!
|
||||
public open fun </*0*/ E3 : kotlin.Enum<E3!>!> foo(/*0*/ s1: E3!, /*1*/ s2: E3!, /*2*/ s3: E3!): kotlin.String!
|
||||
public open fun </*0*/ E4 : kotlin.Enum<E4!>!> foo(/*0*/ vararg ss: E4! /*kotlin.Array<(out) E4!>!*/): kotlin.Int
|
||||
}
|
||||
|
||||
public final enum class X : kotlin.Enum<X> {
|
||||
9
compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.kt
vendored
Normal file
9
compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.kt
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
object X1
|
||||
object X2
|
||||
|
||||
class A<T>
|
||||
|
||||
fun <T1> A<T1>.foo() = X1
|
||||
fun <T2> A<out T2>.foo() = X2
|
||||
|
||||
fun <T> A<out T>.test() = <!CANNOT_COMPLETE_RESOLVE!>foo<!>()
|
||||
26
compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.txt
vendored
Normal file
26
compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.txt
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T1> A<T1>.foo(): X1
|
||||
public fun </*0*/ T2> A<out T2>.foo(): X2
|
||||
public fun </*0*/ T> A<out T>.test(): [ERROR : Error function type]
|
||||
|
||||
public final class A</*0*/ T> {
|
||||
public constructor A</*0*/ T>()
|
||||
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 object X1 {
|
||||
private constructor X1()
|
||||
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 object X2 {
|
||||
private constructor X2()
|
||||
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
|
||||
}
|
||||
@@ -13892,15 +13892,15 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/resolve/overloadConflicts"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("extensionReceiverAndVarargs.kt")
|
||||
public void testExtensionReceiverAndVarargs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/extensionReceiverAndVarargs.kt");
|
||||
@TestMetadata("allLambdas.kt")
|
||||
public void testAllLambdas() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/allLambdas.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("javaOverloadedVarargs.kt")
|
||||
public void testJavaOverloadedVarargs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/javaOverloadedVarargs.kt");
|
||||
@TestMetadata("extensionReceiverAndVarargs.kt")
|
||||
public void testExtensionReceiverAndVarargs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/extensionReceiverAndVarargs.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@@ -13922,6 +13922,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargWithMoreSpecificSignature.kt")
|
||||
public void testVarargWithMoreSpecificSignature() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargWithMoreSpecificSignature.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargs.kt")
|
||||
public void testVarargs() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargs.kt");
|
||||
@@ -13939,6 +13945,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsMixed.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargsWithRecursiveGenerics.kt")
|
||||
public void testVarargsWithRecursiveGenerics() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/varargsWithRecursiveGenerics.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withVariance.kt")
|
||||
public void testWithVariance() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/resolve/overloadConflicts/withVariance.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/resolve/priority")
|
||||
|
||||
Reference in New Issue
Block a user