Approximate definitely not-null types for type parameter's types if they are already not-null (has not-null upper bounds)
^KT-44440 Fixed
This commit is contained in:
Vendored
+1
-1
@@ -7,5 +7,5 @@ FILE: definetelyNotNullForTypeParameter.kt
|
||||
public final fun <F : R|kotlin/Any|> foo(computable: R|Out<F?>|): R|kotlin/Unit| {
|
||||
}
|
||||
public final fun <T : R|kotlin/Any|> bar(computable: R|Out<T?>|): R|kotlin/Unit| {
|
||||
R|/foo|<R|T?!!|>(R|/id|<R|T?|>(R|<local>/computable|))
|
||||
R|/foo|<R|T|>(R|/id|<R|T?|>(R|<local>/computable|))
|
||||
}
|
||||
|
||||
+6
@@ -14002,6 +14002,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44440.kt")
|
||||
public void testKt44440() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt44440.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt702.kt")
|
||||
public void testKt702() throws Exception {
|
||||
|
||||
@@ -360,6 +360,10 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
return this is ConeCapturedTypeConstructor
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.isTypeParameterTypeConstructor(): Boolean {
|
||||
return this.getTypeParameterClassifier() != null
|
||||
}
|
||||
|
||||
override fun KotlinTypeMarker.removeExactAnnotation(): KotlinTypeMarker {
|
||||
// TODO
|
||||
return this
|
||||
|
||||
@@ -338,6 +338,12 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
val originalType = type.original()
|
||||
val approximatedOriginalType =
|
||||
if (toSuper) approximateToSuperType(originalType, conf, depth) else approximateToSubType(originalType, conf, depth)
|
||||
val typeWithErasedNullability = originalType.withNullability(false)
|
||||
|
||||
// Approximate T!! into T if T is already not-null (has not-null upper bounds)
|
||||
if (originalType.typeConstructor().isTypeParameterTypeConstructor() && !typeWithErasedNullability.isNullableType()) {
|
||||
return typeWithErasedNullability
|
||||
}
|
||||
|
||||
return if (conf.definitelyNotNullType) {
|
||||
approximatedOriginalType?.makeDefinitelyNotNullOrNotNull()
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
|
||||
interface I
|
||||
|
||||
fun consume(x: WrapperFactory<Wrapper<I>>) {}
|
||||
|
||||
fun test(x: I) {
|
||||
val y = foo(x)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("WrapperFactory<Wrapper<I>>")!>y<!>
|
||||
consume(y)
|
||||
}
|
||||
|
||||
fun <CX: I> foo(
|
||||
x: CX,
|
||||
fn1: (CX) -> Unit = {},
|
||||
fn2: (CX?) -> Unit = {}
|
||||
) = WrapperFactory { Wrapper(fn1, fn2) }
|
||||
|
||||
class WrapperFactory<W>(val creator: () -> W)
|
||||
|
||||
class Wrapper<in CX2>(val fn1: (CX2) -> Unit, val fn2: (CX2?) -> Unit)
|
||||
@@ -0,0 +1,21 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
|
||||
interface I
|
||||
|
||||
fun consume(x: WrapperFactory<Wrapper<I>>) {}
|
||||
|
||||
fun test(x: I) {
|
||||
val y = foo(x)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("WrapperFactory<Wrapper<I>>")!>y<!>
|
||||
consume(y)
|
||||
}
|
||||
|
||||
fun <CX: I> foo(
|
||||
x: CX,
|
||||
fn1: (CX) -> Unit = {},
|
||||
fn2: (CX?) -> Unit = {}
|
||||
) = WrapperFactory { Wrapper(fn1, fn2) }
|
||||
|
||||
class WrapperFactory<W>(val creator: () -> W)
|
||||
|
||||
class Wrapper<in CX2>(val fn1: (CX2) -> Unit, val fn2: (CX2?) -> Unit)
|
||||
@@ -0,0 +1,28 @@
|
||||
package
|
||||
|
||||
public fun consume(/*0*/ x: WrapperFactory<Wrapper<I>>): kotlin.Unit
|
||||
public fun </*0*/ CX : I> foo(/*0*/ x: CX, /*1*/ fn1: (CX) -> kotlin.Unit = ..., /*2*/ fn2: (CX?) -> kotlin.Unit = ...): WrapperFactory<Wrapper<CX>>
|
||||
public fun test(/*0*/ x: I): kotlin.Unit
|
||||
|
||||
public interface I {
|
||||
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
|
||||
}
|
||||
|
||||
public final class Wrapper</*0*/ in CX2> {
|
||||
public constructor Wrapper</*0*/ in CX2>(/*0*/ fn1: (CX2) -> kotlin.Unit, /*1*/ fn2: (CX2?) -> kotlin.Unit)
|
||||
public final val fn1: (CX2) -> kotlin.Unit
|
||||
public final val fn2: (CX2?) -> kotlin.Unit
|
||||
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
|
||||
}
|
||||
|
||||
public final class WrapperFactory</*0*/ W> {
|
||||
public constructor WrapperFactory</*0*/ W>(/*0*/ creator: () -> W)
|
||||
public final val creator: () -> W
|
||||
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
|
||||
}
|
||||
Generated
+6
@@ -14008,6 +14008,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt44440.kt")
|
||||
public void testKt44440() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt44440.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt702.kt")
|
||||
public void testKt702() throws Exception {
|
||||
|
||||
@@ -464,7 +464,7 @@ fun <T : Number> T?.case_11() {
|
||||
equals(this)
|
||||
itest1()
|
||||
apply {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>
|
||||
equals(null)
|
||||
propT
|
||||
propAny
|
||||
@@ -475,29 +475,29 @@ fun <T : Number> T?.case_11() {
|
||||
funNullableT()
|
||||
funNullableAny()
|
||||
itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.itest1()
|
||||
}
|
||||
also {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.itest1()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.funNullableAny()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,7 +564,7 @@ fun <T : Number> case_11(x: T?) {
|
||||
x.funNullableAny()
|
||||
x.itest()
|
||||
x.apply {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>
|
||||
equals(null)
|
||||
propT
|
||||
propAny
|
||||
@@ -575,29 +575,29 @@ fun <T : Number> case_11(x: T?) {
|
||||
funNullableT()
|
||||
funNullableAny()
|
||||
itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>this<!>.itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>this<!>.itest()
|
||||
}
|
||||
x.also {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T?!!")!>it<!>.funNullableAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.itest()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.equals(null)
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.propT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.propAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.propNullableT
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.propNullableAny
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.funT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.funAny()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.funNullableT()
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Interface1 & T")!>it<!>.funNullableAny()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,6 +137,8 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
|
||||
|
||||
fun TypeConstructorMarker.isCapturedTypeConstructor(): Boolean
|
||||
|
||||
fun TypeConstructorMarker.isTypeParameterTypeConstructor(): Boolean
|
||||
|
||||
fun Collection<KotlinTypeMarker>.singleBestRepresentative(): KotlinTypeMarker?
|
||||
|
||||
fun KotlinTypeMarker.isUnit(): Boolean
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.annotations.BuiltInAnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -573,6 +574,10 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
||||
return this is NewCapturedTypeConstructor
|
||||
}
|
||||
|
||||
override fun TypeConstructorMarker.isTypeParameterTypeConstructor(): Boolean {
|
||||
return this is AbstractTypeConstructor && this.declarationDescriptor is AbstractTypeParameterDescriptor
|
||||
}
|
||||
|
||||
override fun arrayType(componentType: KotlinTypeMarker): SimpleTypeMarker {
|
||||
require(componentType is KotlinType, this::errorMessage)
|
||||
return builtIns.getArrayType(Variance.INVARIANT, componentType)
|
||||
|
||||
Reference in New Issue
Block a user