[NI] discriminate Nothing for reified parameters
Related issues: KT-32836, KT-35728
This commit is contained in:
Generated
+10
@@ -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");
|
||||
|
||||
+3
-4
@@ -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
|
||||
|
||||
+5
@@ -33,6 +33,7 @@ class VariableFixationFinder(
|
||||
interface Context : TypeSystemInferenceExtensionContext {
|
||||
val notFixedTypeVariables: Map<TypeConstructorMarker, VariableWithConstraints>
|
||||
val postponedTypeVariables: List<TypeVariableMarker>
|
||||
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
|
||||
}
|
||||
+6
@@ -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<TypeVariableMarker, StubTypeMarker> {
|
||||
checkState(State.BUILDING, State.COMPLETION)
|
||||
// TODO: SUB
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNREACHABLE_CODE
|
||||
|
||||
interface Bound
|
||||
|
||||
fun <T : Bound> take(t: T?): T = t ?: TODO()
|
||||
inline fun <reified T : Bound> takeReified(t: T?): T = t ?: TODO()
|
||||
inline fun <reified T> takeReifiedUnbound(t: T?): T = t ?: TODO()
|
||||
|
||||
fun <M : Bound> materialize(): M = TODO()
|
||||
inline fun <reified M : Bound> materializeReified(): M = TODO()
|
||||
inline fun <reified M> materializeReifiedUnbound(): M = TODO()
|
||||
|
||||
fun <T> 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()
|
||||
)
|
||||
}
|
||||
Vendored
+53
@@ -0,0 +1,53 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNREACHABLE_CODE
|
||||
|
||||
interface Bound
|
||||
|
||||
fun <T : Bound> take(t: T?): T = t ?: TODO()
|
||||
inline fun <reified T : Bound> takeReified(t: T?): T = t ?: TODO()
|
||||
inline fun <reified T> takeReifiedUnbound(t: T?): T = t ?: TODO()
|
||||
|
||||
fun <M : Bound> materialize(): M = TODO()
|
||||
inline fun <reified M : Bound> materializeReified(): M = TODO()
|
||||
inline fun <reified M> materializeReifiedUnbound(): M = TODO()
|
||||
|
||||
fun <T> select(a: T, b: T): T = TODO()
|
||||
|
||||
fun test1() {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!><!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>take<!>(null)<!>
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Bound")!>takeReified(null)<!>
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>takeReifiedUnbound<!>(null)
|
||||
}
|
||||
|
||||
fun test4(): Bound = <!DEBUG_INFO_EXPRESSION_TYPE("Bound")!>takeReifiedUnbound(null)<!>
|
||||
|
||||
fun test5(): Bound? = select(
|
||||
null,
|
||||
<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>materialize<!>()
|
||||
)
|
||||
|
||||
fun test6() {
|
||||
select(
|
||||
null,
|
||||
<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, IMPLICIT_NOTHING_AS_TYPE_PARAMETER, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>materializeReified<!>()
|
||||
)
|
||||
}
|
||||
|
||||
fun test7(): Bound? =
|
||||
select(
|
||||
null,
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Bound?")!>materializeReifiedUnbound()<!>
|
||||
)
|
||||
|
||||
fun test8() {
|
||||
select(
|
||||
null,
|
||||
<!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>materializeReifiedUnbound<!>()
|
||||
)
|
||||
}
|
||||
compiler/testData/diagnostics/tests/inference/nothingType/discriminateNothingForReifiedParameter.txt
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ M : Bound> materialize(): M
|
||||
public inline fun </*0*/ reified M : Bound> materializeReified(): M
|
||||
public inline fun </*0*/ reified M> materializeReifiedUnbound(): M
|
||||
public fun </*0*/ T> select(/*0*/ a: T, /*1*/ b: T): T
|
||||
public fun </*0*/ T : Bound> take(/*0*/ t: T?): T
|
||||
public inline fun </*0*/ reified T : Bound> takeReified(/*0*/ t: T?): T
|
||||
public inline fun </*0*/ reified T> 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
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
|
||||
interface ExpectedType
|
||||
|
||||
inline fun <reified M> 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.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
}
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
|
||||
|
||||
interface ExpectedType
|
||||
|
||||
inline fun <reified M> parse(): M? = TODO()
|
||||
|
||||
fun test(s: String?, silent: Boolean) {
|
||||
val result: ExpectedType =
|
||||
if (s != null) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("ExpectedType?")!>parse()<!> ?: TODO()
|
||||
} else <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>if (silent) {
|
||||
return
|
||||
} else {
|
||||
throw Exception()
|
||||
}<!>
|
||||
|
||||
<!DEBUG_INFO_SMARTCAST!>s<!>.length
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
package
|
||||
|
||||
public inline fun </*0*/ reified M> 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
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !WITH_NEW_INFERENCE
|
||||
|
||||
inline fun <reified T> parse(json: String): T? = TODO()
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !WITH_NEW_INFERENCE
|
||||
|
||||
inline fun <reified T> parse(json: String): T? = TODO()
|
||||
|
||||
@@ -7,7 +6,7 @@ class MyType
|
||||
|
||||
fun parseMyData(json: String): MyType =
|
||||
try {
|
||||
<!NI;REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, NI;REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>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")
|
||||
|
||||
@@ -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");
|
||||
|
||||
Generated
+10
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user