diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt index 669403009ba..ceb0497ee2b 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -341,6 +341,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") { } val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error() + + val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error { + parameter("name") + } } val AMBIGUITY by object : DiagnosticGroup("Ambiguity") { diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 5f28ae3f37b..a7c7f91816e 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -256,6 +256,7 @@ object FirErrors { val ASSIGNMENT_TYPE_MISMATCH by error2() val RESULT_TYPE_MISMATCH by error2() val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0() + val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1() // Ambiguity val OVERLOAD_RESOLUTION_AMBIGUITY by error1>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt index 7ab0b496a6f..54ca97114f6 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -15,6 +15,8 @@ import org.jetbrains.kotlin.fir.declarations.isOperator import org.jetbrains.kotlin.fir.diagnostics.* import org.jetbrains.kotlin.fir.resolve.calls.* import org.jetbrains.kotlin.fir.resolve.diagnostics.* +import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable +import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeVariableForLambdaReturnType import org.jetbrains.kotlin.fir.resolve.inference.model.ConeArgumentConstraintPosition import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExpectedTypeConstraintPosition import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExplicitTypeParameterConstraintPosition @@ -191,6 +193,7 @@ private fun mapSystemHasContradictionError( qualifiedAccessSource, diagnostic.candidate.callInfo.session.typeContext, errorsToIgnore, + diagnostic.candidate, ) ) } @@ -202,6 +205,7 @@ private fun mapSystemHasContradictionError( is NewConstraintError -> "NewConstraintError at ${it.position}: ${it.lowerType} return@firstNotNullOfOrNull null + is NotEnoughInformationForTypeParameter<*> -> return@firstNotNullOfOrNull null else -> "Inference error: ${it::class.simpleName}" } @@ -223,6 +227,7 @@ private fun ConstraintSystemError.toDiagnostic( qualifiedAccessSource: FirSourceElement?, typeContext: ConeTypeContext, errorsToIgnore: MutableSet, + candidate: Candidate, ): FirDiagnostic? { return when (this) { is NewConstraintError -> { @@ -270,6 +275,25 @@ private fun ConstraintSystemError.toDiagnostic( else -> null } } + is NotEnoughInformationForTypeParameter<*> -> { + val isDiagnosticRedundant = candidate.system.errors.any { otherError -> + (otherError is ConstrainingTypeIsError && otherError.typeVariable == this.typeVariable) + || otherError is NewConstraintError + } + + if (isDiagnosticRedundant) return null + + val typeVariableName = when (val typeVariable = this.typeVariable) { + is ConeTypeParameterBasedTypeVariable -> typeVariable.typeParameterSymbol.name.asString() + is ConeTypeVariableForLambdaReturnType -> "return type of lambda" + else -> error("Unsupported type variable: $typeVariable") + } + + FirErrors.NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER.on( + source, + typeVariableName, + ) + } else -> null } } diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt index aab3d4982a1..69c4f6ab740 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypes.kt @@ -87,7 +87,7 @@ typealias ConeKotlinErrorType = ConeClassErrorType class ConeClassLikeErrorLookupTag(override val classId: ClassId) : ConeClassLikeLookupTag() -class ConeClassErrorType(val diagnostic: ConeDiagnostic) : ConeClassLikeType() { +class ConeClassErrorType(val diagnostic: ConeDiagnostic, val isUninferredParameter: Boolean = false) : ConeClassLikeType() { override val lookupTag: ConeClassLikeLookupTag get() = ConeClassLikeErrorLookupTag(ClassId.fromString("")) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt index 8d9fbcd85d5..15d8cca4445 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConeConstraintSystemUtilContext.kt @@ -99,8 +99,9 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext { argument: PostponedAtomWithRevisableExpectedType, index: Int ): TypeVariableMarker { - return ConeTypeVariableForPostponedAtom( - PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE + index + return ConeTypeVariableForLambdaParameterType( + PostponedArgumentInputTypesResolver.TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE + index, + index ) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt index 4a0d282d8de..1dd104f2cfe 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/ConstraintSystemCompleter.kt @@ -5,6 +5,9 @@ package org.jetbrains.kotlin.fir.resolve.inference +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic +import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents import org.jetbrains.kotlin.fir.resolve.calls.Candidate @@ -15,10 +18,12 @@ import org.jetbrains.kotlin.fir.returnExpressions import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.resolve.calls.inference.components.* import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl +import org.jetbrains.kotlin.resolve.calls.inference.model.NotEnoughInformationForTypeParameter import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints import org.jetbrains.kotlin.resolve.calls.model.PostponedAtomWithRevisableExpectedType import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.TypeConstructorMarker +import org.jetbrains.kotlin.types.model.TypeVariableMarker import org.jetbrains.kotlin.utils.addIfNotNull import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -219,19 +224,83 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) { fixVariable(asConstraintSystemCompletionContext(), topLevelType, variableWithConstraints, postponedArguments) return true } else { -// TODO("Not enough information for parameter") - fixVariable( - asConstraintSystemCompletionContext(), - topLevelType, - variableWithConstraints, - postponedArguments - ) // means Nothing/Any instead of Error type + processVariableWhenNotEnoughInformation(this, variableWithConstraints, topLevelAtoms) } } return false } + private fun processVariableWhenNotEnoughInformation( + c: ConstraintSystemCompletionContext, + variableWithConstraints: VariableWithConstraints, + topLevelAtoms: List, + ) { + val typeVariable = variableWithConstraints.typeVariable + val resolvedAtom = + findResolvedAtomBy(typeVariable, topLevelAtoms) ?: topLevelAtoms.firstOrNull() + + if (resolvedAtom != null) { + c.addError(NotEnoughInformationForTypeParameter(typeVariable, resolvedAtom)) + } + + val resultErrorType = when (typeVariable) { + is ConeTypeParameterBasedTypeVariable -> + createCannotInferErrorType( + "Cannot infer argument for type parameter ${typeVariable.typeParameterSymbol.name}", + isUninferredParameter = true, + ) + is ConeTypeVariableForLambdaParameterType -> createCannotInferErrorType("Cannot infer lambda parameter type") + else -> createCannotInferErrorType("Cannot infer type variable $typeVariable") + } + + c.fixVariable(typeVariable, resultErrorType, ConeFixVariableConstraintPosition(typeVariable)) + } + + private fun createCannotInferErrorType(message: String, isUninferredParameter: Boolean = false) = + ConeClassErrorType( + ConeSimpleDiagnostic( + message, + DiagnosticKind.CannotInferParameterType, + ), + isUninferredParameter, + ) + + private fun findResolvedAtomBy( + typeVariable: TypeVariableMarker, + topLevelAtoms: List + ): FirStatement? { + + fun FirStatement.findFirstAtomContainingVariable(): FirStatement? { + + var result: FirStatement? = null + + fun suggestElement(element: FirElement) { + if (result == null && element is FirStatement) { + result = element + } + } + + this@findFirstAtomContainingVariable.processAllContainingCallCandidates(processBlocks = true) { candidate -> + if (typeVariable in candidate.freshVariables) { + suggestElement(candidate.callInfo.callSite) + } + + for (postponedAtom in candidate.postponedAtoms) { + if (postponedAtom is ResolvedLambdaAtom) { + if (postponedAtom.typeVariableForLambdaReturnType == typeVariable) { + suggestElement(postponedAtom.atom) + } + } + } + } + + return result + } + + return topLevelAtoms.firstNotNullOfOrNull(FirStatement::findFirstAtomContainingVariable) + } + private fun analyzeRemainingNotAnalyzedPostponedArgument( postponedArguments: List, analyze: (PostponedResolvedAtom) -> Unit diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedAtoms.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedAtoms.kt index 88661f56495..24e8c2a69fe 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedAtoms.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedAtoms.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker class ConeTypeVariableForLambdaReturnType(val argument: FirAnonymousFunction, name: String) : ConeTypeVariable(name) class ConeTypeVariableForPostponedAtom(name: String) : ConeTypeVariable(name) +class ConeTypeVariableForLambdaParameterType(name: String, val index: Int) : ConeTypeVariable(name) // -------------------------- Atoms -------------------------- diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt index e7845098e68..f45a4fd5617 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeTypeContext.kt @@ -91,7 +91,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty override fun KotlinTypeMarker.isUninferredParameter(): Boolean { assert(this is ConeKotlinType) - return false // TODO + return this is ConeClassErrorType && this.isUninferredParameter } override fun FlexibleTypeMarker.asDynamicType(): DynamicTypeMarker? { diff --git a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt index 9b37837c67e..fdc93703b50 100644 --- a/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt +++ b/compiler/resolution.common/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt @@ -104,7 +104,7 @@ class CapturedTypeFromSubtyping( val position: ConstraintPosition ) : ConstraintSystemError(INAPPLICABLE) -abstract class NotEnoughInformationForTypeParameter( +open class NotEnoughInformationForTypeParameter( val typeVariable: TypeVariableMarker, val resolvedAtom: T ) : ConstraintSystemError(INAPPLICABLE) diff --git a/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.fir.kt b/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.fir.kt deleted file mode 100644 index 0f70a950cb1..00000000000 --- a/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -fun fooT22() : T? { - return null -} - -fun foo1() { - fooT22() -} - -val n : Nothing = null.sure() - -fun T?.sure() : T = this!! diff --git a/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.kt b/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.kt index 86021c301c0..522939fdaba 100644 --- a/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.kt +++ b/compiler/testData/diagnostics/tests/inference/NoInferenceFromDeclaredBounds.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL fun fooT22() : T? { return null } diff --git a/compiler/testData/diagnostics/tests/inference/noInformationForParameter.fir.kt b/compiler/testData/diagnostics/tests/inference/noInformationForParameter.fir.kt deleted file mode 100644 index 56a1b03283d..00000000000 --- a/compiler/testData/diagnostics/tests/inference/noInformationForParameter.fir.kt +++ /dev/null @@ -1,14 +0,0 @@ -package noInformationForParameter -//+JDK - -import java.util.* - -fun test() { - val n = newList() - - val n1 : List = newList() -} - -fun newList() : ArrayList { - return ArrayList() -} diff --git a/compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt b/compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt index 5044d325e80..0864374b592 100644 --- a/compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt +++ b/compiler/testData/diagnostics/tests/inference/noInformationForParameter.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL package noInformationForParameter //+JDK diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.fir.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.fir.kt deleted file mode 100644 index 9c9d03f21b0..00000000000 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -// !DIAGNOSTICS: -UNREACHABLE_CODE -//KT-2445 Calling method with function with generic parameter causes compile-time exception -package a - -fun main() { - test { - - } -} - -fun test(callback: (R) -> Unit):Unit = callback(null!!) diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt index 94def98c406..ca971fad4a1 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt2445.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNREACHABLE_CODE //KT-2445 Calling method with function with generic parameter causes compile-time exception package a diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt832.fir.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt832.fir.kt deleted file mode 100644 index 51fd6ed2833..00000000000 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt832.fir.kt +++ /dev/null @@ -1,10 +0,0 @@ -//KT-832 Provide better diagnostics when type inference fails for an expression that returns a function -package a - -fun fooT2() : (t : T) -> T { - return {it} -} - -fun test() { - fooT2()(1) // here 1 should not be marked with an error -} diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt832.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt832.kt index 13e57f4df37..dd825d31d07 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt832.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt832.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL //KT-832 Provide better diagnostics when type inference fails for an expression that returns a function package a diff --git a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/cantBeInferred.fir.kt b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/cantBeInferred.fir.kt deleted file mode 100644 index f6f10a935c6..00000000000 --- a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/cantBeInferred.fir.kt +++ /dev/null @@ -1,6 +0,0 @@ -// NI_EXPECTED_FILE -val x get() = foo() -val y get() = bar() - -fun foo(): E = null!! -fun bar(): List = null!! diff --git a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/cantBeInferred.kt b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/cantBeInferred.kt index 612e6cd04b8..2f4790baac0 100644 --- a/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/cantBeInferred.kt +++ b/compiler/testData/diagnostics/tests/properties/inferenceFromGetters/cantBeInferred.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // NI_EXPECTED_FILE val x get() = foo() val y get() = bar() diff --git a/compiler/testData/diagnostics/tests/regressions/kt353.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt353.fir.kt deleted file mode 100644 index 4533391638b..00000000000 --- a/compiler/testData/diagnostics/tests/regressions/kt353.fir.kt +++ /dev/null @@ -1,32 +0,0 @@ -// KT-353 Generic type argument inference sometimes doesn't work - -interface A { - fun gen() : T -} - -fun foo(a: A) { - val g : () -> Unit = { - a.gen() //it works: Unit is derived - } - - val u: Unit = a.gen() // Unit should be inferred - - if (true) { - a.gen() // Shouldn't work: no info for inference - } - - val b : () -> Unit = { - if (true) { - a.gen() // unit can be inferred - } - else { - Unit - } - } - - val f : () -> Int = { - a.gen() //type mismatch, but Int can be derived - } - - a.gen() // Shouldn't work: no info for inference -} diff --git a/compiler/testData/diagnostics/tests/regressions/kt353.kt b/compiler/testData/diagnostics/tests/regressions/kt353.kt index 4ebfe1e457c..4fa3ca523dd 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt353.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt353.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // KT-353 Generic type argument inference sometimes doesn't work interface A { diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.fir.kt deleted file mode 100644 index 68b1292130c..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.fir.kt +++ /dev/null @@ -1,51 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// NI_EXPECTED_FILE - -@file:OptIn(ExperimentalTypeInference::class) - -import kotlin.experimental.ExperimentalTypeInference - -interface Base - -interface Controller : Base { - suspend fun yield(t: T) {} -} - -interface SpecificController : Base { - suspend fun yield(t: T) {} -} - -fun generate(@BuilderInference g: suspend Controller.() -> Unit): S = TODO() -fun generateSpecific(@BuilderInference g: suspend SpecificController.() -> Unit): S = TODO() - -fun Base<*>.starBase() {} -fun Base.stringBase() {} - -val test1 = generate { - starBase() - yield("foo") -} - -val test2 = generate { - starBase() -} - -val test3 = generate { - yield("bar") - stringBase() -} - -val test4 = generateSpecific { - yield(42) - starBase() -} - -val test5 = generateSpecific { - yield(42) - stringBase() -} - -val test6 = generateSpecific { - stringBase() -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.kt index fbc9b73aeab..efb87a0ce27 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraintsGenericBase.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // NI_EXPECTED_FILE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.fir.kt deleted file mode 100644 index 1b8a0640c3d..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.fir.kt +++ /dev/null @@ -1,23 +0,0 @@ -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE -// NI_EXPECTED_FILE - -@file:OptIn(ExperimentalTypeInference::class) - -import kotlin.experimental.ExperimentalTypeInference - -class GenericController { - suspend fun yield(t: T) {} -} - -fun generate(@BuilderInference g: suspend GenericController.() -> Unit): List = TODO() - -@BuilderInference -suspend fun GenericController>.yieldGenerate(g: suspend GenericController.() -> Unit): Unit = TODO() - -val test1 = generate { - // TODO: KT-15185 - yieldGenerate { - yield(4) - } -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.kt index 9aa73a642d8..6931b2002f4 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE // NI_EXPECTED_FILE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.fir.kt deleted file mode 100644 index b58604aa740..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.fir.kt +++ /dev/null @@ -1,12 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_PARAMETER -// NI_EXPECTED_FILE - -class Controller { - suspend fun yield(t: T) {} -} - -fun generate(g: suspend Controller.() -> Unit): S = TODO() - -val test = generate { - yield("foo") -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.kt index 916b60bc8b0..177c78cfdc1 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_PARAMETER // NI_EXPECTED_FILE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/withUninferredParameter.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/withUninferredParameter.fir.kt deleted file mode 100644 index 776b7b953ee..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/withUninferredParameter.fir.kt +++ /dev/null @@ -1,20 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE -// NI_EXPECTED_FILE - -class GenericController { - suspend fun yield(t: T) {} -} - -fun generate(g: suspend GenericController.(S) -> Unit): S = TODO() - -val test1 = generate { - yield(4) -} - -val test2 = generate { - yield(4) -} - -val test3 = generate { bar: Int -> - yield(4) -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/withUninferredParameter.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/withUninferredParameter.kt index 4e2499f3c0f..58b437e1b95 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/withUninferredParameter.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/withUninferredParameter.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE // NI_EXPECTED_FILE diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/kt28658.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/kt28658.fir.kt deleted file mode 100644 index b5344f01fb8..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/kt28658.fir.kt +++ /dev/null @@ -1,34 +0,0 @@ -// !LANGUAGE: +NewInference -// !USE_EXPERIMENTAL: kotlin.RequiresOptIn -// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE - -import kotlin.experimental.ExperimentalTypeInference - -fun test1() { - sequence { - val a: Array = arrayOf(1, 2, 3) - val b = arrayOf(1, 2, 3) - } -} - -fun test2() = sequence { arrayOf(1, 2, 3) } - - -class Foo - -fun f1(f: Foo.() -> Unit) {} - -@OptIn(ExperimentalTypeInference::class) -fun f2(@BuilderInference f: Foo.() -> Unit) { -} - -fun test3() { - f1 { - val a: Array = arrayOf(1, 2, 3) - } - - f2 { - val a: Array = arrayOf(1, 2, 3) - } -} - diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/kt28658.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/kt28658.kt index 65cf42a412b..a9d91a64d42 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/kt28658.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/kt28658.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +NewInference // !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt index 8771ccc1b72..8fa50ac82cf 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -1082,6 +1082,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirErrors.NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER) { firDiagnostic -> + NewInferenceNoInformationForParameterImpl( + firDiagnostic.a, + firDiagnostic as FirPsiDiagnostic<*>, + token, + ) + } add(FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY) { firDiagnostic -> OverloadResolutionAmbiguityImpl( firDiagnostic.a.map { abstractFirBasedSymbol -> diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt index b64592dbc22..33ca69854f1 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnostics.kt @@ -774,6 +774,11 @@ sealed class KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = ManyLambdaExpressionArguments::class } + abstract class NewInferenceNoInformationForParameter : KtFirDiagnostic() { + override val diagnosticClass get() = NewInferenceNoInformationForParameter::class + abstract val name: String + } + abstract class OverloadResolutionAmbiguity : KtFirDiagnostic() { override val diagnosticClass get() = OverloadResolutionAmbiguity::class abstract val candidates: List diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index d9161e6c21e..8e7d76355d9 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -1246,6 +1246,14 @@ internal class ManyLambdaExpressionArgumentsImpl( override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) } +internal class NewInferenceNoInformationForParameterImpl( + override val name: String, + firDiagnostic: FirPsiDiagnostic<*>, + override val token: ValidityToken, +) : KtFirDiagnostic.NewInferenceNoInformationForParameter(), KtAbstractFirDiagnostic { + override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) +} + internal class OverloadResolutionAmbiguityImpl( override val candidates: List, firDiagnostic: FirPsiDiagnostic<*>,