diff --git a/compiler/testData/diagnostics/tests/controlStructures/typeInferenceForExclExcl.kt b/compiler/testData/diagnostics/tests/controlStructures/typeInferenceForExclExcl.kt new file mode 100644 index 00000000000..ebf365b3cd8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlStructures/typeInferenceForExclExcl.kt @@ -0,0 +1,20 @@ +// !CHECK_TYPE +// FILE: A.java +public class A { + public static String foo() { + return ""; + } +} + +// FILE: b.kt +fun exclExcl(t: T?): T = t!! + +fun test11() { + // not 'String!' + exclExcl(A.foo()) checkType { it : _ } + exclExcl(A.foo()) checkType { it : _ } + + // not 'String!' + A.foo()!! checkType { it : _ } + A.foo()!! checkType { it : _ } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlStructures/typeInferenceForExclExcl.txt b/compiler/testData/diagnostics/tests/controlStructures/typeInferenceForExclExcl.txt new file mode 100644 index 00000000000..f0e28eae292 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlStructures/typeInferenceForExclExcl.txt @@ -0,0 +1,14 @@ +package + +internal fun exclExcl(/*0*/ t: T?): T +internal fun test11(): kotlin.Unit + +public open class A { + public constructor A() + 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 + + // Static members + public open fun foo(): kotlin.String! +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java index ee0a137c7e9..ce165337a55 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestGenerated.java @@ -2022,6 +2022,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("typeInferenceForExclExcl.kt") + public void testTypeInferenceForExclExcl() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlStructures/typeInferenceForExclExcl.kt"); + doTest(fileName); + } + @TestMetadata("valVarCatchParameter.kt") public void testValVarCatchParameter() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/controlStructures/valVarCatchParameter.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt index 1263450de12..a879972d631 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemImpl.kt @@ -333,18 +333,20 @@ public class ConstraintSystemImpl : ConstraintSystem { val typeBounds = getTypeBounds(parameterType) - if (!parameterType.isMarkedNullable() || !newConstrainingType.isMarkedNullable()) { + if (!parameterType.isMarkedNullable() || !TypeUtils.isNullableType(newConstrainingType)) { typeBounds.addBound(boundKind, newConstrainingType, constraintPosition) return } // For parameter type T: // constraint T? = Int? should transform to T >: Int and T <: Int? - // constraint T? >: Int? should transform to T >: Int + // constraint T? = Int! should transform to T >: Int and T <: Int! + + // constraints T? >: Int?; T? >: Int! should transform to T >: Int val notNullConstrainingType = TypeUtils.makeNotNullable(newConstrainingType) if (boundKind == EXACT_BOUND || boundKind == LOWER_BOUND) { typeBounds.addBound(LOWER_BOUND, notNullConstrainingType, constraintPosition) } - // constraint T? <: Int? should transform to T <: Int? + // constraints T? <: Int?; T? <: Int! should transform to T <: Int?; T <: Int! correspondingly if (boundKind == EXACT_BOUND || boundKind == UPPER_BOUND) { typeBounds.addBound(UPPER_BOUND, newConstrainingType, constraintPosition) }