Use flexible upper bound of parameter's type for vararg argument
See the issue and the test. The problem was that when generating call to `foo` method in member scope of `AT<*>` its resulting descriptor after substitution and approximation was: fun foo(x: Nothing..Array<out Nothing>). This signature is correct, but when using this parameter type for generating a vararg argument the assertion is violated that the type of the argument must be an array (by default we're using lower flexible bound everywhere) The solution is using upper bound for flexible types that should always have a form of Array<out T> for varargs (even for such corner cases) both for Kotlin and Java declarations. #KT-14607 Fixed
This commit is contained in:
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
|
||||
import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.ValueArgument;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*;
|
||||
import org.jetbrains.kotlin.types.FlexibleTypesKt;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.List;
|
||||
@@ -84,7 +85,9 @@ public class CallBasedArgumentGenerator extends ArgumentGenerator {
|
||||
protected void generateVararg(int i, @NotNull VarargValueArgument argument) {
|
||||
ValueParameterDescriptor parameter = valueParameters.get(i);
|
||||
Type type = valueParameterTypes.get(i);
|
||||
codegen.genVarargs(argument, parameter.getType());
|
||||
// Upper bound for type of vararg parameter should always have a form of 'Array<out T>',
|
||||
// while its lower bound may be Nothing-typed after approximation
|
||||
codegen.genVarargs(argument, FlexibleTypesKt.upperIfFlexible(parameter.getType()));
|
||||
callGenerator.afterParameterPut(type, null, i);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// FILE: AT.java
|
||||
|
||||
public class AT<G> {
|
||||
public String result = "fail";
|
||||
public void foo(G ...y) {
|
||||
result = "OK";
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun AT<*>.bar() {
|
||||
foo()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val a = AT<String>()
|
||||
a.bar()
|
||||
return a.result
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
@kotlin.Metadata
|
||||
public final class MainKt {
|
||||
public final static method bar(@org.jetbrains.annotations.NotNull p0: AT): void
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
}
|
||||
+6
@@ -617,6 +617,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargsWithJava.kt")
|
||||
public void testVarargsWithJava() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/varargsWithJava.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/arrays/multiDecl")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -617,6 +617,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargsWithJava.kt")
|
||||
public void testVarargsWithJava() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/varargsWithJava.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/arrays/multiDecl")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -809,6 +809,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("varargsWithJava.kt")
|
||||
public void testVarargsWithJava() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/arrays/varargsWithJava.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/arrays/multiDecl")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user