FIR: Report INFERENCE_NO_INFORMATION_FOR_PARAMETER diagnostic
This commit is contained in:
committed by
TeamCityServer
parent
6e901e3785
commit
c420957eac
+4
@@ -341,6 +341,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
}
|
||||
|
||||
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error<KtValueArgument>()
|
||||
|
||||
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error<KtElement> {
|
||||
parameter<String>("name")
|
||||
}
|
||||
}
|
||||
|
||||
val AMBIGUITY by object : DiagnosticGroup("Ambiguity") {
|
||||
|
||||
@@ -256,6 +256,7 @@ object FirErrors {
|
||||
val ASSIGNMENT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
|
||||
val RESULT_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
|
||||
val MANY_LAMBDA_EXPRESSION_ARGUMENTS by error0<KtValueArgument>()
|
||||
val NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER by error1<KtElement, String>()
|
||||
|
||||
// Ambiguity
|
||||
val OVERLOAD_RESOLUTION_AMBIGUITY by error1<PsiElement, Collection<AbstractFirBasedSymbol<*>>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
+24
@@ -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} <!: ${it.upperType}"
|
||||
// Error should be reported on the error type itself
|
||||
is ConstrainingTypeIsError -> 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<ConstraintSystemError>,
|
||||
candidate: Candidate,
|
||||
): FirDiagnostic<FirSourceElement>? {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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("<error>"))
|
||||
|
||||
|
||||
+3
-2
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+76
-7
@@ -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<FirStatement>,
|
||||
) {
|
||||
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>
|
||||
): 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<PostponedResolvedAtom>,
|
||||
analyze: (PostponedResolvedAtom) -> Unit
|
||||
|
||||
@@ -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 --------------------------
|
||||
|
||||
|
||||
@@ -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? {
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ class CapturedTypeFromSubtyping(
|
||||
val position: ConstraintPosition
|
||||
) : ConstraintSystemError(INAPPLICABLE)
|
||||
|
||||
abstract class NotEnoughInformationForTypeParameter<T>(
|
||||
open class NotEnoughInformationForTypeParameter<T>(
|
||||
val typeVariable: TypeVariableMarker,
|
||||
val resolvedAtom: T
|
||||
) : ConstraintSystemError(INAPPLICABLE)
|
||||
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
fun <T: Any> fooT22() : T? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun foo1() {
|
||||
fooT22()
|
||||
}
|
||||
|
||||
val n : Nothing = null.sure()
|
||||
|
||||
fun <T : Any> T?.sure() : T = this!!
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun <T: Any> fooT22() : T? {
|
||||
return null
|
||||
}
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
package noInformationForParameter
|
||||
//+JDK
|
||||
|
||||
import java.util.*
|
||||
|
||||
fun test() {
|
||||
val n = newList()
|
||||
|
||||
val n1 : List<String> = newList()
|
||||
}
|
||||
|
||||
fun <S> newList() : ArrayList<S> {
|
||||
return ArrayList<S>()
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
package noInformationForParameter
|
||||
//+JDK
|
||||
|
||||
|
||||
@@ -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 <R> test(callback: (R) -> Unit):Unit = callback(null!!)
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNREACHABLE_CODE
|
||||
//KT-2445 Calling method with function with generic parameter causes compile-time exception
|
||||
package a
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
//KT-832 Provide better diagnostics when type inference fails for an expression that returns a function
|
||||
package a
|
||||
|
||||
fun <T> fooT2() : (t : T) -> T {
|
||||
return {it}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
fooT2()(1) // here 1 should not be marked with an error
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
//KT-832 Provide better diagnostics when type inference fails for an expression that returns a function
|
||||
package a
|
||||
|
||||
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
// NI_EXPECTED_FILE
|
||||
val x get() = foo()
|
||||
val y get() = bar()
|
||||
|
||||
fun <E> foo(): E = null!!
|
||||
fun <E> bar(): List<E> = null!!
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// NI_EXPECTED_FILE
|
||||
val x get() = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>()
|
||||
val y get() = <!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!>()
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// KT-353 Generic type argument inference sometimes doesn't work
|
||||
|
||||
interface A {
|
||||
fun <T> 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
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// KT-353 Generic type argument inference sometimes doesn't work
|
||||
|
||||
interface A {
|
||||
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||
// NI_EXPECTED_FILE
|
||||
|
||||
@file:OptIn(ExperimentalTypeInference::class)
|
||||
|
||||
import kotlin.experimental.ExperimentalTypeInference
|
||||
|
||||
interface Base<K>
|
||||
|
||||
interface Controller<T> : Base<T> {
|
||||
suspend fun yield(t: T) {}
|
||||
}
|
||||
|
||||
interface SpecificController<T> : Base<String> {
|
||||
suspend fun yield(t: T) {}
|
||||
}
|
||||
|
||||
fun <S> generate(@BuilderInference g: suspend Controller<S>.() -> Unit): S = TODO()
|
||||
fun <S> generateSpecific(@BuilderInference g: suspend SpecificController<S>.() -> Unit): S = TODO()
|
||||
|
||||
fun Base<*>.starBase() {}
|
||||
fun Base<String>.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()
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||
// NI_EXPECTED_FILE
|
||||
|
||||
Vendored
-23
@@ -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<T> {
|
||||
suspend fun yield(t: T) {}
|
||||
}
|
||||
|
||||
fun <S> generate(@BuilderInference g: suspend GenericController<S>.() -> Unit): List<S> = TODO()
|
||||
|
||||
@BuilderInference
|
||||
suspend fun <S> GenericController<List<S>>.yieldGenerate(g: suspend GenericController<S>.() -> Unit): Unit = TODO()
|
||||
|
||||
val test1 = generate {
|
||||
// TODO: KT-15185
|
||||
yieldGenerate {
|
||||
yield(4)
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
// NI_EXPECTED_FILE
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// NI_EXPECTED_FILE
|
||||
|
||||
class Controller<T : Number> {
|
||||
suspend fun yield(t: T) {}
|
||||
}
|
||||
|
||||
fun <S : Number> generate(g: suspend Controller<S>.() -> Unit): S = TODO()
|
||||
|
||||
val test = generate {
|
||||
yield(<!ARGUMENT_TYPE_MISMATCH!>"foo"<!>)
|
||||
}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// NI_EXPECTED_FILE
|
||||
|
||||
|
||||
Vendored
-20
@@ -1,20 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
||||
// NI_EXPECTED_FILE
|
||||
|
||||
class GenericController<T> {
|
||||
suspend fun yield(t: T) {}
|
||||
}
|
||||
|
||||
fun <S> generate(g: suspend GenericController<S>.(S) -> Unit): S = TODO()
|
||||
|
||||
val test1 = generate {
|
||||
yield(<!ARGUMENT_TYPE_MISMATCH!>4<!>)
|
||||
}
|
||||
|
||||
val test2 = generate<Int> {
|
||||
yield(4)
|
||||
}
|
||||
|
||||
val test3 = generate { bar: Int ->
|
||||
yield(4)
|
||||
}
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
||||
// NI_EXPECTED_FILE
|
||||
|
||||
|
||||
@@ -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<Int> = arrayOf(1, 2, 3)
|
||||
val b = arrayOf(1, 2, 3)
|
||||
}
|
||||
}
|
||||
|
||||
fun test2() = sequence { arrayOf(1, 2, 3) }
|
||||
|
||||
|
||||
class Foo<T>
|
||||
|
||||
fun <T> f1(f: Foo<T>.() -> Unit) {}
|
||||
|
||||
@OptIn(ExperimentalTypeInference::class)
|
||||
fun <T> f2(@BuilderInference f: Foo<T>.() -> Unit) {
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
f1 {
|
||||
val a: Array<Int> = arrayOf(1, 2, 3)
|
||||
}
|
||||
|
||||
f2 {
|
||||
val a: Array<Int> = arrayOf(1, 2, 3)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +NewInference
|
||||
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
|
||||
+7
@@ -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 ->
|
||||
|
||||
+5
@@ -774,6 +774,11 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = ManyLambdaExpressionArguments::class
|
||||
}
|
||||
|
||||
abstract class NewInferenceNoInformationForParameter : KtFirDiagnostic<KtElement>() {
|
||||
override val diagnosticClass get() = NewInferenceNoInformationForParameter::class
|
||||
abstract val name: String
|
||||
}
|
||||
|
||||
abstract class OverloadResolutionAmbiguity : KtFirDiagnostic<PsiElement>() {
|
||||
override val diagnosticClass get() = OverloadResolutionAmbiguity::class
|
||||
abstract val candidates: List<KtSymbol>
|
||||
|
||||
+8
@@ -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<KtElement> {
|
||||
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
|
||||
}
|
||||
|
||||
internal class OverloadResolutionAmbiguityImpl(
|
||||
override val candidates: List<KtSymbol>,
|
||||
firDiagnostic: FirPsiDiagnostic<*>,
|
||||
|
||||
Reference in New Issue
Block a user