[FIR] Keep all failed resolution candidates and fully resolve them
Previously, when a candidate was found with an applicability that is better than the current best applicability, all previous candidates were thrown away. Now we keep them, unless the new applicability is successful. If no successful candidates are found, we fully resolve all the unsuccessful ones and select the ones with the least bad applicability. This improves diagnostics for unresolved calls. #KT-57844 Fixed
This commit is contained in:
committed by
Space Team
parent
451daaa7c5
commit
b2fa104081
+6
@@ -26592,6 +26592,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/CycleInTypeArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorPriority.kt")
|
||||
public void testErrorPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/errorPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("HiddenDeclarations.kt")
|
||||
public void testHiddenDeclarations() throws Exception {
|
||||
|
||||
+6
@@ -26592,6 +26592,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/CycleInTypeArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorPriority.kt")
|
||||
public void testErrorPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/errorPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("HiddenDeclarations.kt")
|
||||
public void testHiddenDeclarations() throws Exception {
|
||||
|
||||
@@ -23,5 +23,5 @@ open class A5 {
|
||||
constructor(x: Short)
|
||||
}
|
||||
|
||||
class B5_1 : <!NONE_APPLICABLE!>A5<!>(1 + 1)
|
||||
class B5_2 : <!NONE_APPLICABLE!>A5<!>(100 * 2)
|
||||
class B5_1 : A5(<!ARGUMENT_TYPE_MISMATCH!>1 + 1<!>)
|
||||
class B5_2 : A5(<!ARGUMENT_TYPE_MISMATCH!>100 * 2<!>)
|
||||
|
||||
@@ -6,5 +6,5 @@ sealed class WithPrivateConstructor private constructor(val x: Int) {
|
||||
private constructor() : this(42)
|
||||
}
|
||||
|
||||
object First : <!NONE_APPLICABLE!>WithPrivateConstructor<!>() // error
|
||||
object Second : <!NONE_APPLICABLE!>WithPrivateConstructor<!>(0) // error
|
||||
object First : <!INVISIBLE_REFERENCE!>WithPrivateConstructor<!>() // error
|
||||
object Second : <!INVISIBLE_REFERENCE!>WithPrivateConstructor<!>(0) // error
|
||||
|
||||
+6
@@ -26592,6 +26592,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/CycleInTypeArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorPriority.kt")
|
||||
public void testErrorPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/errorPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("HiddenDeclarations.kt")
|
||||
public void testHiddenDeclarations() throws Exception {
|
||||
|
||||
+6
@@ -26604,6 +26604,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/CycleInTypeArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorPriority.kt")
|
||||
public void testErrorPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/errorPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("HiddenDeclarations.kt")
|
||||
public void testHiddenDeclarations() throws Exception {
|
||||
|
||||
+6
@@ -50156,6 +50156,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
||||
public void testSuppressInvisible() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suppressInvisibleCtor.kt")
|
||||
public void testSuppressInvisibleCtor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisibleCtor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -50156,6 +50156,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
||||
public void testSuppressInvisible() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suppressInvisibleCtor.kt")
|
||||
public void testSuppressInvisibleCtor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisibleCtor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
-1
@@ -25,7 +25,12 @@ class ConeEquivalentCallConflictResolver(
|
||||
specificityComparator: TypeSpecificityComparator,
|
||||
inferenceComponents: InferenceComponents,
|
||||
transformerComponents: BodyResolveComponents
|
||||
) : AbstractConeCallConflictResolver(specificityComparator, inferenceComponents, transformerComponents) {
|
||||
) : AbstractConeCallConflictResolver(
|
||||
specificityComparator,
|
||||
inferenceComponents,
|
||||
transformerComponents,
|
||||
considerMissingArgumentsInSignatures = true,
|
||||
) {
|
||||
override fun chooseMaximallySpecificCandidates(
|
||||
candidates: Set<Candidate>,
|
||||
discriminateAbstracts: Boolean
|
||||
|
||||
@@ -164,52 +164,46 @@ class FirCallResolver(
|
||||
)
|
||||
towerResolver.reset()
|
||||
val result = towerResolver.runResolver(info, resolutionContext, collector)
|
||||
val bestCandidates = result.bestCandidates()
|
||||
|
||||
var reducedCandidates = reduceCandidates(bestCandidates, explicitReceiver, resolutionContext, result.currentApplicability.isSuccess)
|
||||
reducedCandidates = overloadByLambdaReturnTypeResolver.reduceCandidates(qualifiedAccess, bestCandidates, reducedCandidates)
|
||||
var (reducedCandidates, newApplicability) = reduceCandidates(result, explicitReceiver, resolutionContext)
|
||||
reducedCandidates = overloadByLambdaReturnTypeResolver.reduceCandidates(qualifiedAccess, reducedCandidates, reducedCandidates)
|
||||
|
||||
return ResolutionResult(info, result.currentApplicability, reducedCandidates)
|
||||
return ResolutionResult(info, newApplicability ?: result.currentApplicability, reducedCandidates)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a [Pair] consisting of the reduced candidates and the new applicability if it has changed and `null` otherwise.
|
||||
*/
|
||||
private fun reduceCandidates(
|
||||
candidates: List<Candidate>,
|
||||
explicitReceiver: FirExpression?,
|
||||
resolutionContext: ResolutionContext,
|
||||
isSuccess: Boolean,
|
||||
): Set<Candidate> {
|
||||
collector: CandidateCollector,
|
||||
explicitReceiver: FirExpression? = null,
|
||||
resolutionContext: ResolutionContext = transformer.resolutionContext,
|
||||
): Pair<Set<Candidate>, CandidateApplicability?> {
|
||||
fun chooseMostSpecific(list: List<Candidate>): Set<Candidate> {
|
||||
val onSuperReference = (explicitReceiver as? FirQualifiedAccessExpression)?.calleeReference is FirSuperReference
|
||||
return conflictResolver.chooseMaximallySpecificCandidates(list, discriminateAbstracts = onSuperReference)
|
||||
}
|
||||
|
||||
if (isSuccess) {
|
||||
return chooseMostSpecific(candidates)
|
||||
val candidates = collector.bestCandidates()
|
||||
|
||||
if (collector.currentApplicability.isSuccess) {
|
||||
return chooseMostSpecific(candidates) to null
|
||||
}
|
||||
|
||||
val singleApplicability = candidates.mapTo(mutableSetOf()) { it.currentApplicability }.singleOrNull()
|
||||
|
||||
if (singleApplicability == null || singleApplicability <= CandidateApplicability.INAPPLICABLE) {
|
||||
return candidates.toSet()
|
||||
}
|
||||
|
||||
// If all candidates have the same kind on inapplicability - try to choose the most specific one
|
||||
if (candidates.size > 1) {
|
||||
// We have multiple candidates with the same inapplicability. We want to select the "least bad" candidates.
|
||||
|
||||
// First, fully process all of them and group them by their worst applicability.
|
||||
val groupedByDiagnosticCount = candidates.groupBy {
|
||||
components.resolutionStageRunner.fullyProcessCandidate(it, resolutionContext)
|
||||
it.diagnostics.minOf(ResolutionDiagnostic::applicability)
|
||||
}
|
||||
|
||||
// Then, select the group with the best worst applicability.
|
||||
// Then, select the group with the least bad applicability.
|
||||
groupedByDiagnosticCount.maxBy { it.key }.let {
|
||||
return chooseMostSpecific(it.value)
|
||||
return chooseMostSpecific(it.value) to it.key
|
||||
}
|
||||
}
|
||||
|
||||
return chooseMostSpecific(candidates)
|
||||
return candidates.toSet() to null
|
||||
}
|
||||
|
||||
fun resolveVariableAccessAndSelectCandidate(
|
||||
@@ -384,23 +378,18 @@ class FirCallResolver(
|
||||
manager = TowerResolveManager(localCollector),
|
||||
)
|
||||
}
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val applicability = result.currentApplicability
|
||||
val noSuccessfulCandidates = !applicability.isSuccess
|
||||
val reducedCandidates = if (noSuccessfulCandidates) {
|
||||
bestCandidates.toSet()
|
||||
} else {
|
||||
conflictResolver.chooseMaximallySpecificCandidates(bestCandidates)
|
||||
}
|
||||
val isSuccess = result.currentApplicability.isSuccess
|
||||
val (reducedCandidates, newApplicability) = reduceCandidates(result, callableReferenceAccess.explicitReceiver)
|
||||
val applicability = newApplicability ?: result.currentApplicability
|
||||
|
||||
(callableReferenceAccess.explicitReceiver as? FirResolvedQualifier)?.replaceResolvedToCompanionObject(
|
||||
bestCandidates.isNotEmpty() && bestCandidates.all { it.isFromCompanionObjectTypeScope }
|
||||
reducedCandidates.isNotEmpty() && reducedCandidates.all { it.isFromCompanionObjectTypeScope }
|
||||
)
|
||||
|
||||
resolvedCallableReferenceAtom.hasBeenResolvedOnce = true
|
||||
|
||||
when {
|
||||
noSuccessfulCandidates -> {
|
||||
!isSuccess -> {
|
||||
val errorReference = buildReferenceWithErrorCandidate(
|
||||
info,
|
||||
if (applicability == CandidateApplicability.K2_UNSUPPORTED) {
|
||||
@@ -496,7 +485,7 @@ class FirCallResolver(
|
||||
transformer.resolutionContext
|
||||
)
|
||||
|
||||
return components.callResolver.selectDelegatingConstructorCall(delegatedConstructorCall, name, result, callInfo)
|
||||
return selectDelegatingConstructorCall(delegatedConstructorCall, name, result, callInfo)
|
||||
}
|
||||
|
||||
private fun ConeTypeProjection.toFirTypeProjection(): FirTypeProjection = when (this) {
|
||||
@@ -594,19 +583,14 @@ class FirCallResolver(
|
||||
private fun selectDelegatingConstructorCall(
|
||||
call: FirDelegatedConstructorCall, name: Name, result: CandidateCollector, callInfo: CallInfo
|
||||
): FirDelegatedConstructorCall {
|
||||
val bestCandidates = result.bestCandidates()
|
||||
val reducedCandidates = if (!result.currentApplicability.isSuccess) {
|
||||
bestCandidates.toSet()
|
||||
} else {
|
||||
conflictResolver.chooseMaximallySpecificCandidates(bestCandidates)
|
||||
}
|
||||
val (reducedCandidates, newApplicability) = reduceCandidates(result)
|
||||
|
||||
val nameReference = createResolvedNamedReference(
|
||||
call.calleeReference,
|
||||
name,
|
||||
callInfo,
|
||||
reducedCandidates,
|
||||
result.currentApplicability,
|
||||
newApplicability ?: result.currentApplicability,
|
||||
)
|
||||
|
||||
return call.apply {
|
||||
|
||||
+27
-8
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.resolve.calls
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
|
||||
@@ -32,7 +33,8 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
abstract class AbstractConeCallConflictResolver(
|
||||
private val specificityComparator: TypeSpecificityComparator,
|
||||
protected val inferenceComponents: InferenceComponents,
|
||||
private val transformerComponents: BodyResolveComponents
|
||||
private val transformerComponents: BodyResolveComponents,
|
||||
private val considerMissingArgumentsInSignatures: Boolean,
|
||||
) : ConeCallConflictResolver() {
|
||||
|
||||
private val samResolver: FirSamResolver get() = transformerComponents.samResolver
|
||||
@@ -188,19 +190,36 @@ abstract class AbstractConeCallConflictResolver(
|
||||
} else {
|
||||
called.contextReceivers.mapTo(this) { TypeWithConversion(it.typeRef.coneType.fullyExpandedType(session)) }
|
||||
call.argumentMapping?.mapTo(this) { (_, parameter) ->
|
||||
val argumentType = parameter.argumentType().fullyExpandedType(session)
|
||||
if (!call.usesSAM) {
|
||||
TypeWithConversion(argumentType)
|
||||
} else {
|
||||
val functionType = samResolver.getFunctionTypeForPossibleSamType(argumentType)
|
||||
if (functionType == null) TypeWithConversion(argumentType)
|
||||
else TypeWithConversion(functionType, argumentType)
|
||||
parameter.toTypeWithConversion(session, call)
|
||||
}
|
||||
|
||||
if (considerMissingArgumentsInSignatures) {
|
||||
// When we create signatures for unsuccessful candidates, some parameters might be missing an argument.
|
||||
// When necessary, we consider those too.
|
||||
// fun foo(a: String, b: Int)
|
||||
// fun foo(a: String, c: Boolean)
|
||||
// foo(a)
|
||||
// Here, no argument is passed for the parameters b and c, but the signatures will be different.
|
||||
call.diagnostics.mapNotNullTo(this) {
|
||||
if (it !is NoValueForParameter) return@mapNotNullTo null
|
||||
it.valueParameter.toTypeWithConversion(session, call)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirValueParameter.toTypeWithConversion(session: FirSession, call: Candidate): TypeWithConversion {
|
||||
val argumentType = argumentType().fullyExpandedType(session)
|
||||
return if (!call.usesSAM) {
|
||||
TypeWithConversion(argumentType)
|
||||
} else {
|
||||
val functionType = samResolver.getFunctionTypeForPossibleSamType(argumentType)
|
||||
if (functionType == null) TypeWithConversion(argumentType)
|
||||
else TypeWithConversion(functionType, argumentType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun createFlatSignature(call: Candidate, klass: FirClassLikeDeclaration): FlatSignature<Candidate> {
|
||||
return FlatSignature(
|
||||
call,
|
||||
|
||||
+7
-1
@@ -34,7 +34,13 @@ open class CandidateCollector(
|
||||
val applicability = resolutionStageRunner.processCandidate(candidate, context)
|
||||
|
||||
if (applicability > currentApplicability || (applicability == currentApplicability && group < bestGroup)) {
|
||||
candidates.clear()
|
||||
// Only throw away previous candidates if the new one is successful. If we don't find a successful candidate, we keep all
|
||||
// unsuccessful ones so that we can run all stages and pick the one with the least bad applicability.
|
||||
// See FirCallResolver.reduceCandidates.
|
||||
if (applicability >= CandidateApplicability.RESOLVED_LOW_PRIORITY) {
|
||||
candidates.clear()
|
||||
}
|
||||
|
||||
currentApplicability = applicability
|
||||
bestGroup = group
|
||||
}
|
||||
|
||||
+8
-3
@@ -31,12 +31,17 @@ typealias CandidateSignature = FlatSignature<Candidate>
|
||||
class ConeOverloadConflictResolver(
|
||||
specificityComparator: TypeSpecificityComparator,
|
||||
inferenceComponents: InferenceComponents,
|
||||
transformerComponents: BodyResolveComponents
|
||||
) : AbstractConeCallConflictResolver(specificityComparator, inferenceComponents, transformerComponents) {
|
||||
transformerComponents: BodyResolveComponents,
|
||||
) : AbstractConeCallConflictResolver(
|
||||
specificityComparator,
|
||||
inferenceComponents,
|
||||
transformerComponents,
|
||||
considerMissingArgumentsInSignatures = false,
|
||||
) {
|
||||
|
||||
override fun chooseMaximallySpecificCandidates(
|
||||
candidates: Set<Candidate>,
|
||||
discriminateAbstracts: Boolean
|
||||
discriminateAbstracts: Boolean,
|
||||
): Set<Candidate> = chooseMaximallySpecificCandidates(candidates, discriminateAbstracts, discriminateGenerics = true)
|
||||
|
||||
private fun chooseMaximallySpecificCandidates(
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// ISSUE: KT-58421
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// MODULE: lib
|
||||
// FILE: ContinuationImpl.kt
|
||||
|
||||
internal abstract class ContinuationImpl() {
|
||||
constructor(arg: Int) : this()
|
||||
}
|
||||
|
||||
// MODULE: main(lib)
|
||||
// FILE: box.kt
|
||||
|
||||
@Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE", "NONE_APPLICABLE")
|
||||
internal class SafeCollector: ContinuationImpl()
|
||||
|
||||
fun box() = "OK"
|
||||
@@ -1,5 +1,5 @@
|
||||
object A1<!CONSTRUCTOR_IN_OBJECT!>()<!> {
|
||||
<!CONSTRUCTOR_IN_OBJECT!>constructor(x: Int = "", y: Int)<!> : <!NONE_APPLICABLE!>this<!>() {
|
||||
<!CONSTRUCTOR_IN_OBJECT!>constructor(x: Int = "", y: Int)<!> : <!UNRESOLVED_REFERENCE!>this<!>() {
|
||||
x + y
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,6 +11,6 @@ fun test() {
|
||||
<!NONE_APPLICABLE!>foo<!>(1, 2)
|
||||
foo(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||
|
||||
<!NONE_APPLICABLE!>bar<!>(1, 2)
|
||||
bar(1, <!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
<!NONE_APPLICABLE!>bar<!>()
|
||||
}
|
||||
|
||||
Vendored
+2
-2
@@ -94,7 +94,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (x == null) {
|
||||
x<!UNSAFE_CALL!>.<!>toString("")
|
||||
x.<!NONE_APPLICABLE!>toString<!>("")
|
||||
}
|
||||
|
||||
""
|
||||
@@ -134,7 +134,7 @@ fun test() {
|
||||
emit(null)
|
||||
val x = get()
|
||||
if (<!FORBIDDEN_IDENTITY_EQUALS_WARNING!>x === null<!>) {
|
||||
x<!UNSAFE_CALL!>.<!>toString("")
|
||||
x.<!NONE_APPLICABLE!>toString<!>("")
|
||||
}
|
||||
|
||||
""
|
||||
|
||||
+1
-1
@@ -13,6 +13,6 @@ fun <T: Any> joinT(x: Comparable<*>, y: T): T? {
|
||||
}
|
||||
|
||||
fun test() {
|
||||
val x2 = <!NONE_APPLICABLE!>joinT<!>(Unit, "2")
|
||||
val x2 = joinT(<!ARGUMENT_TYPE_MISMATCH!>Unit<!>, "2")
|
||||
checkSubtype<String?>(x2)
|
||||
}
|
||||
|
||||
+5
-5
@@ -274,8 +274,8 @@ fun poll76() {
|
||||
}
|
||||
|
||||
fun poll8() {
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar<!> <!NONE_APPLICABLE!>in<!> <!NONE_APPLICABLE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo<!>)
|
||||
<!NO_VALUE_FOR_PARAMETER!>inv()<!>
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar<!> <!INAPPLICABLE_CANDIDATE!>in<!> <!INAPPLICABLE_CANDIDATE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo<!>)
|
||||
<!UNRESOLVED_REFERENCE!>inv<!>()
|
||||
}
|
||||
|
||||
fun poll81() {
|
||||
@@ -284,8 +284,8 @@ fun poll81() {
|
||||
}
|
||||
|
||||
fun poll82() {
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar3<!> <!NONE_APPLICABLE!>in<!> <!NONE_APPLICABLE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo3<!>)
|
||||
<!NO_VALUE_FOR_PARAMETER!>inv()<!>
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar3<!> <!INAPPLICABLE_CANDIDATE!>in<!> <!INAPPLICABLE_CANDIDATE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo3<!>)
|
||||
<!UNRESOLVED_REFERENCE!>inv<!>()
|
||||
}
|
||||
|
||||
fun poll83() {
|
||||
@@ -294,7 +294,7 @@ fun poll83() {
|
||||
}
|
||||
|
||||
fun poll84() {
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar5<!> <!NONE_APPLICABLE!>in<!> <!NONE_APPLICABLE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo5<!>)
|
||||
val inv = ::<!UNRESOLVED_REFERENCE!>bar5<!> <!INAPPLICABLE_CANDIDATE!>in<!> <!INAPPLICABLE_CANDIDATE!>setOf<!>(::<!UNRESOLVED_REFERENCE!>foo5<!>)
|
||||
inv
|
||||
}
|
||||
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
fun f(s: String, t: String) = s + t
|
||||
|
||||
// MODULE: m2
|
||||
// FILE: b.kt
|
||||
package p
|
||||
|
||||
fun f(s: String, t: String) = t + s
|
||||
|
||||
// MODULE: m3(m1, m2)
|
||||
// FILE: c.kt
|
||||
import p.f
|
||||
|
||||
fun test() {
|
||||
// There should be no "none applicable" error here
|
||||
<!NONE_APPLICABLE!>f<!>(
|
||||
<!SYNTAX!><!>}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
package p
|
||||
|
||||
+1
-1
@@ -5,5 +5,5 @@ fun <T : Bar, T1> foo(x : Int) {}
|
||||
fun <T1, T : Foo> foo(x : Long) {}
|
||||
|
||||
fun f(): Unit {
|
||||
<!NONE_APPLICABLE!>foo<!><Int, Int>(1)
|
||||
foo<<!UPPER_BOUND_VIOLATED!>Int<!>, Int>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// SKIP_TXT
|
||||
|
||||
// FILE: MyJClass.java
|
||||
|
||||
public class MyJClass {
|
||||
public void meth(int pathname) {}
|
||||
private void meth(String pathname, int prefixLength) {}
|
||||
private void meth(String child, boolean b) {}
|
||||
}
|
||||
|
||||
// FILE: MyJClass2.java
|
||||
|
||||
public class MyJClass2 {
|
||||
public void meth(int pathname) {}
|
||||
public void meth(String pathname, int prefixLength) {}
|
||||
private void meth(String child, boolean b) {}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun test1(myJClass: MyJClass) {
|
||||
myJClass.meth(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||
}
|
||||
|
||||
fun test2(myJClass: MyJClass2) {
|
||||
myJClass.meth(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// SKIP_TXT
|
||||
|
||||
// FILE: MyJClass.java
|
||||
|
||||
public class MyJClass {
|
||||
public void meth(int pathname) {}
|
||||
private void meth(String pathname, int prefixLength) {}
|
||||
private void meth(String child, boolean b) {}
|
||||
}
|
||||
|
||||
// FILE: MyJClass2.java
|
||||
|
||||
public class MyJClass2 {
|
||||
public void meth(int pathname) {}
|
||||
public void meth(String pathname, int prefixLength) {}
|
||||
private void meth(String child, boolean b) {}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun test1(myJClass: MyJClass) {
|
||||
myJClass.meth(<!TYPE_MISMATCH!>""<!>)
|
||||
}
|
||||
|
||||
fun test2(myJClass: MyJClass2) {
|
||||
myJClass.meth(<!TYPE_MISMATCH!>""<!>)
|
||||
}
|
||||
Vendored
+1
-1
@@ -7,7 +7,7 @@ class SomeClass
|
||||
|
||||
fun test(identifier: SomeClass, fn: String.() -> Unit) {
|
||||
<!NONE_APPLICABLE!>identifier<!>()
|
||||
identifier(<!NO_VALUE_FOR_PARAMETER!>123)<!>
|
||||
<!NONE_APPLICABLE!>identifier<!>(123)
|
||||
identifier(1, <!TOO_MANY_ARGUMENTS!>2<!>)
|
||||
<!ARGUMENT_TYPE_MISMATCH!>1<!>.fn()
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -8,6 +8,6 @@ fun overloadedFun(arg: String, vararg args: String) = X1
|
||||
fun overloadedFun(arg: String, vararg args: String, flag: Boolean = true) = X2
|
||||
|
||||
val test1a: X1 = overloadedFun("", "")
|
||||
val test1b: X1 = <!NONE_APPLICABLE!>overloadedFun<!>("", args = "")
|
||||
val test1b: X1 = overloadedFun("", args = <!ARGUMENT_TYPE_MISMATCH, ASSIGNING_SINGLE_ELEMENT_TO_VARARG_IN_NAMED_FORM_FUNCTION_ERROR!>""<!>)
|
||||
val test1c: X2 = overloadedFun("", "", "", flag = true)
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ val y2: B<Int> = B("")
|
||||
val y3: B<Int> = B<Int>(1)
|
||||
val y4: B<Int> = B<Int>("")
|
||||
|
||||
val y5: B<String> = <!NONE_APPLICABLE!>B<!><String>(1)
|
||||
val y5: B<String> = B<String>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||
val y6: B<String> = B<String>("")
|
||||
val y7: B<String> = <!TYPE_MISMATCH, TYPE_MISMATCH!>B(1)<!>
|
||||
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: Int): <!NONE_APPLICABLE!>this<!>(x, "")
|
||||
constructor(x: T1, y: Int): this(x, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
|
||||
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(<!ARGUMENT_TYPE_MISMATCH!>y<!>, <!ARGUMENT_TYPE_MISMATCH!>x<!>)
|
||||
}
|
||||
|
||||
class A1<T1, T2> : B<T1, T2> {
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ fun bar(arg: Long?): Long {
|
||||
return i<!UNSAFE_CALL!>--<!> <!UNSAFE_OPERATOR_CALL!>+<!> i
|
||||
}
|
||||
if (i++ == 7L) {
|
||||
return i++ <!UNSAFE_OPERATOR_CALL!>+<!> i
|
||||
return i++ <!NONE_APPLICABLE!>+<!> i
|
||||
}
|
||||
return 0L
|
||||
}
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ fun testLong(@ImplicitIntegerCoercion x: ULong) = x
|
||||
|
||||
fun box(): String = when {
|
||||
test(5) != 5.toUInt() -> "Fail: test(5)"
|
||||
<!NONE_APPLICABLE!>test<!>(5L) != 5L.toULong() -> "Fail: test(5L)"
|
||||
<!EQUALITY_NOT_APPLICABLE!>test(<!ARGUMENT_TYPE_MISMATCH!>5L<!>) != 5L.toULong()<!> -> "Fail: test(5L)"
|
||||
testLong(5) != 5L.toULong() -> "Fail: test(5L)"
|
||||
testLong(<!ARGUMENT_TYPE_MISMATCH!>5L<!>) != 5L.toULong() -> "Fail: test(5L)"
|
||||
else -> "OK"
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ fun foo() {
|
||||
<!NEW_INFERENCE_ERROR!>select(1, 1u)<!> checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><Comparable<*>>() }
|
||||
takeUByte(<!ARGUMENT_TYPE_MISMATCH!>id(1)<!>)
|
||||
|
||||
1 <!NONE_APPLICABLE!>+<!> 1u
|
||||
(1u <!NONE_APPLICABLE!>+<!> 1) <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>checkType<!> { _<UInt>() }
|
||||
1 + <!ARGUMENT_TYPE_MISMATCH!>1u<!>
|
||||
(1u + <!ARGUMENT_TYPE_MISMATCH!>1<!>) checkType { _<UInt>() }
|
||||
|
||||
id<UInt>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
|
||||
}
|
||||
|
||||
+2
-2
@@ -9,6 +9,6 @@ fun test() {
|
||||
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>fUShort<!>()
|
||||
1.<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>fULong<!>()
|
||||
|
||||
3000000000 <!NONE_APPLICABLE!>until<!> 3000000004UL
|
||||
0 <!NONE_APPLICABLE!>until<!> 10u
|
||||
3000000000 until <!ARGUMENT_TYPE_MISMATCH!>3000000004UL<!>
|
||||
0 until <!ARGUMENT_TYPE_MISMATCH!>10u<!>
|
||||
}
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ fun test() {
|
||||
foo(1) checkType { _<Int>() }
|
||||
foo(1u) checkType { _<String>() }
|
||||
|
||||
<!NONE_APPLICABLE!>foo<!>(2147483648) <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>checkType<!> { _<String>() }
|
||||
foo(<!ARGUMENT_TYPE_MISMATCH!>2147483648<!>) checkType { <!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>_<!><String>() }
|
||||
foo(2147483647 + 1) checkType { _<Int>() }
|
||||
|
||||
fooByte(1) checkType { _<Int>() }
|
||||
|
||||
Generated
+6
@@ -27376,6 +27376,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/CycleInTypeArgs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorPriority.kt")
|
||||
public void testErrorPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/errorPriority.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("HiddenDeclarations.kt")
|
||||
public void testHiddenDeclarations() throws Exception {
|
||||
|
||||
+6
@@ -47534,6 +47534,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testSuppressInvisible() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suppressInvisibleCtor.kt")
|
||||
public void testSuppressInvisibleCtor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisibleCtor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -50156,6 +50156,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
public void testSuppressInvisible() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suppressInvisibleCtor.kt")
|
||||
public void testSuppressInvisibleCtor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisibleCtor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+6
@@ -50156,6 +50156,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
||||
public void testSuppressInvisible() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisible.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("suppressInvisibleCtor.kt")
|
||||
public void testSuppressInvisibleCtor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisibleCtor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+5
@@ -38575,6 +38575,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
public void testSuppressInvisible() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisible.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suppressInvisibleCtor.kt")
|
||||
public void testSuppressInvisibleCtor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/suppressions/suppressInvisibleCtor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/suspendConversion")
|
||||
|
||||
+2
-2
@@ -26,7 +26,7 @@ import checkSubtype
|
||||
fun case1() {
|
||||
val a: Any = true
|
||||
if (<!CONDITION_TYPE_MISMATCH!>a<!>) { "true" } else "false"
|
||||
<!NONE_APPLICABLE!>checkSubtype<!><Boolean>(a)
|
||||
checkSubtype<Boolean>(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -37,7 +37,7 @@ fun case1() {
|
||||
fun case2() {
|
||||
val a = JavaContainer.aO
|
||||
if (<!CONDITION_TYPE_MISMATCH!>a<!>) { "true" } else "false"
|
||||
<!NONE_APPLICABLE!>checkSubtype<!><Boolean>(a)
|
||||
checkSubtype<Boolean>(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
||||
}
|
||||
|
||||
// TESTCASE NUMBER: 3
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ class Case1() {
|
||||
}
|
||||
|
||||
fun case() {
|
||||
<!NONE_APPLICABLE!>Companion<!>(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>x<!>)
|
||||
<!INAPPLICABLE_CANDIDATE!>Companion<!>(::<!UNRESOLVED_REFERENCE!>x<!>)
|
||||
}
|
||||
|
||||
val x = ""
|
||||
@@ -26,7 +26,7 @@ class Case2() {
|
||||
}
|
||||
|
||||
fun case() {
|
||||
<!NONE_APPLICABLE!>Companion<!>(::<!OVERLOAD_RESOLUTION_AMBIGUITY!>x<!>)
|
||||
<!INAPPLICABLE_CANDIDATE!>Companion<!>(::<!UNRESOLVED_REFERENCE!>x<!>)
|
||||
}
|
||||
|
||||
val x = C()
|
||||
|
||||
@@ -13,7 +13,7 @@ fun case_1(x: Class?) {
|
||||
fun case_2() {
|
||||
var x: Class? = <!INITIALIZER_TYPE_MISMATCH!>10<!>
|
||||
x!!
|
||||
<!UNSAFE_IMPLICIT_INVOKE_CALL!>x<!>(if (true) {x=null;0} else 0, <!DEBUG_INFO_EXPRESSION_TYPE("Class?")!>x<!>)
|
||||
x(if (true) {x=null;0} else 0, <!ARGUMENT_TYPE_MISMATCH, DEBUG_INFO_EXPRESSION_TYPE("Class?")!>x<!>)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Class?")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Class?")!>x<!><!UNSAFE_CALL!>.<!>fun_1()
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ fun case_4() {
|
||||
fun case_5() {
|
||||
var x: Class? = Class()
|
||||
x!!
|
||||
<!UNSAFE_IMPLICIT_INVOKE_CALL!>x<!>(if (true) {x=null;0} else 0, <!DEBUG_INFO_EXPRESSION_TYPE("Class?")!>x<!>)
|
||||
x(if (true) {x=null;0} else 0, <!ARGUMENT_TYPE_MISMATCH, DEBUG_INFO_EXPRESSION_TYPE("Class?")!>x<!>)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Class?")!>x<!><!UNSAFE_CALL!>.<!>fun_1()
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ fun case_1(x: Double?, y: Double?) : Double {
|
||||
} else if (x == null && y != null) {
|
||||
y
|
||||
} else {
|
||||
x <!UNSAFE_OPERATOR_CALL!>+<!> y
|
||||
x <!NONE_APPLICABLE!>+<!> y
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ class Case1<T : Number> {
|
||||
inline fun <reified T : CharSequence>case_1(x: Any?) {
|
||||
if (x is T) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & T")!>x<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & T")!>x<!>.<!NO_VALUE_FOR_PARAMETER!>toByte()<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Any? & T")!>x<!>.<!NONE_APPLICABLE!>toByte<!>()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user