Do not check type depth for constrains generated on subtyping
#KT-38143 fixed
This commit is contained in:
+5
@@ -1921,6 +1921,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt38143.kt")
|
||||||
|
public void testKt38143() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt38143.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt4975.kt")
|
@TestMetadata("kt4975.kt")
|
||||||
public void testKt4975() throws Exception {
|
public void testKt4975() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
||||||
|
|||||||
+11
-3
@@ -79,13 +79,14 @@ class ConstraintInjector(
|
|||||||
possibleNewConstraints!!.add(typeVar to constraint)
|
possibleNewConstraints!!.add(typeVar to constraint)
|
||||||
}
|
}
|
||||||
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
|
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
|
||||||
|
var constraintsFromIsSubtype = true
|
||||||
|
|
||||||
while (possibleNewConstraints != null) {
|
while (possibleNewConstraints != null) {
|
||||||
|
|
||||||
val constraintsToProcess = possibleNewConstraints
|
val constraintsToProcess = possibleNewConstraints
|
||||||
possibleNewConstraints = null
|
possibleNewConstraints = null
|
||||||
for ((typeVariable, constraint) in constraintsToProcess!!) {
|
for ((typeVariable, constraint) in constraintsToProcess!!) {
|
||||||
if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue
|
if (c.shouldWeSkipConstraint(typeVariable, constraint, constraintsFromIsSubtype)) continue
|
||||||
|
|
||||||
val constraints =
|
val constraints =
|
||||||
c.notFixedTypeVariables[typeVariable.freshTypeConstructor(c)] ?: typeCheckerContext.fixedTypeVariable(typeVariable)
|
c.notFixedTypeVariables[typeVariable.freshTypeConstructor(c)] ?: typeCheckerContext.fixedTypeVariable(typeVariable)
|
||||||
@@ -108,6 +109,7 @@ class ConstraintInjector(
|
|||||||
) {
|
) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
constraintsFromIsSubtype = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,11 +117,17 @@ class ConstraintInjector(
|
|||||||
c.maxTypeDepthFromInitialConstraints = max(c.maxTypeDepthFromInitialConstraints, initialType.typeDepth())
|
c.maxTypeDepthFromInitialConstraints = max(c.maxTypeDepthFromInitialConstraints, initialType.typeDepth())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Context.shouldWeSkipConstraint(typeVariable: TypeVariableMarker, constraint: Constraint): Boolean {
|
private fun Context.shouldWeSkipConstraint(
|
||||||
|
typeVariable: TypeVariableMarker,
|
||||||
|
constraint: Constraint,
|
||||||
|
constraintsFromIsSubtype: Boolean
|
||||||
|
): Boolean {
|
||||||
assert(constraint.kind != ConstraintKind.EQUALITY)
|
assert(constraint.kind != ConstraintKind.EQUALITY)
|
||||||
|
|
||||||
val constraintType = constraint.type
|
val constraintType = constraint.type
|
||||||
if (!isAllowedType(constraintType)) return true
|
// TODO: seems these coditions never met, at least in the tests, we need either to find a test for it or drop the check
|
||||||
|
if (!constraintsFromIsSubtype && !isAllowedType(constraintType))
|
||||||
|
return true
|
||||||
|
|
||||||
if (constraintType.typeConstructor() == typeVariable.freshTypeConstructor()) {
|
if (constraintType.typeConstructor() == typeVariable.freshTypeConstructor()) {
|
||||||
if (constraintType.lowerBoundIfFlexible().isMarkedNullable() && constraint.kind == LOWER) return false // T? <: T
|
if (constraintType.lowerBoundIfFlexible().isMarkedNullable() && constraint.kind == LOWER) return false // T? <: T
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
|
// !LANGUAGE: +NewInference
|
||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||||
|
|
||||||
|
// Generic interface, nothing interesting here
|
||||||
|
interface UseCase<in I, out O> {
|
||||||
|
fun execute(input: I): O
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't want to call use cases without input with explicit Unit argument, so we create this handy extension
|
||||||
|
fun <O> UseCase<Unit, O>.execute(): O = execute(Unit)
|
||||||
|
|
||||||
|
class Foo : UseCase<Unit, List<List<List<String>>>> {
|
||||||
|
override fun execute(input: Unit) = listOf(listOf(listOf("foo")))
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar : UseCase<Unit, List<List<String>>> {
|
||||||
|
override fun execute(input: Unit) = listOf(listOf("bar"))
|
||||||
|
}
|
||||||
|
|
||||||
|
class Baz : UseCase<Unit, List<List<List<List<List<List<String>>>>>>> {
|
||||||
|
override fun execute(input: Unit) = listOf(listOf(listOf(listOf(listOf(listOf("foo"))))))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val foo = Foo()
|
||||||
|
foo.execute(Unit) // Member: OK both versions
|
||||||
|
foo.execute() // Extension: OI - OK, NI - was error: "Not enough information to infer type variable O"
|
||||||
|
|
||||||
|
val bar = Bar()
|
||||||
|
bar.execute(Unit) // Member: OK both versions
|
||||||
|
bar.execute() // Extension: OK both versions
|
||||||
|
|
||||||
|
val baz = Baz()
|
||||||
|
baz.execute(Unit)
|
||||||
|
baz.execute()
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun main(): kotlin.Unit
|
||||||
|
public fun </*0*/ O> UseCase<kotlin.Unit, O>.execute(): O
|
||||||
|
|
||||||
|
public final class Bar : UseCase<kotlin.Unit, kotlin.collections.List<kotlin.collections.List<kotlin.String>>> {
|
||||||
|
public constructor Bar()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ fun execute(/*0*/ input: kotlin.Unit): kotlin.collections.List<kotlin.collections.List<kotlin.String>>
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Baz : UseCase<kotlin.Unit, kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.String>>>>>>> {
|
||||||
|
public constructor Baz()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ fun execute(/*0*/ input: kotlin.Unit): kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.String>>>>>>
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Foo : UseCase<kotlin.Unit, kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.String>>>> {
|
||||||
|
public constructor Foo()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ fun execute(/*0*/ input: kotlin.Unit): kotlin.collections.List<kotlin.collections.List<kotlin.collections.List<kotlin.String>>>
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface UseCase</*0*/ in I, /*1*/ out O> {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public abstract fun execute(/*0*/ input: I): O
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+5
@@ -2931,6 +2931,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt38143.kt")
|
||||||
|
public void testKt38143() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt38143.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt4975.kt")
|
@TestMetadata("kt4975.kt")
|
||||||
public void testKt4975() throws Exception {
|
public void testKt4975() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
||||||
|
|||||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+5
@@ -2931,6 +2931,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt37627.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("kt38143.kt")
|
||||||
|
public void testKt38143() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt38143.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kt4975.kt")
|
@TestMetadata("kt4975.kt")
|
||||||
public void testKt4975() throws Exception {
|
public void testKt4975() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user