[NI] Fix checking for inline lambdas without candidate
#KT-34506
This commit is contained in:
+5
@@ -1839,6 +1839,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
public void testResolutionInOldInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/resolutionInOldInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnFromInlineLambda.kt")
|
||||
public void testReturnFromInlineLambda() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/returnFromInlineLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop")
|
||||
|
||||
@@ -274,6 +274,7 @@ public interface BindingContext {
|
||||
WritableSlice<KtExpression, PrimitiveNumericComparisonInfo> PRIMITIVE_NUMERIC_COMPARISON_INFO = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<KtExpression, Ref<VariableDescriptor>> NEW_INFERENCE_CATCH_EXCEPTION_PARAMETER = Slices.createSimpleSlice();
|
||||
WritableSlice<PsiElement, Boolean> NEW_INFERENCE_IS_LAMBDA_FOR_OVERLOAD_RESOLUTION_INLINE = Slices.createSimpleSlice();
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
@Deprecated // This field is needed only for the side effects of its initializer
|
||||
|
||||
+13
-7
@@ -8,19 +8,14 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveTypeOrNullablePrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.isUnderKotlinPackage
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.builtins.createFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.KtReturnExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getBinaryWithTypeParent
|
||||
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
@@ -40,6 +35,7 @@ import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
|
||||
@@ -48,7 +44,6 @@ import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
|
||||
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
data class LambdaContextInfo(
|
||||
@@ -317,6 +312,17 @@ class KotlinResolutionCallbacksImpl(
|
||||
return convertSignedConstantToUnsigned(argumentExpression)
|
||||
}
|
||||
|
||||
override fun recordInlinabilityOfLambda(lambdas: Set<Map.Entry<KotlinResolutionCandidate, ResolvedLambdaAtom>>) {
|
||||
val call = lambdas.first().value.atom.psiCallArgument.valueArgument as? KtLambdaArgument ?: return
|
||||
val literal = call.getLambdaExpression()?.functionLiteral ?: return
|
||||
val isLambdaInline = lambdas.all { (candidate, atom) ->
|
||||
if (!InlineUtil.isInline(candidate.resolvedCall.candidateDescriptor)) return
|
||||
val valueParameterDescriptor = candidate.resolvedCall.argumentToCandidateParameter[atom.atom] ?: return
|
||||
InlineUtil.isInlineParameter(valueParameterDescriptor)
|
||||
}.takeIf { it }
|
||||
trace.record(BindingContext.NEW_INFERENCE_IS_LAMBDA_FOR_OVERLOAD_RESOLUTION_INLINE, literal, isLambdaInline)
|
||||
}
|
||||
|
||||
private fun convertSignedConstantToUnsigned(expression: KtExpression): IntegerValueTypeConstant? {
|
||||
val constant = trace[BindingContext.COMPILE_TIME_VALUE, expression]
|
||||
if (constant !is IntegerValueTypeConstant || !constantCanBeConvertedToUnsigned(constant)) return null
|
||||
|
||||
@@ -99,6 +99,11 @@ public class InlineUtil {
|
||||
if (containingFunctionDescriptor == null) return false;
|
||||
|
||||
while (canBeInlineArgument(containingFunction) && fromFunction != containingFunctionDescriptor) {
|
||||
Boolean isLambdaDefinitelyInline = bindingContext.get(BindingContext.NEW_INFERENCE_IS_LAMBDA_FOR_OVERLOAD_RESOLUTION_INLINE, containingFunction);
|
||||
if (isLambdaDefinitelyInline != null) {
|
||||
return isLambdaDefinitelyInline;
|
||||
}
|
||||
|
||||
if (!isInlinedArgument((KtFunction) containingFunction, bindingContext, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+2
-4
@@ -6,11 +6,8 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.container.DefaultImplementation
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -20,7 +17,6 @@ import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.StubType
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
|
||||
@@ -85,4 +81,6 @@ interface KotlinResolutionCallbacks {
|
||||
fun disableContractsIfNecessary(resolvedAtom: ResolvedCallAtom)
|
||||
|
||||
fun convertSignedConstantToUnsigned(argument: KotlinCallArgument): IntegerValueTypeConstant?
|
||||
|
||||
fun recordInlinabilityOfLambda(atom: Set<Map.Entry<KotlinResolutionCandidate, ResolvedLambdaAtom>>)
|
||||
}
|
||||
|
||||
+3
-2
@@ -16,8 +16,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintS
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.TrivialConstraintTypeInferenceOracle
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage.Empty.hasContradiction
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.LambdaArgumentConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.forceResolution
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
@@ -113,6 +111,9 @@ class KotlinCallCompleter(
|
||||
val diagnosticHolderForLambda = KotlinDiagnosticsHolder.SimpleHolder()
|
||||
val iterator = newAtoms.entries.iterator()
|
||||
val (firstCandidate, firstAtom) = iterator.next()
|
||||
|
||||
resolutionCallbacks.recordInlinabilityOfLambda(lambdas.entries)
|
||||
|
||||
val results = postponedArgumentsAnalyzer.analyzeLambda(
|
||||
firstCandidate.getSystem().asPostponedArgumentsAnalyzerContext(),
|
||||
resolutionCallbacks,
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// !LANGUAGE: +NewInference +OverloadResolutionByLambdaReturnType
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS
|
||||
// ISSUE: KT-11265
|
||||
|
||||
// FILE: OverloadResolutionByLambdaReturnType.kt
|
||||
|
||||
package kotlin
|
||||
|
||||
annotation class OverloadResolutionByLambdaReturnType
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
import kotlin.OverloadResolutionByLambdaReturnType
|
||||
|
||||
inline fun <T, R> Array<out T>.myFlatMap(transform: (T) -> Iterable<R>): List<R> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
@OverloadResolutionByLambdaReturnType
|
||||
@JvmName("seqFlatMap")
|
||||
inline fun <T, R> Array<out T>.myFlatMap(transform: (T) -> Sequence<R>): List<R> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun String.toList(): List<String> = null!!
|
||||
|
||||
fun test_1(a: Array<String>, b: Boolean) {
|
||||
a.<!AMBIGUITY!>myFlatMap<!> { <!UNRESOLVED_REFERENCE!>it<!>.toList().ifEmpty { return } }
|
||||
a.<!AMBIGUITY!>myFlatMap<!> {
|
||||
if (b) return
|
||||
<!UNRESOLVED_REFERENCE!>it<!>.toList()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> Array<out T>.noInlineFlatMap(transform: (T) -> Iterable<R>): List<R> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
@OverloadResolutionByLambdaReturnType
|
||||
@JvmName("noInlineSeqFlatMap")
|
||||
fun <T, R> Array<out T>.noInlineFlatMap(transform: (T) -> Sequence<R>): List<R> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun test_2(a: Array<String>, b: Boolean) {
|
||||
a.<!AMBIGUITY!>noInlineFlatMap<!> { <!UNRESOLVED_REFERENCE!>it<!>.toList().ifEmpty { return } }
|
||||
a.<!AMBIGUITY!>noInlineFlatMap<!> {
|
||||
if (b) return
|
||||
<!UNRESOLVED_REFERENCE!>it<!>.toList()
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
// !LANGUAGE: +NewInference +OverloadResolutionByLambdaReturnType
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_EXPRESSION -EXPERIMENTAL_API_USAGE -EXPERIMENTAL_UNSIGNED_LITERALS
|
||||
// ISSUE: KT-11265
|
||||
|
||||
// FILE: OverloadResolutionByLambdaReturnType.kt
|
||||
|
||||
package kotlin
|
||||
|
||||
annotation class OverloadResolutionByLambdaReturnType
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
import kotlin.OverloadResolutionByLambdaReturnType
|
||||
|
||||
inline fun <T, R> Array<out T>.myFlatMap(transform: (T) -> Iterable<R>): List<R> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
@OverloadResolutionByLambdaReturnType
|
||||
@JvmName("seqFlatMap")
|
||||
inline fun <T, R> Array<out T>.myFlatMap(transform: (T) -> Sequence<R>): List<R> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun String.toList(): List<String> = null!!
|
||||
|
||||
fun test_1(a: Array<String>, b: Boolean) {
|
||||
a.myFlatMap { it.toList().ifEmpty { return } }
|
||||
a.myFlatMap {
|
||||
if (b) return
|
||||
it.toList()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T, R> Array<out T>.noInlineFlatMap(transform: (T) -> Iterable<R>): List<R> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
@OverloadResolutionByLambdaReturnType
|
||||
@JvmName("noInlineSeqFlatMap")
|
||||
fun <T, R> Array<out T>.noInlineFlatMap(transform: (T) -> Sequence<R>): List<R> {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun test_2(a: Array<String>, b: Boolean) {
|
||||
a.noInlineFlatMap { it.toList().ifEmpty { <!RETURN_NOT_ALLOWED!>return<!> } }
|
||||
a.noInlineFlatMap {
|
||||
if (b) <!RETURN_NOT_ALLOWED!>return<!>
|
||||
it.toList()
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
public fun test_1(/*0*/ a: kotlin.Array<kotlin.String>, /*1*/ b: kotlin.Boolean): kotlin.Unit
|
||||
public fun test_2(/*0*/ a: kotlin.Array<kotlin.String>, /*1*/ b: kotlin.Boolean): kotlin.Unit
|
||||
public inline fun </*0*/ T, /*1*/ R> kotlin.Array<out T>.myFlatMap(/*0*/ transform: (T) -> kotlin.collections.Iterable<R>): kotlin.collections.List<R>
|
||||
@kotlin.OverloadResolutionByLambdaReturnType @kotlin.jvm.JvmName(name = "seqFlatMap") public inline fun </*0*/ T, /*1*/ R> kotlin.Array<out T>.myFlatMap(/*0*/ transform: (T) -> kotlin.sequences.Sequence<R>): kotlin.collections.List<R>
|
||||
public fun </*0*/ T, /*1*/ R> kotlin.Array<out T>.noInlineFlatMap(/*0*/ transform: (T) -> kotlin.collections.Iterable<R>): kotlin.collections.List<R>
|
||||
@kotlin.OverloadResolutionByLambdaReturnType @kotlin.jvm.JvmName(name = "noInlineSeqFlatMap") public fun </*0*/ T, /*1*/ R> kotlin.Array<out T>.noInlineFlatMap(/*0*/ transform: (T) -> kotlin.sequences.Sequence<R>): kotlin.collections.List<R>
|
||||
public fun kotlin.String.toList(): kotlin.collections.List<kotlin.String>
|
||||
|
||||
package kotlin {
|
||||
|
||||
public final annotation class OverloadResolutionByLambdaReturnType : kotlin.Annotation {
|
||||
public constructor OverloadResolutionByLambdaReturnType()
|
||||
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
|
||||
}
|
||||
}
|
||||
+5
@@ -2854,6 +2854,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
||||
public void testResolutionInOldInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/resolutionInOldInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnFromInlineLambda.kt")
|
||||
public void testReturnFromInlineLambda() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/returnFromInlineLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop")
|
||||
|
||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+5
@@ -2854,6 +2854,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
||||
public void testResolutionInOldInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/resolutionInOldInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnFromInlineLambda.kt")
|
||||
public void testReturnFromInlineLambda() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/factoryPattern/returnFromInlineLambda.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/forInArrayLoop")
|
||||
|
||||
Reference in New Issue
Block a user