diff --git a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java index 01409261f8f..aa2a7427616 100644 --- a/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/resolve/tests/org/jetbrains/kotlin/fir/FirOldFrontendDiagnosticsTestGenerated.java @@ -10708,6 +10708,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte runTest("compiler/testData/diagnostics/tests/inference/nothingType/complexDependancyOnVariableWithTrivialConstraint.kt"); } + @TestMetadata("discriminateNothingForReifiedParameter.kt") + public void testDiscriminateNothingForReifiedParameter() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.kt"); + } + + @TestMetadata("discriminatedNothingAndSmartCast.kt") + public void testDiscriminatedNothingAndSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.kt"); + } + @TestMetadata("generateConstraintWithInnerNothingType.kt") public void testGenerateConstraintWithInnerNothingType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nothingType/generateConstraintWithInnerNothingType.kt"); diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt index 8732f958034..3d6c04093a7 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/ResultTypeResolver.kt @@ -22,11 +22,8 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.TypeVariableDirec import org.jetbrains.kotlin.resolve.calls.inference.model.* import org.jetbrains.kotlin.types.AbstractTypeApproximator import org.jetbrains.kotlin.types.TypeApproximatorConfiguration -import org.jetbrains.kotlin.types.model.KotlinTypeMarker -import org.jetbrains.kotlin.types.model.TypeVariableMarker +import org.jetbrains.kotlin.types.model.* import org.jetbrains.kotlin.utils.addToStdlib.safeAs -import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker -import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext class ResultTypeResolver( val typeApproximator: AbstractTypeApproximator, @@ -35,6 +32,7 @@ class ResultTypeResolver( interface Context : TypeSystemInferenceExtensionContext { fun isProperType(type: KotlinTypeMarker): Boolean fun buildNotFixedVariablesToStubTypesSubstitutor(): TypeSubstitutorMarker + fun isReified(variable: TypeVariableMarker): Boolean } fun findResultType(c: Context, variableWithConstraints: VariableWithConstraints, direction: ResolveDirection): KotlinTypeMarker { @@ -85,6 +83,7 @@ class ResultTypeResolver( } if (!trivialConstraintTypeInferenceOracle.isSuitableResultedType(resultType)) { if (resultType.isNullableType() && checkSingleLowerNullabilityConstraint(filteredConstraints)) return false + if (isReified(variableWithConstraints.typeVariable)) return false } return true diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt index 5af7ad1f3ca..25e6fdb91d4 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/VariableFixationFinder.kt @@ -33,6 +33,7 @@ class VariableFixationFinder( interface Context : TypeSystemInferenceExtensionContext { val notFixedTypeVariables: Map val postponedTypeVariables: List + fun isReified(variable: TypeVariableMarker): Boolean } data class VariableForFixation( @@ -56,6 +57,7 @@ class VariableFixationFinder( WITH_TRIVIAL_OR_NON_PROPER_CONSTRAINTS, // proper trivial constraint from arguments, Nothing <: T RELATED_TO_ANY_OUTPUT_TYPE, READY_FOR_FIXATION, + READY_FOR_FIXATION_REIFIED, } private fun Context.getTypeVariableReadiness( @@ -68,6 +70,7 @@ class VariableFixationFinder( hasDependencyToOtherTypeVariables(variable) -> TypeVariableFixationReadiness.WITH_COMPLEX_DEPENDENCY variableHasTrivialOrNonProperConstraints(variable) -> TypeVariableFixationReadiness.WITH_TRIVIAL_OR_NON_PROPER_CONSTRAINTS dependencyProvider.isVariableRelatedToAnyOutputType(variable) -> TypeVariableFixationReadiness.RELATED_TO_ANY_OUTPUT_TYPE + isReified(variable) -> TypeVariableFixationReadiness.READY_FOR_FIXATION_REIFIED else -> TypeVariableFixationReadiness.READY_FOR_FIXATION } @@ -121,4 +124,6 @@ class VariableFixationFinder( private fun Context.isProperType(type: KotlinTypeMarker): Boolean = !type.contains { notFixedTypeVariables.containsKey(it.typeConstructor()) } + private fun Context.isReified(variable: TypeConstructorMarker): Boolean = + notFixedTypeVariables[variable]?.typeVariable?.let { isReified(it) } ?: false } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index f48df413dfe..c7ae669995c 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -341,6 +341,12 @@ class NewConstraintSystemImpl( return storage.buildNotFixedVariablesToNonSubtypableTypesSubstitutor(this) } + // ResultTypeResolver.Context, VariableFixationFinder.Context + override fun isReified(variable: TypeVariableMarker): Boolean { + if (variable !is TypeVariableFromCallableDescriptor) return false + return variable.originalTypeParameter.isReified + } + override fun bindingStubsForPostponedVariables(): Map { checkState(State.BUILDING, State.COMPLETION) // TODO: SUB diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.fir.kt b/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.fir.kt new file mode 100644 index 00000000000..31dfc9b6be5 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.fir.kt @@ -0,0 +1,53 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNREACHABLE_CODE + +interface Bound + +fun take(t: T?): T = t ?: TODO() +inline fun takeReified(t: T?): T = t ?: TODO() +inline fun takeReifiedUnbound(t: T?): T = t ?: TODO() + +fun materialize(): M = TODO() +inline fun materializeReified(): M = TODO() +inline fun materializeReifiedUnbound(): M = TODO() + +fun select(a: T, b: T): T = TODO() + +fun test1() { + take(null) +} + +fun test2() { + takeReified(null) +} + +fun test3() { + takeReifiedUnbound(null) +} + +fun test4(): Bound = takeReifiedUnbound(null) + +fun test5(): Bound? = select( + null, + materialize() +) + +fun test6() { + select( + null, + materializeReified() + ) +} + +fun test7(): Bound? = + select( + null, + materializeReifiedUnbound() + ) + +fun test8() { + select( + null, + materializeReifiedUnbound() + ) +} diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.kt b/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.kt new file mode 100644 index 00000000000..24c7d1bc089 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.kt @@ -0,0 +1,53 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNREACHABLE_CODE + +interface Bound + +fun take(t: T?): T = t ?: TODO() +inline fun takeReified(t: T?): T = t ?: TODO() +inline fun takeReifiedUnbound(t: T?): T = t ?: TODO() + +fun materialize(): M = TODO() +inline fun materializeReified(): M = TODO() +inline fun materializeReifiedUnbound(): M = TODO() + +fun select(a: T, b: T): T = TODO() + +fun test1() { + take(null) +} + +fun test2() { + takeReified(null) +} + +fun test3() { + takeReifiedUnbound(null) +} + +fun test4(): Bound = takeReifiedUnbound(null) + +fun test5(): Bound? = select( + null, + materialize() +) + +fun test6() { + select( + null, + materializeReified() + ) +} + +fun test7(): Bound? = + select( + null, + materializeReifiedUnbound() + ) + +fun test8() { + select( + null, + materializeReifiedUnbound() + ) +} diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.txt b/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.txt new file mode 100644 index 00000000000..30d6b8a7615 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.txt @@ -0,0 +1,23 @@ +package + +public fun materialize(): M +public inline fun materializeReified(): M +public inline fun materializeReifiedUnbound(): M +public fun select(/*0*/ a: T, /*1*/ b: T): T +public fun take(/*0*/ t: T?): T +public inline fun takeReified(/*0*/ t: T?): T +public inline fun takeReifiedUnbound(/*0*/ t: T?): T +public fun test1(): kotlin.Unit +public fun test2(): kotlin.Unit +public fun test3(): kotlin.Unit +public fun test4(): Bound +public fun test5(): Bound? +public fun test6(): kotlin.Unit +public fun test7(): Bound? +public fun test8(): kotlin.Unit + +public interface Bound { + 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 +} diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.fir.kt b/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.fir.kt new file mode 100644 index 00000000000..80ba65790b1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.fir.kt @@ -0,0 +1,19 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +interface ExpectedType + +inline fun parse(): M? = TODO() + +fun test(s: String?, silent: Boolean) { + val result: ExpectedType = + if (s != null) { + parse() ?: TODO() + } else if (silent) { + return + } else { + throw Exception() + } + + s.length +} diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.kt b/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.kt new file mode 100644 index 00000000000..6eb9f178a36 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.kt @@ -0,0 +1,19 @@ +// !LANGUAGE: +NewInference +// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE + +interface ExpectedType + +inline fun parse(): M? = TODO() + +fun test(s: String?, silent: Boolean) { + val result: ExpectedType = + if (s != null) { + parse() ?: TODO() + } else if (silent) { + return + } else { + throw Exception() + } + + s.length +} diff --git a/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.txt b/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.txt new file mode 100644 index 00000000000..0767cc42e1b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.txt @@ -0,0 +1,10 @@ +package + +public inline fun parse(): M? +public fun test(/*0*/ s: kotlin.String?, /*1*/ silent: kotlin.Boolean): kotlin.Unit + +public interface ExpectedType { + 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 +} diff --git a/compiler/testData/diagnostics/tests/regressions/kt32836.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt32836.fir.kt index 32a5a618f77..adbdda52fea 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt32836.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt32836.fir.kt @@ -1,5 +1,4 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// !WITH_NEW_INFERENCE inline fun parse(json: String): T? = TODO() diff --git a/compiler/testData/diagnostics/tests/regressions/kt32836.kt b/compiler/testData/diagnostics/tests/regressions/kt32836.kt index 67d09adb679..adbdda52fea 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt32836.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt32836.kt @@ -1,5 +1,4 @@ // !DIAGNOSTICS: -UNUSED_PARAMETER -// !WITH_NEW_INFERENCE inline fun parse(json: String): T? = TODO() @@ -7,7 +6,7 @@ class MyType fun parseMyData(json: String): MyType = try { - parse(json) // error with new inf only: Cannot use 'Nothing?' as reified type parameter + parse(json) // error with new inf only: Cannot use 'Nothing?' as reified type parameter ?: throw IllegalArgumentException("Can't parse") } catch (e: Exception) { throw IllegalArgumentException("Can't parse") diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 987d681d40b..a1dde9872f1 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10715,6 +10715,16 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { runTest("compiler/testData/diagnostics/tests/inference/nothingType/complexDependancyOnVariableWithTrivialConstraint.kt"); } + @TestMetadata("discriminateNothingForReifiedParameter.kt") + public void testDiscriminateNothingForReifiedParameter() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.kt"); + } + + @TestMetadata("discriminatedNothingAndSmartCast.kt") + public void testDiscriminatedNothingAndSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.kt"); + } + @TestMetadata("generateConstraintWithInnerNothingType.kt") public void testGenerateConstraintWithInnerNothingType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nothingType/generateConstraintWithInnerNothingType.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 7e9f103bbcc..40130ba333d 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10710,6 +10710,16 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing runTest("compiler/testData/diagnostics/tests/inference/nothingType/complexDependancyOnVariableWithTrivialConstraint.kt"); } + @TestMetadata("discriminateNothingForReifiedParameter.kt") + public void testDiscriminateNothingForReifiedParameter() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.kt"); + } + + @TestMetadata("discriminatedNothingAndSmartCast.kt") + public void testDiscriminatedNothingAndSmartCast() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/nothingType/discriminatedNothingAndSmartCast.kt"); + } + @TestMetadata("generateConstraintWithInnerNothingType.kt") public void testGenerateConstraintWithInnerNothingType() throws Exception { runTest("compiler/testData/diagnostics/tests/inference/nothingType/generateConstraintWithInnerNothingType.kt");