提交 f06a5321 编写于 作者: V Victor Petukhov

Approximate definitely not-null types for type parameter's types if they are...

Approximate definitely not-null types for type parameter's types if they are already not-null (has not-null upper bounds)

^KT-44440 Fixed
上级 f2c1608c
......@@ -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|))
}
......@@ -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()
......
// !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)
// !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)
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
}
......@@ -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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册