[NI] Implement various optimizations for incorporation algorithm
Mostly, these optimisations are picked from the old inference. Also, remove exponential complexity for flexible types in approximation, note that more correct fix for this would be to introduce new types that corresponds just to platform types to avoid nullability problems, but due to complexity it will be done later #KT-31415 Fixed
This commit is contained in:
+2
-3
@@ -158,9 +158,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val simpleType = this.asSimpleType() ?: return false
|
repeat(argumentsCount()) { index ->
|
||||||
repeat(simpleType.argumentsCount()) { index ->
|
val argument = getArgument(index)
|
||||||
val argument = simpleType.getArgument(index)
|
|
||||||
if (!argument.isStarProjection() && argument.getType().containsInternal(predicate, visited)) return true
|
if (!argument.isStarProjection() && argument.getType().containsInternal(predicate, visited)) return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -144,13 +144,13 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
|
|||||||
return typeConstructor
|
return typeConstructor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.argumentsCount(): Int {
|
override fun KotlinTypeMarker.argumentsCount(): Int {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
|
|
||||||
return this.typeArguments.size
|
return this.typeArguments.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.getArgument(index: Int): TypeArgumentMarker {
|
override fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
|
|
||||||
return this.typeArguments.getOrNull(index)
|
return this.typeArguments.getOrNull(index)
|
||||||
|
|||||||
+10
@@ -10059,6 +10059,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt8879.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt8879.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyConstraintsDueToFlexibleRawTypes.kt")
|
||||||
|
public void testManyConstraintsDueToFlexibleRawTypes() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToFlexibleRawTypes.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt")
|
||||||
|
public void testManyConstraintsDueToRecursiveFlexibleTypesWithWildcards() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notNullConstraintOnNullableType.kt")
|
@TestMetadata("notNullConstraintOnNullableType.kt")
|
||||||
public void testNotNullConstraintOnNullableType() throws Exception {
|
public void testNotNullConstraintOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/notNullConstraintOnNullableType.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/notNullConstraintOnNullableType.kt");
|
||||||
|
|||||||
+3
-5
@@ -22,10 +22,8 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext
|
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext
|
||||||
import org.jetbrains.kotlin.types.model.StubTypeMarker
|
import org.jetbrains.kotlin.types.model.*
|
||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
import java.util.*
|
||||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
|
||||||
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
|
|
||||||
|
|
||||||
fun ConstraintStorage.buildCurrentSubstitutor(
|
fun ConstraintStorage.buildCurrentSubstitutor(
|
||||||
context: TypeSystemInferenceExtensionContext,
|
context: TypeSystemInferenceExtensionContext,
|
||||||
@@ -84,4 +82,4 @@ fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTyp
|
|||||||
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun <E> MutableList<E>.trimToSize(newSize: Int) = subList(newSize, size).clear()
|
internal fun <E> MutableList<E>.trimToSize(newSize: Int) = subList(newSize, size).clear()
|
||||||
|
|||||||
+59
-12
@@ -29,6 +29,8 @@ class ConstraintIncorporator(
|
|||||||
fun getConstraintsForVariable(typeVariable: TypeVariableMarker): Collection<Constraint>
|
fun getConstraintsForVariable(typeVariable: TypeVariableMarker): Collection<Constraint>
|
||||||
|
|
||||||
fun addNewIncorporatedConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker)
|
fun addNewIncorporatedConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker)
|
||||||
|
|
||||||
|
fun addNewIncorporatedConstraint(typeVariable: TypeVariableMarker, type: KotlinTypeMarker, constraintContext: ConstraintContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
// \alpha is typeVariable, \beta -- other type variable registered in ConstraintStorage
|
// \alpha is typeVariable, \beta -- other type variable registered in ConstraintStorage
|
||||||
@@ -138,24 +140,49 @@ class ConstraintIncorporator(
|
|||||||
|
|
||||||
if (baseConstraint.kind != ConstraintKind.UPPER) {
|
if (baseConstraint.kind != ConstraintKind.UPPER) {
|
||||||
val generatedConstraintType = approximateCapturedTypes(typeForApproximation, toSuper = false)
|
val generatedConstraintType = approximateCapturedTypes(typeForApproximation, toSuper = false)
|
||||||
if (!trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(
|
addNewConstraint(targetVariable, baseConstraint, otherVariable, otherConstraint, generatedConstraintType, isSubtype = true)
|
||||||
otherConstraint, generatedConstraintType, isSubtype = true
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
addNewIncorporatedConstraint(generatedConstraintType, targetVariable.defaultType())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (baseConstraint.kind != ConstraintKind.LOWER) {
|
if (baseConstraint.kind != ConstraintKind.LOWER) {
|
||||||
val generatedConstraintType = approximateCapturedTypes(typeForApproximation, toSuper = true)
|
val generatedConstraintType = approximateCapturedTypes(typeForApproximation, toSuper = true)
|
||||||
if (!trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(
|
addNewConstraint(targetVariable, baseConstraint, otherVariable, otherConstraint, generatedConstraintType, isSubtype = false)
|
||||||
otherConstraint, generatedConstraintType, isSubtype = false
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
addNewIncorporatedConstraint(targetVariable.defaultType(), generatedConstraintType)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun Context.addNewConstraint(
|
||||||
|
targetVariable: TypeVariableMarker,
|
||||||
|
baseConstraint: Constraint,
|
||||||
|
otherVariable: TypeVariableMarker,
|
||||||
|
otherConstraint: Constraint,
|
||||||
|
newConstraint: KotlinTypeMarker,
|
||||||
|
isSubtype: Boolean
|
||||||
|
) {
|
||||||
|
if (targetVariable in getNestedTypeVariables(newConstraint)) return
|
||||||
|
if (!containsConstrainingTypeWithoutProjection(newConstraint, otherConstraint)) return
|
||||||
|
if (trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(otherConstraint, newConstraint, isSubtype)) return
|
||||||
|
|
||||||
|
val derivedFrom = (baseConstraint.derivedFrom + otherConstraint.derivedFrom).toMutableSet()
|
||||||
|
if (otherVariable in derivedFrom) return
|
||||||
|
|
||||||
|
derivedFrom.add(otherVariable)
|
||||||
|
|
||||||
|
val kind = if (isSubtype) ConstraintKind.LOWER else ConstraintKind.UPPER
|
||||||
|
|
||||||
|
addNewIncorporatedConstraint(targetVariable, newConstraint, ConstraintContext(kind, derivedFrom))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.containsConstrainingTypeWithoutProjection(
|
||||||
|
newConstraint: KotlinTypeMarker,
|
||||||
|
otherConstraint: Constraint
|
||||||
|
): Boolean {
|
||||||
|
return getNestedArguments(newConstraint).any {
|
||||||
|
it.getType().typeConstructor() == otherConstraint.type.typeConstructor() && it.getVariance() == TypeVariance.INV
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Context.getNestedTypeVariables(type: KotlinTypeMarker): List<TypeVariableMarker> =
|
||||||
|
getNestedArguments(type).mapNotNull { getTypeVariable(it.getType().typeConstructor()) }
|
||||||
|
|
||||||
|
|
||||||
private fun KotlinTypeMarker.substitute(c: Context, typeVariable: TypeVariableMarker, value: KotlinTypeMarker): KotlinTypeMarker {
|
private fun KotlinTypeMarker.substitute(c: Context, typeVariable: TypeVariableMarker, value: KotlinTypeMarker): KotlinTypeMarker {
|
||||||
val substitutor = c.typeSubstitutorByTypeConstructor(mapOf(typeVariable.freshTypeConstructor(c) to value))
|
val substitutor = c.typeSubstitutorByTypeConstructor(mapOf(typeVariable.freshTypeConstructor(c) to value))
|
||||||
return substitutor.safeSubstitute(c, this)
|
return substitutor.safeSubstitute(c, this)
|
||||||
@@ -166,3 +193,23 @@ class ConstraintIncorporator(
|
|||||||
if (toSuper) typeApproximator.approximateToSuperType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type
|
if (toSuper) typeApproximator.approximateToSuperType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type
|
||||||
else typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type
|
else typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun TypeSystemInferenceExtensionContext.getNestedArguments(type: KotlinTypeMarker): List<TypeArgumentMarker> {
|
||||||
|
val result = ArrayList<TypeArgumentMarker>()
|
||||||
|
|
||||||
|
val stack = ArrayDeque<TypeArgumentMarker>()
|
||||||
|
stack.push(createTypeArgument(type, TypeVariance.INV))
|
||||||
|
|
||||||
|
while (!stack.isEmpty()) {
|
||||||
|
val typeProjection = stack.pop()
|
||||||
|
if (typeProjection.isStarProjection()) continue
|
||||||
|
|
||||||
|
result.add(typeProjection)
|
||||||
|
|
||||||
|
val projectedType = typeProjection.getType()
|
||||||
|
for (argumentIndex in 0 until projectedType.argumentsCount()) {
|
||||||
|
stack.add(projectedType.getArgument(argumentIndex))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|||||||
+22
-10
@@ -163,7 +163,24 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
|
|
||||||
private fun addConstraint(typeVariableConstructor: TypeConstructorMarker, type: KotlinTypeMarker, kind: ConstraintKind) {
|
private fun addConstraint(typeVariableConstructor: TypeConstructorMarker, type: KotlinTypeMarker, kind: ConstraintKind) {
|
||||||
val typeVariable = c.allTypeVariables[typeVariableConstructor]
|
val typeVariable = c.allTypeVariables[typeVariableConstructor]
|
||||||
?: error("Should by type variableConstructor: $typeVariableConstructor. ${c.allTypeVariables.values}")
|
?: error("Should by type variableConstructor: $typeVariableConstructor. ${c.allTypeVariables.values}")
|
||||||
|
|
||||||
|
addNewIncorporatedConstraint(typeVariable, type, ConstraintContext(kind, emptySet()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// from ConstraintIncorporator.Context
|
||||||
|
override fun addNewIncorporatedConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker) {
|
||||||
|
if (c.isAllowedType(lowerType) && c.isAllowedType(upperType)) {
|
||||||
|
runIsSubtypeOf(lowerType, upperType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addNewIncorporatedConstraint(
|
||||||
|
typeVariable: TypeVariableMarker,
|
||||||
|
type: KotlinTypeMarker,
|
||||||
|
constraintContext: ConstraintContext
|
||||||
|
) {
|
||||||
|
val (kind, derivedFrom) = constraintContext
|
||||||
|
|
||||||
var targetType = type
|
var targetType = type
|
||||||
if (targetType.isUninferredParameter()) {
|
if (targetType.isUninferredParameter()) {
|
||||||
@@ -200,14 +217,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
possibleNewConstraints.add(typeVariable to Constraint(kind, targetType, position))
|
possibleNewConstraints.add(typeVariable to Constraint(kind, targetType, position, derivedFrom = derivedFrom))
|
||||||
}
|
|
||||||
|
|
||||||
// from ConstraintIncorporator.Context
|
|
||||||
override fun addNewIncorporatedConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker) {
|
|
||||||
if (c.isAllowedType(lowerType) && c.isAllowedType(upperType)) {
|
|
||||||
runIsSubtypeOf(lowerType, upperType)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val allTypeVariablesWithConstraints: Collection<VariableWithConstraints>
|
override val allTypeVariablesWithConstraints: Collection<VariableWithConstraints>
|
||||||
@@ -234,4 +244,6 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
|
|
||||||
private fun renderBaseConstraint() = "Base constraint: $baseLowerType <: $baseUpperType from position: $position"
|
private fun renderBaseConstraint() = "Base constraint: $baseLowerType <: $baseUpperType from position: $position"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class ConstraintContext(val kind: ConstraintKind, val derivedFrom: Set<TypeVariableMarker>)
|
||||||
+2
-1
@@ -67,7 +67,8 @@ class Constraint(
|
|||||||
val kind: ConstraintKind,
|
val kind: ConstraintKind,
|
||||||
val type: KotlinTypeMarker, // flexible types here is allowed
|
val type: KotlinTypeMarker, // flexible types here is allowed
|
||||||
val position: IncorporationConstraintPosition,
|
val position: IncorporationConstraintPosition,
|
||||||
val typeHashCode: Int = type.hashCode()
|
val typeHashCode: Int = type.hashCode(),
|
||||||
|
val derivedFrom: Set<TypeVariableMarker>
|
||||||
) {
|
) {
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
|
|||||||
+7
-1
@@ -47,7 +47,13 @@ class MutableVariableWithConstraints(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val actualConstraint = if (addAsEqualityConstraint)
|
val actualConstraint = if (addAsEqualityConstraint)
|
||||||
Constraint(ConstraintKind.EQUALITY, constraint.type, constraint.position, constraint.typeHashCode)
|
Constraint(
|
||||||
|
ConstraintKind.EQUALITY,
|
||||||
|
constraint.type,
|
||||||
|
constraint.position,
|
||||||
|
constraint.typeHashCode,
|
||||||
|
derivedFrom = constraint.derivedFrom
|
||||||
|
)
|
||||||
else
|
else
|
||||||
constraint
|
constraint
|
||||||
|
|
||||||
|
|||||||
@@ -189,9 +189,15 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
|||||||
* Similar for L_1 <: L_2: Let B : resultType <: B. L_2 <: B and L_1 <: B.
|
* Similar for L_1 <: L_2: Let B : resultType <: B. L_2 <: B and L_1 <: B.
|
||||||
* I.e. for every type B such as L_2 <: B, L_1 <: B. For example B = L_2.
|
* I.e. for every type B such as L_2 <: B, L_1 <: B. For example B = L_2.
|
||||||
*/
|
*/
|
||||||
|
val lowerBound = type.lowerBound()
|
||||||
|
val upperBound = type.upperBound()
|
||||||
|
|
||||||
val lowerResult = approximateTo(type.lowerBound(), conf, depth)
|
val lowerResult = approximateTo(lowerBound, conf, depth)
|
||||||
val upperResult = approximateTo(type.upperBound(), conf, depth)
|
|
||||||
|
val upperResult = if (lowerBound.typeConstructor() == upperBound.typeConstructor())
|
||||||
|
lowerResult?.withNullability(upperBound.isMarkedNullable())
|
||||||
|
else
|
||||||
|
approximateTo(upperBound, conf, depth)
|
||||||
if (lowerResult == null && upperResult == null) return null
|
if (lowerResult == null && upperResult == null) return null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -202,8 +208,8 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
|||||||
* If U_1 <: U_2.lower .. U_2.upper, then we know only that U_1 <: U_2.upper.
|
* If U_1 <: U_2.lower .. U_2.upper, then we know only that U_1 <: U_2.upper.
|
||||||
*/
|
*/
|
||||||
return createFlexibleType(
|
return createFlexibleType(
|
||||||
lowerResult?.lowerBoundIfFlexible() ?: type.lowerBound(),
|
lowerResult?.lowerBoundIfFlexible() ?: lowerBound,
|
||||||
upperResult?.upperBoundIfFlexible() ?: type.upperBound()
|
upperResult?.upperBoundIfFlexible() ?: upperBound
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
return type.bound().let { approximateTo(it, conf, depth) ?: it }
|
return type.bound().let { approximateTo(it, conf, depth) ?: it }
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ package boundsWithSubstitutors
|
|||||||
class C : A<C>()
|
class C : A<C>()
|
||||||
|
|
||||||
val a = B<C>()
|
val a = B<C>()
|
||||||
val a1 = B<<!NI;UPPER_BOUND_VIOLATED, NI;UPPER_BOUND_VIOLATED, NI;UPPER_BOUND_VIOLATED, NI;UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Int<!>>()
|
val a1 = B<<!NI;UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Int<!>>()
|
||||||
|
|
||||||
class X<A, B : A>()
|
class X<A, B : A>()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@ package c
|
|||||||
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
|
|
||||||
fun Array<Int>.toIntArray(): IntArray = this.<!NI;TYPE_MISMATCH!><!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>mapTo<!>(<!NI;TYPE_MISMATCH!>IntArray(size)<!>, {<!NI;TYPE_MISMATCH!>it<!>})<!>
|
fun Array<Int>.toIntArray(): IntArray = this.<!NI;TYPE_MISMATCH!><!OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>mapTo<!>(<!NI;TYPE_MISMATCH!>IntArray(size)<!>, {it})<!>
|
||||||
|
|
||||||
fun Array<Int>.toArrayList(): ArrayList<Int> = this.mapTo(ArrayList<Int>(size), {it})
|
fun Array<Int>.toArrayList(): ArrayList<Int> = this.mapTo(ArrayList<Int>(size), {it})
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ fun <T: Inv2<T>> foo(klass: Inv<T>): String? = null
|
|||||||
fun <X> bar(): Inv<X> = null!!
|
fun <X> bar(): Inv<X> = null!!
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!>())
|
<!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>(<!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>bar<!>())
|
||||||
}
|
}
|
||||||
Vendored
+32
@@ -0,0 +1,32 @@
|
|||||||
|
// !WITH_NEW_INFERENCE
|
||||||
|
// SKIP_JAVAC
|
||||||
|
|
||||||
|
// FILE: MySettings.java
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class MySettings<
|
||||||
|
SS extends MySettings<SS, PS, L>,
|
||||||
|
PS extends MyComparableSettings,
|
||||||
|
L extends MySettingsListener<PS>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public Collection<PS> getLinkedProjectsSettings() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MySettings getSettings() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MyComparableSettings implements Comparable<MyComparableSettings> {}
|
||||||
|
abstract class MySettingsListener<S extends MyComparableSettings> {}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a = MySettings.getSettings()
|
||||||
|
a.getLinkedProjectsSettings()
|
||||||
|
a.<!NI;DEBUG_INFO_UNRESOLVED_WITH_TARGET, NI;UNRESOLVED_REFERENCE_WRONG_RECEIVER, OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE, OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>linkedProjectsSettings<!>
|
||||||
|
}
|
||||||
Vendored
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
|
|
||||||
|
public open class MySettings</*0*/ SS : MySettings<SS!, PS!, L!>!, /*1*/ PS : MyComparableSettings!, /*2*/ L : MySettingsListener<PS!>!> {
|
||||||
|
public constructor MySettings</*0*/ SS : MySettings<SS!, PS!, L!>!, /*1*/ PS : MyComparableSettings!, /*2*/ L : MySettingsListener<PS!>!>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun getLinkedProjectsSettings(): kotlin.collections.(Mutable)Collection<PS!>!
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public open fun getSettings(): MySettings<(raw) MySettings<*, *, *>!, (raw) MyComparableSettings!, (raw) MySettingsListener<*>!>!
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
// !WITH_NEW_INFERENCE
|
||||||
|
// SKIP_JAVAC
|
||||||
|
|
||||||
|
// FILE: MySettings.java
|
||||||
|
|
||||||
|
import java.util.Collection
|
||||||
|
|
||||||
|
class MySettings<
|
||||||
|
SS extends MySettings<SS, PS, L>,
|
||||||
|
PS extends MyComparableSettings,
|
||||||
|
L extends MySettingsListener<PS>
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public Collection<PS> getLinkedProjectsSettings() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MySettings<?, ?, ?> getSettings() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MyComparableSettings implements Comparable<MyComparableSettings> {}
|
||||||
|
abstract class MySettingsListener<S extends MyComparableSettings> {}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a = MySettings.getSettings()
|
||||||
|
a.getLinkedProjectsSettings()
|
||||||
|
a.<!OI;DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE, OI;TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>linkedProjectsSettings<!>
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun test(): kotlin.Unit
|
||||||
|
|
||||||
|
public/*package*/ open class MySettings</*0*/ SS : MySettings<SS!, PS!, L!>!, /*1*/ PS : MyComparableSettings!, /*2*/ L : MySettingsListener<PS!>!> {
|
||||||
|
public/*package*/ constructor MySettings</*0*/ SS : MySettings<SS!, PS!, L!>!, /*1*/ PS : MyComparableSettings!, /*2*/ L : MySettingsListener<PS!>!>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun getLinkedProjectsSettings(): kotlin.collections.(Mutable)Collection<PS!>!
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
// Static members
|
||||||
|
public open fun getSettings(): MySettings<*, *, *>!
|
||||||
|
}
|
||||||
+1
-1
@@ -7,7 +7,7 @@ fun <T> g (<!UNUSED_PARAMETER!>f<!>: () -> List<T>) : T {<!NO_RETURN_IN_FUNCTION
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
//here possibly can be a cycle on constraints
|
//here possibly can be a cycle on constraints
|
||||||
val <!UNUSED_VARIABLE!>x<!> = g { Collections.<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>emptyList<!>() }
|
val <!UNUSED_VARIABLE!>x<!> = <!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>g<!> { Collections.<!NI;NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>emptyList<!>() }
|
||||||
|
|
||||||
val <!UNUSED_VARIABLE!>y<!> = g<Int> { Collections.emptyList() }
|
val <!UNUSED_VARIABLE!>y<!> = g<Int> { Collections.emptyList() }
|
||||||
val <!UNUSED_VARIABLE!>z<!> : List<Int> = g { Collections.<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>emptyList<!>() }
|
val <!UNUSED_VARIABLE!>z<!> : List<Int> = g { Collections.<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>emptyList<!>() }
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
public val test1: [ERROR : Type for BOutIn(listOf(), null!!)]
|
public val test1: [ERROR : Type for BOutIn(listOf(), null!!)]
|
||||||
public val test2: BInIn<kotlin.collections.List<kotlin.collections.List<kotlin.Any?>>> /* = Bound<in kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.Any?>>>, in kotlin.collections.List<kotlin.collections.List<kotlin.Any?>>> */
|
public val test2: BInIn<kotlin.Nothing> /* = Bound<in kotlin.collections.List<kotlin.Nothing>, in kotlin.Nothing> */
|
||||||
public fun </*0*/ T> listOf(): kotlin.collections.List<T>
|
public fun </*0*/ T> listOf(): kotlin.collections.List<T>
|
||||||
|
|
||||||
public final class Bound</*0*/ X, /*1*/ Y : X> {
|
public final class Bound</*0*/ X, /*1*/ Y : X> {
|
||||||
|
|||||||
@@ -10066,6 +10066,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt8879.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt8879.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyConstraintsDueToFlexibleRawTypes.kt")
|
||||||
|
public void testManyConstraintsDueToFlexibleRawTypes() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToFlexibleRawTypes.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt")
|
||||||
|
public void testManyConstraintsDueToRecursiveFlexibleTypesWithWildcards() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notNullConstraintOnNullableType.kt")
|
@TestMetadata("notNullConstraintOnNullableType.kt")
|
||||||
public void testNotNullConstraintOnNullableType() throws Exception {
|
public void testNotNullConstraintOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/notNullConstraintOnNullableType.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/notNullConstraintOnNullableType.kt");
|
||||||
|
|||||||
Generated
+10
@@ -10061,6 +10061,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
|||||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt8879.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt8879.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyConstraintsDueToFlexibleRawTypes.kt")
|
||||||
|
public void testManyConstraintsDueToFlexibleRawTypes() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToFlexibleRawTypes.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt")
|
||||||
|
public void testManyConstraintsDueToRecursiveFlexibleTypesWithWildcards() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notNullConstraintOnNullableType.kt")
|
@TestMetadata("notNullConstraintOnNullableType.kt")
|
||||||
public void testNotNullConstraintOnNullableType() throws Exception {
|
public void testNotNullConstraintOnNullableType() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/notNullConstraintOnNullableType.kt");
|
runTest("compiler/testData/diagnostics/tests/inference/constraints/notNullConstraintOnNullableType.kt");
|
||||||
|
|||||||
@@ -127,12 +127,12 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext {
|
|||||||
return this.constructor
|
return this.constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.argumentsCount(): Int {
|
override fun KotlinTypeMarker.argumentsCount(): Int {
|
||||||
require(this is SimpleType, this::errorMessage)
|
require(this is KotlinType, this::errorMessage)
|
||||||
return this.arguments.size
|
return this.arguments.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.getArgument(index: Int): TypeArgumentMarker {
|
override fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker {
|
||||||
require(this is SimpleType, this::errorMessage)
|
require(this is SimpleType, this::errorMessage)
|
||||||
return this.arguments[index]
|
return this.arguments[index]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,8 +167,8 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
|||||||
fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker
|
fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker
|
||||||
fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker
|
fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker
|
||||||
|
|
||||||
fun SimpleTypeMarker.argumentsCount(): Int
|
fun KotlinTypeMarker.argumentsCount(): Int
|
||||||
fun SimpleTypeMarker.getArgument(index: Int): TypeArgumentMarker
|
fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker
|
||||||
|
|
||||||
fun SimpleTypeMarker.getArgumentOrNull(index: Int): TypeArgumentMarker? {
|
fun SimpleTypeMarker.getArgumentOrNull(index: Int): TypeArgumentMarker? {
|
||||||
if (index in 0 until argumentsCount()) return getArgument(index)
|
if (index in 0 until argumentsCount()) return getArgument(index)
|
||||||
|
|||||||
Reference in New Issue
Block a user