Fix for KT-10313: ClassCastException with Generics
#KT-10313 Fixed
This commit is contained in:
committed by
Michael Bogdanov
parent
edf6a2142b
commit
0073257841
@@ -1242,12 +1242,21 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Nullable
|
||||
public static ConstantValue<?> getCompileTimeConstant(@NotNull KtExpression expression, @NotNull BindingContext bindingContext) {
|
||||
return getCompileTimeConstant(expression, bindingContext, false);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static ConstantValue<?> getCompileTimeConstant(
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull BindingContext bindingContext,
|
||||
boolean checkPure
|
||||
) {
|
||||
CompileTimeConstant<?> compileTimeValue = ConstantExpressionEvaluator.getConstant(expression, bindingContext);
|
||||
if (compileTimeValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (compileTimeValue.getUsesNonConstValAsConstant()) return null;
|
||||
if (compileTimeValue.getUsesNonConstValAsConstant() || (checkPure && !compileTimeValue.getParameters().isPure())) return null;
|
||||
|
||||
KotlinType expectedType = bindingContext.getType(expression);
|
||||
return compileTimeValue.toConstantValue(expectedType);
|
||||
@@ -2893,6 +2902,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
expression.getRight(), reference);
|
||||
}
|
||||
else {
|
||||
ConstantValue<?> compileTimeConstant = getCompileTimeConstant(expression, bindingContext, true);
|
||||
if (compileTimeConstant != null) {
|
||||
return StackValue.constant(compileTimeConstant.getValue(), expressionType(expression));
|
||||
}
|
||||
|
||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(expression, bindingContext);
|
||||
FunctionDescriptor descriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
||||
|
||||
@@ -3165,6 +3179,11 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
|
||||
@Override
|
||||
public StackValue visitPrefixExpression(@NotNull KtPrefixExpression expression, @NotNull StackValue receiver) {
|
||||
ConstantValue<?> compileTimeConstant = getCompileTimeConstant(expression, bindingContext, true);
|
||||
if (compileTimeConstant != null) {
|
||||
return StackValue.constant(compileTimeConstant.getValue(), expressionType(expression));
|
||||
}
|
||||
|
||||
DeclarationDescriptor originalOperation = bindingContext.get(REFERENCE_TARGET, expression.getOperationReference());
|
||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCallWithAssert(expression, bindingContext);
|
||||
CallableDescriptor op = resolvedCall.getResultingDescriptor();
|
||||
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
class Box<T>(val value: T)
|
||||
|
||||
fun box() : String {
|
||||
val b = Box<Long>(2 * 3)
|
||||
val expected: Long? = 6L
|
||||
return if (b.value == expected) "OK" else "fail"
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
class Box<T>(val value: T)
|
||||
|
||||
fun box() : String {
|
||||
val b = Box<Long>(x@ (1 + 2))
|
||||
val expected: Long? = 3L
|
||||
return if (b.value == expected) "OK" else "fail"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
class Box<T>(val value: T)
|
||||
|
||||
fun box() : String {
|
||||
val b = Box<Long>((-1))
|
||||
val expected: Long? = -1L
|
||||
return if (b.value == expected) "OK" else "fail"
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
open class Base<T>(val value: T)
|
||||
class Box(): Base<Long>(-1)
|
||||
|
||||
fun box(): String {
|
||||
val expected: Long? = -1L
|
||||
return if (Box().value == expected) "OK" else "fail"
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
class Box<T>(val value: T)
|
||||
|
||||
fun box() : String {
|
||||
val b = Box<Long>(-1)
|
||||
val expected: Long? = -1L
|
||||
return if (b.value == expected) "OK" else "fail"
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
class Box<T>(val value: T)
|
||||
|
||||
fun <T> run(vararg z: T): Box<T> {
|
||||
return Box<T>(z[0])
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val b = run<Long>(-1, -1, -1)
|
||||
val expected: Long? = -1L
|
||||
return if (b.value == expected) "OK" else "fail"
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
public class Box<T> {
|
||||
private final T value;
|
||||
|
||||
public Box(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public static <T> Box<T> create(T defaultValue) {
|
||||
return new Box(defaultValue);
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
fun box(): String {
|
||||
val sub = Box<Long>(-1)
|
||||
return if (sub.value == -1L) "OK" else "fail"
|
||||
}
|
||||
+4
-1
@@ -1,5 +1,8 @@
|
||||
const val one = 1
|
||||
const val two = 2
|
||||
|
||||
fun test1() {
|
||||
if (!(1 < 2)) {
|
||||
if (!(one < two)) {
|
||||
val p = 1
|
||||
}
|
||||
}
|
||||
|
||||
+45
@@ -987,6 +987,51 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/casts/unitNullableCast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class LiteralExpressionAsGenericArgument extends AbstractBlackBoxCodegenTest {
|
||||
public void testAllFilesPresentInLiteralExpressionAsGenericArgument() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("binaryExpressionCast.kt")
|
||||
public void testBinaryExpressionCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/binaryExpressionCast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("labeledExpressionCast.kt")
|
||||
public void testLabeledExpressionCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/labeledExpressionCast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("parenthesizedExpressionCast.kt")
|
||||
public void testParenthesizedExpressionCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/parenthesizedExpressionCast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("superConstructor.kt")
|
||||
public void testSuperConstructor() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/superConstructor.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("unaryExpressionCast.kt")
|
||||
public void testUnaryExpressionCast() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/unaryExpressionCast.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("vararg.kt")
|
||||
public void testVararg() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/casts/literalExpressionAsGenericArgument/vararg.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/classes")
|
||||
|
||||
+6
@@ -241,6 +241,12 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege
|
||||
doTestWithJava(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("literalExpressionAsGenericArgument")
|
||||
public void testLiteralExpressionAsGenericArgument() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxWithJava/casts/literalExpressionAsGenericArgument/");
|
||||
doTestWithJava(fileName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/boxWithJava/collections")
|
||||
|
||||
Reference in New Issue
Block a user