[NI] Don't apply SAM-conversion for type that is subtype of function
Plus, don't get synthetic candidates as all candidates are creating by conversion #KT-31503 Fixed
This commit is contained in:
+5
@@ -12383,6 +12383,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/privateCandidatesWithWrongArguments.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/privateCandidatesWithWrongArguments.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("recursiveSamsAndInvoke.kt")
|
||||||
|
public void testRecursiveSamsAndInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/recursiveSamsAndInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("samOnTypeParameter.kt")
|
@TestMetadata("samOnTypeParameter.kt")
|
||||||
public void testSamOnTypeParameter() throws Exception {
|
public void testSamOnTypeParameter() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/samOnTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/samOnTypeParameter.kt");
|
||||||
|
|||||||
+1
-2
@@ -60,8 +60,7 @@ class SamAdapterFunctionsScope(
|
|||||||
private val deprecationResolver: DeprecationResolver,
|
private val deprecationResolver: DeprecationResolver,
|
||||||
private val lookupTracker: LookupTracker
|
private val lookupTracker: LookupTracker
|
||||||
) : SyntheticScope.Default() {
|
) : SyntheticScope.Default() {
|
||||||
private val samViaSyntheticScopeDisabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference) &&
|
private val samViaSyntheticScopeDisabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
|
||||||
languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)
|
|
||||||
|
|
||||||
private val extensionForFunction =
|
private val extensionForFunction =
|
||||||
storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
|
storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
|
||||||
|
|||||||
+2
-8
@@ -5,9 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.components
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
|
|
||||||
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||||
|
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
||||||
@@ -27,7 +26,6 @@ import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
|||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import org.jetbrains.kotlin.types.checker.anySuperTypeConstructor
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -300,7 +298,7 @@ private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
|
|||||||
if (!callComponents.samConversionTransformer.shouldRunSamConversionForFunction(resolvedCall.candidateDescriptor)) return null
|
if (!callComponents.samConversionTransformer.shouldRunSamConversionForFunction(resolvedCall.candidateDescriptor)) return null
|
||||||
|
|
||||||
val argumentIsFunctional = when (argument) {
|
val argumentIsFunctional = when (argument) {
|
||||||
is SimpleKotlinCallArgument -> argument.receiver.stableType.isSubtypeOfFunctionType()
|
is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType
|
||||||
is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true
|
is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
@@ -324,10 +322,6 @@ private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
|
|||||||
return convertedTypeByCandidate
|
return convertedTypeByCandidate
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun UnwrappedType.isSubtypeOfFunctionType() = anySuperTypeConstructor {
|
|
||||||
it.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.Function
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object CheckReceivers : ResolutionPart() {
|
internal object CheckReceivers : ResolutionPart() {
|
||||||
private fun KotlinResolutionCandidate.checkReceiver(
|
private fun KotlinResolutionCandidate.checkReceiver(
|
||||||
receiverArgument: SimpleKotlinCallArgument?,
|
receiverArgument: SimpleKotlinCallArgument?,
|
||||||
|
|||||||
+2
-2
@@ -16,14 +16,14 @@ fun <T> bar(s: T) {}
|
|||||||
fun <T> complex(t: T, f: (T) -> Unit) {}
|
fun <T> complex(t: T, f: (T) -> Unit) {}
|
||||||
|
|
||||||
fun test1() {
|
fun test1() {
|
||||||
foo(1, A::invokeLater) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE
|
foo(1, <!NI;TYPE_MISMATCH!>A::invokeLater<!>) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE
|
||||||
foo(1, ::bar)
|
foo(1, ::bar)
|
||||||
|
|
||||||
complex(1, ::bar)
|
complex(1, ::bar)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <R> test2(x: R) {
|
fun <R> test2(x: R) {
|
||||||
foo(x, A::invokeLater) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE
|
foo(x, <!NI;TYPE_MISMATCH!>A::invokeLater<!>) // KT-24507 SAM conversion accidentally applied to callable reference and incorrectly handled via BE
|
||||||
foo(x, ::bar)
|
foo(x, ::bar)
|
||||||
|
|
||||||
complex(x, ::bar)
|
complex(x, ::bar)
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// FILE: MyFuture.java
|
||||||
|
|
||||||
|
public interface MyFuture<V> {
|
||||||
|
MyFuture<V> addListener(MyListener<? extends MyFuture<? super V>> listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: MyListener.java
|
||||||
|
|
||||||
|
public interface MyListener<F extends MyFuture<?>> {
|
||||||
|
void operationComplete(F future) throws Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
typealias Handler = (cause: Throwable?) -> Unit
|
||||||
|
|
||||||
|
fun <T> MyFuture<T>.setup() {
|
||||||
|
addListener(ListenerImpl<T, MyFuture<T>>())
|
||||||
|
addListener { }
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListenerImpl<T, F : MyFuture<T>> : MyListener<F>, Handler {
|
||||||
|
override fun operationComplete(future: F) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun invoke(cause: Throwable?) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun </*0*/ T> MyFuture<T>.setup(): kotlin.Unit
|
||||||
|
|
||||||
|
public final class ListenerImpl</*0*/ T, /*1*/ F : MyFuture<T>> : MyListener<F>, Handler /* = (cause: kotlin.Throwable?) -> kotlin.Unit */ {
|
||||||
|
public constructor ListenerImpl</*0*/ T, /*1*/ F : MyFuture<T>>()
|
||||||
|
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ fun invoke(/*0*/ cause: kotlin.Throwable?): kotlin.Unit
|
||||||
|
public open override /*1*/ fun operationComplete(/*0*/ future: F): kotlin.Unit
|
||||||
|
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface MyFuture</*0*/ V : kotlin.Any!> {
|
||||||
|
public abstract fun addListener(/*0*/ listener: MyListener<out MyFuture<in V!>!>!): MyFuture<V!>!
|
||||||
|
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 MyListener</*0*/ F : MyFuture<*>!> {
|
||||||
|
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 abstract fun operationComplete(/*0*/ future: F!): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
public typealias Handler = (cause: kotlin.Throwable?) -> kotlin.Unit
|
||||||
+1
-1
@@ -21,7 +21,7 @@ class B : A() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (d.x is B) {
|
if (d.x is B) {
|
||||||
<!SMARTCAST_IMPOSSIBLE!>d.x<!>.<!NI;INVISIBLE_MEMBER!>foo<!> {}
|
<!OI;SMARTCAST_IMPOSSIBLE!>d.x<!>.<!NI;INVISIBLE_MEMBER!>foo<!> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12390,6 +12390,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/privateCandidatesWithWrongArguments.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/privateCandidatesWithWrongArguments.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("recursiveSamsAndInvoke.kt")
|
||||||
|
public void testRecursiveSamsAndInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/recursiveSamsAndInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("samOnTypeParameter.kt")
|
@TestMetadata("samOnTypeParameter.kt")
|
||||||
public void testSamOnTypeParameter() throws Exception {
|
public void testSamOnTypeParameter() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/samOnTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/samOnTypeParameter.kt");
|
||||||
|
|||||||
Generated
+5
@@ -12385,6 +12385,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/privateCandidatesWithWrongArguments.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/privateCandidatesWithWrongArguments.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("recursiveSamsAndInvoke.kt")
|
||||||
|
public void testRecursiveSamsAndInvoke() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/recursiveSamsAndInvoke.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("samOnTypeParameter.kt")
|
@TestMetadata("samOnTypeParameter.kt")
|
||||||
public void testSamOnTypeParameter() throws Exception {
|
public void testSamOnTypeParameter() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/samOnTypeParameter.kt");
|
runTest("compiler/testData/diagnostics/tests/j+k/sam/samOnTypeParameter.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user