diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index 30688697540..b20bdf1722c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -265,6 +265,7 @@ public interface BindingContext { WritableSlice FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice<>(DO_NOTHING, true); WritableSlice FILE_TO_PACKAGE_FRAGMENT = Slices.createSimpleSlice(); WritableSlice> PACKAGE_TO_FILES = Slices.createSimpleSlice(); + WritableSlice CAST_TYPE_USED_AS_EXPECTED_TYPE = Slices.createSimpleSlice(); WritableSlice NEW_INFERENCE_LAMBDA_INFO = new BasicWritableSlice<>(DO_NOTHING); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt index de0a0041b0e..f5523e29483 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/GenericCandidateResolver.kt @@ -20,11 +20,16 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor +import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.FunctionDescriptorUtil import org.jetbrains.kotlin.resolve.TemporaryBindingTrace import org.jetbrains.kotlin.resolve.calls.callResolverUtil.* @@ -39,6 +44,7 @@ import org.jetbrains.kotlin.resolve.calls.context.ResolutionResultsCache import org.jetbrains.kotlin.resolve.calls.context.TemporaryTraceAndCache import org.jetbrains.kotlin.resolve.calls.inference.* import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition +import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.RECEIVER_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.VALUE_PARAMETER_POSITION import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ValidityConstraintForConstituentType @@ -53,12 +59,16 @@ import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils.ResolveConstruct import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils +import org.jetbrains.kotlin.types.typeUtil.contains +import org.jetbrains.kotlin.types.typeUtil.makeNullable +import org.jetbrains.kotlin.utils.addToStdlib.safeAs private val SPECIAL_FUNCTION_NAMES = ResolveConstruct.values().map { it.specialFunctionName }.toSet() class GenericCandidateResolver( private val argumentTypeResolver: ArgumentTypeResolver, - private val coroutineInferenceSupport: CoroutineInferenceSupport + private val coroutineInferenceSupport: CoroutineInferenceSupport, + private val languageVersionSettings: LanguageVersionSettings ) { fun inferTypeArguments(context: CallCandidateResolutionContext): ResolutionStatus { val candidateCall = context.candidateCall @@ -116,11 +126,68 @@ class GenericCandidateResolver( // Solution val hasContradiction = constraintSystem.status.hasContradiction() if (!hasContradiction) { + addExpectedTypeForExplicitCast(context, builder) return INCOMPLETE_TYPE_INFERENCE } return OTHER_ERROR } + private fun ConstraintSystem.Builder.typeInSystem(call: Call, type: KotlinType?): KotlinType? = + type?.let { + typeVariableSubstitutors[call.toHandle()]?.substitute(it, Variance.INVARIANT) + } + + private fun FunctionDescriptor.isFunctionForExpectTypeFromCastFeature(): Boolean { + val typeParameter = typeParameters.singleOrNull() ?: return false + + val returnType = returnType ?: return false + if (returnType is DeferredType && returnType.isComputing) return false + + if (returnType.constructor != typeParameter.typeConstructor) return false + + fun KotlinType.isBadType() = contains { it.constructor == typeParameter.typeConstructor } + + if (valueParameters.any { it.type.isBadType() } || extensionReceiverParameter?.type?.isBadType() == true) return false + + return true + } + + private fun addExpectedTypeForExplicitCast( + context: CallCandidateResolutionContext<*>, + builder: ConstraintSystem.Builder + ) { + if (!languageVersionSettings.supportsFeature(LanguageFeature.ExpectedTypeFromCast)) return + + if (context.candidateCall is VariableAsFunctionResolvedCall) return + + val candidateDescriptor = context.candidateCall.candidateDescriptor.safeAs() ?: return + + val binaryParent = getBinaryWithTypeParent(context.call.calleeExpression) ?: return + val operationType = binaryParent.operationReference.getReferencedNameElementType().takeIf { + it == KtTokens.AS_KEYWORD || it == KtTokens.AS_SAFE + } ?: return + + val leftType = context.trace.get(BindingContext.TYPE, binaryParent.right ?: return) ?: return + val expectedType = if (operationType == KtTokens.AS_SAFE) leftType.makeNullable() else leftType + + if (context.candidateCall.call.typeArgumentList != null || !candidateDescriptor.isFunctionForExpectTypeFromCastFeature()) return + + val typeInSystem = builder.typeInSystem(context.call, candidateDescriptor.returnType ?: return) ?: return + + context.trace.record(BindingContext.CAST_TYPE_USED_AS_EXPECTED_TYPE, binaryParent) + builder.addSubtypeConstraint(typeInSystem, expectedType, ConstraintPositionKind.SPECIAL.position()) + } + + private fun getBinaryWithTypeParent(calleeExpression: KtExpression?): KtBinaryExpressionWithTypeRHS? { + val callExpression = calleeExpression?.parent.safeAs() ?: return null + val parent = callExpression.parent + return when (parent) { + is KtBinaryExpressionWithTypeRHS -> parent + is KtQualifiedExpression -> parent.parent.safeAs().takeIf { parent.selectorExpression == callExpression } + else -> null + } + } + private fun addValidityConstraintsForConstituentTypes(builder: ConstraintSystem.Builder, type: KotlinType) { val typeConstructor = type.constructor if (typeConstructor.declarationDescriptor is TypeParameterDescriptor) return diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index 890fff4eae4..3e53cd209d8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -366,6 +366,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { ) { if (actualType == null || noExpectedType(targetType) || KotlinTypeKt.isError(targetType)) return; + if (Boolean.TRUE.equals(context.trace.get(BindingContext.CAST_TYPE_USED_AS_EXPECTED_TYPE, expression))) return; + if (DynamicTypesKt.isDynamic(targetType)) { KtTypeReference right = expression.getRight(); assert right != null : "We know target is dynamic, but RHS is missing"; diff --git a/compiler/testData/codegen/box/reified/expectedTypeFromCast.kt b/compiler/testData/codegen/box/reified/expectedTypeFromCast.kt new file mode 100644 index 00000000000..d77cad0dcd6 --- /dev/null +++ b/compiler/testData/codegen/box/reified/expectedTypeFromCast.kt @@ -0,0 +1,19 @@ +// IGNORE_BACKEND: JS, NATIVE + +// LANGUAGE_VERSION: 1.2 +// WITH_RUNTIME +import kotlin.test.assertEquals + +inline fun foo(): T { + return T::class.java.getName() as T +} + +fun box(): String { + val fooCall = foo() as String + assertEquals("java.lang.String", fooCall) + + val safeFooCall = foo() as? String + assertEquals("java.lang.String", safeFooCall) + + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.kt b/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.kt new file mode 100644 index 00000000000..e125bc93a36 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.kt @@ -0,0 +1,12 @@ +// !LANGUAGE: +ExpectedTypeFromCast + +fun foo() = 1 + +fun foo() = foo() as T + +fun foo2(): T = TODO() + +val test = foo2().plus("") as String + +fun T.bar() = this +val barTest = "".bar() as Number \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.txt b/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.txt new file mode 100644 index 00000000000..ae1f849e82e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.txt @@ -0,0 +1,8 @@ +package + +public val barTest: kotlin.Number +public val test: kotlin.String +public fun foo(): kotlin.Int +public fun foo(): T +public fun foo2(): T +public fun T.bar(): T diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.kt b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.kt new file mode 100644 index 00000000000..f10da90f086 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.kt @@ -0,0 +1,20 @@ +// !LANGUAGE: +ExpectedTypeFromCast + +fun foo(): T = TODO() + +fun id(value: V) = value + +val asString = foo() as String + +val viaId = id(foo()) as String + +val insideId = id(foo() as String) + +val asList = foo() as List + +val asStarList = foo() as List<*> + +val safeAs = foo() as? String + +val fromIs = foo() is String +val fromNoIs = foo() !is String diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.txt b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.txt new file mode 100644 index 00000000000..a0dc51a529e --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.txt @@ -0,0 +1,12 @@ +package + +public val asList: kotlin.collections.List +public val asStarList: kotlin.collections.List<*> +public val asString: kotlin.String +public val fromIs: kotlin.Boolean +public val fromNoIs: kotlin.Boolean +public val insideId: kotlin.String +public val safeAs: kotlin.String? +public val viaId: kotlin.String +public fun foo(): T +public fun id(/*0*/ value: V): V diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeFromCastComplexExpression.kt b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCastComplexExpression.kt new file mode 100644 index 00000000000..ce51ae98727 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCastComplexExpression.kt @@ -0,0 +1,16 @@ +// !LANGUAGE: +ExpectedTypeFromCast + +package pp + +class A { + fun foo(): T = TODO() + + companion object { + fun foo2(): T = TODO() + } +} + +val x = A().foo() as String +val y = A.foo2() as String +val z = pp.A.foo2() as String + diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeFromCastComplexExpression.txt b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCastComplexExpression.txt new file mode 100644 index 00000000000..2abb45263d0 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeFromCastComplexExpression.txt @@ -0,0 +1,23 @@ +package + +package pp { + public val x: kotlin.String + public val y: kotlin.String + public val z: kotlin.String + + public final class A { + public constructor A() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): T + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public companion object Companion { + private constructor Companion() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo2(): T + 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/expectedTypeWithGenerics.kt b/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.kt new file mode 100644 index 00000000000..ed23efe4353 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.kt @@ -0,0 +1,17 @@ +// !LANGUAGE: +ExpectedTypeFromCast + +class X { + fun foo(): T = TODO() +} + +fun test(x: X) { + val y = x.foo() as Int +} + +fun g() { + fun foo(): T = TODO() + + val y = foo() as Int + + val y2 = foo() as D +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.txt b/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.txt new file mode 100644 index 00000000000..dfa466d8b69 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.txt @@ -0,0 +1,12 @@ +package + +public fun g(): kotlin.Unit +public fun test(/*0*/ x: X): kotlin.Unit + +public final class X { + public constructor X() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public final fun foo(): T + 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/findViewById.kt b/compiler/testData/diagnostics/tests/inference/findViewById.kt new file mode 100644 index 00000000000..3ab2d546c51 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/findViewById.kt @@ -0,0 +1,58 @@ +// !LANGUAGE: +ExpectedTypeFromCast +// !DIAGNOSTICS: -UNUSED_VARIABLE -DEBUG_INFO_LEAKING_THIS + +// FILE: a/View.java +package a; + +public class View { + +} + +// FILE: a/Test.java +package a; + +public class Test { + public T findViewById(int id); +} + +// FILE: 1.kt +package a + + +class X : View() + +class Y : View() + +val xExplicit: X = Test().findViewById(0) +val xCast = Test().findViewById(0) as X + +val xCastExplicitType = Test().findViewById(0) as X +val xSafeCastExplicitType = Test().findViewById(0) as? X + +val yExplicit: Y = Test().findViewById(0) +val yCast = Test().findViewById(0) as Y + + +class TestChild : Test() { + val xExplicit: X = findViewById(0) + val xCast = findViewById(0) as X + + val yExplicit: Y = findViewById(0) + val yCast = findViewById(0) as Y +} + +fun test(t: Test) { + val xExplicit: X = t.findViewById(0) + val xCast = t.findViewById(0) as X + + val yExplicit: Y = t.findViewById(0) + val yCast = t.findViewById(0) as Y +} + +fun test2(t: Test?) { + val xSafeCallSafeCast = t?.findViewById(0) as? X + val xSafeCallSafeCastExplicitType = t?.findViewById(0) as? X + + val xSafeCallCast = t?.findViewById(0) as X + val xSafeCallCastExplicitType = t?.findViewById(0) as X +} diff --git a/compiler/testData/diagnostics/tests/inference/findViewById.txt b/compiler/testData/diagnostics/tests/inference/findViewById.txt new file mode 100644 index 00000000000..ce585746f3a --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/findViewById.txt @@ -0,0 +1,53 @@ +package + +package a { + public val xCast: a.X + public val xCastExplicitType: a.X + public val xExplicit: a.X + public val xSafeCastExplicitType: a.X? + public val yCast: a.Y + public val yExplicit: a.Y + public fun test(/*0*/ t: a.Test): kotlin.Unit + public fun test2(/*0*/ t: a.Test?): kotlin.Unit + + public open class Test { + public constructor Test() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open fun findViewById(/*0*/ id: kotlin.Int): T! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public final class TestChild : a.Test { + public constructor TestChild() + public final val xCast: a.X + public final val xExplicit: a.X + public final val yCast: a.Y + public final val yExplicit: a.Y + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun findViewById(/*0*/ id: kotlin.Int): T! + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + public open class View { + public constructor View() + 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 X : a.View { + public constructor X() + 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 Y : a.View { + public constructor Y() + 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/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 181e885dd11..a7b05b01101 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -17825,6 +17825,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes doTest(fileName); } + @TestMetadata("expectedTypeFromCast.kt") + public void testExpectedTypeFromCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reified/expectedTypeFromCast.kt"); + doTest(fileName); + } + @TestMetadata("filterIsInstance.kt") public void testFilterIsInstance() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reified/filterIsInstance.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 2c8dd3fe2a2..c3c9a074f17 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -10222,6 +10222,36 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("expectedTypeAdditionalTest.kt") + public void testExpectedTypeAdditionalTest() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.kt"); + doTest(fileName); + } + + @TestMetadata("expectedTypeFromCast.kt") + public void testExpectedTypeFromCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.kt"); + doTest(fileName); + } + + @TestMetadata("expectedTypeFromCastComplexExpression.kt") + public void testExpectedTypeFromCastComplexExpression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/expectedTypeFromCastComplexExpression.kt"); + doTest(fileName); + } + + @TestMetadata("expectedTypeWithGenerics.kt") + public void testExpectedTypeWithGenerics() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.kt"); + doTest(fileName); + } + + @TestMetadata("findViewById.kt") + public void testFindViewById() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/findViewById.kt"); + doTest(fileName); + } + @TestMetadata("fixVariableToNothing.kt") public void testFixVariableToNothing() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/fixVariableToNothing.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index 13d3a24ea8f..f2c09ef6f15 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -10222,6 +10222,36 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing doTest(fileName); } + @TestMetadata("expectedTypeAdditionalTest.kt") + public void testExpectedTypeAdditionalTest() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/expectedTypeAdditionalTest.kt"); + doTest(fileName); + } + + @TestMetadata("expectedTypeFromCast.kt") + public void testExpectedTypeFromCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/expectedTypeFromCast.kt"); + doTest(fileName); + } + + @TestMetadata("expectedTypeFromCastComplexExpression.kt") + public void testExpectedTypeFromCastComplexExpression() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/expectedTypeFromCastComplexExpression.kt"); + doTest(fileName); + } + + @TestMetadata("expectedTypeWithGenerics.kt") + public void testExpectedTypeWithGenerics() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/expectedTypeWithGenerics.kt"); + doTest(fileName); + } + + @TestMetadata("findViewById.kt") + public void testFindViewById() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/findViewById.kt"); + doTest(fileName); + } + @TestMetadata("fixVariableToNothing.kt") public void testFixVariableToNothing() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inference/fixVariableToNothing.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index b303967aa7d..768b2eecaf7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -17825,6 +17825,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("expectedTypeFromCast.kt") + public void testExpectedTypeFromCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reified/expectedTypeFromCast.kt"); + doTest(fileName); + } + @TestMetadata("filterIsInstance.kt") public void testFilterIsInstance() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reified/filterIsInstance.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index e0b711d95c9..0e9c198cfd3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -17825,6 +17825,12 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes doTest(fileName); } + @TestMetadata("expectedTypeFromCast.kt") + public void testExpectedTypeFromCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reified/expectedTypeFromCast.kt"); + doTest(fileName); + } + @TestMetadata("filterIsInstance.kt") public void testFilterIsInstance() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reified/filterIsInstance.kt"); diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 3c451aebf76..5eddb04f4df 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -64,6 +64,7 @@ enum class LanguageFeature( ThrowNpeOnExplicitEqualsForBoxedNull(KOTLIN_1_2), JvmPackageName(KOTLIN_1_2), AssigningArraysToVarargsInNamedFormInAnnotations(KOTLIN_1_2), + ExpectedTypeFromCast(KOTLIN_1_2), ReturnsEffect(KOTLIN_1_3), CallsInPlaceEffect(KOTLIN_1_3), diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index dc65021acb4..34094a5815a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -21401,6 +21401,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); } + @TestMetadata("expectedTypeFromCast.kt") + public void testExpectedTypeFromCast() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reified/expectedTypeFromCast.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + @TestMetadata("filterIsInstance.kt") public void testFilterIsInstance() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reified/filterIsInstance.kt");