Don't look at raw type's arguments while enhancing super types
^KT-48172 Fixed
This commit is contained in:
committed by
TeamCityServer
parent
63cefe228d
commit
d730db094a
+18
@@ -1350,6 +1350,11 @@ public class IncrementalFirJvmCompilerRunnerTestGenerated extends AbstractIncrem
|
||||
runTest("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
|
||||
}
|
||||
|
||||
@TestMetadata("rawErrorTypeDuringSerialization")
|
||||
public void testRawErrorTypeDuringSerialization() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeFieldType")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -1597,6 +1602,19 @@ public class IncrementalFirJvmCompilerRunnerTestGenerated extends AbstractIncrem
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class RawErrorTypeDuringSerialization extends AbstractIncrementalFirJvmCompilerRunnerTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInRawErrorTypeDuringSerialization() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+18
@@ -1350,6 +1350,11 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
||||
runTest("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
|
||||
}
|
||||
|
||||
@TestMetadata("rawErrorTypeDuringSerialization")
|
||||
public void testRawErrorTypeDuringSerialization() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeFieldType")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -1597,6 +1602,19 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class RawErrorTypeDuringSerialization extends AbstractIncrementalJvmCompilerRunnerTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInRawErrorTypeDuringSerialization() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+18
@@ -1350,6 +1350,11 @@ public class IncrementalJvmOldBackendCompilerRunnerTestGenerated extends Abstrac
|
||||
runTest("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
|
||||
}
|
||||
|
||||
@TestMetadata("rawErrorTypeDuringSerialization")
|
||||
public void testRawErrorTypeDuringSerialization() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeFieldType")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -1597,6 +1602,19 @@ public class IncrementalJvmOldBackendCompilerRunnerTestGenerated extends Abstrac
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class RawErrorTypeDuringSerialization extends AbstractIncrementalJvmOldBackendCompilerRunnerTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInRawErrorTypeDuringSerialization() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/rawErrorTypeDuringSerialization"), Pattern.compile("^([^\\.]+)$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/samConversions")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@ package test
|
||||
public open class RawSuperTypeWithRecursiveBound {
|
||||
public constructor RawSuperTypeWithRecursiveBound()
|
||||
|
||||
public open inner class Derived : test.RawSuperTypeWithRecursiveBound.Super<(raw) *> {
|
||||
public open inner class Derived : test.RawSuperTypeWithRecursiveBound.Super<(raw) test.RawSuperTypeWithRecursiveBound.Super<*>!> {
|
||||
public constructor Derived()
|
||||
public open override /*1*/ fun dummy(): kotlin.Unit
|
||||
public open fun foo(/*0*/ p0: kotlin.Any!): kotlin.Unit
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ package test
|
||||
public open class RawSuperTypeWithRecursiveBoundMultipleParameters {
|
||||
public constructor RawSuperTypeWithRecursiveBoundMultipleParameters()
|
||||
|
||||
public open inner class Derived : test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<(raw) kotlin.Any!, (raw) *> {
|
||||
public open inner class Derived : test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<(raw) kotlin.Any!, (raw) test.RawSuperTypeWithRecursiveBoundMultipleParameters.Super<*, *>!> {
|
||||
public constructor Derived()
|
||||
public open override /*1*/ fun dummy(): kotlin.Unit
|
||||
public open fun foo(/*0*/ p0: kotlin.Any!, /*1*/ p1: kotlin.Any!): kotlin.Unit
|
||||
|
||||
+18
-6
@@ -252,7 +252,10 @@ class SignatureEnhancement(
|
||||
* class A extends B<@NotNull Integer> {}
|
||||
*/
|
||||
fun enhanceSuperType(type: KotlinType, context: LazyJavaResolverContext) =
|
||||
SignatureParts(null, type, emptyList(), false, context, AnnotationQualifierApplicabilityType.TYPE_USE).enhance().type
|
||||
SignatureParts(
|
||||
typeContainer = null, type, emptyList(), isCovariant = false,
|
||||
context, AnnotationQualifierApplicabilityType.TYPE_USE, isSuperTypesEnhancement = true
|
||||
).enhance().type
|
||||
|
||||
private inner class SignatureParts(
|
||||
private val typeContainer: Annotated?,
|
||||
@@ -261,7 +264,8 @@ class SignatureEnhancement(
|
||||
private val isCovariant: Boolean,
|
||||
private val containerContext: LazyJavaResolverContext,
|
||||
private val containerApplicabilityType: AnnotationQualifierApplicabilityType,
|
||||
private val typeParameterBounds: Boolean = false
|
||||
private val typeParameterBounds: Boolean = false,
|
||||
private val isSuperTypesEnhancement: Boolean = false
|
||||
) {
|
||||
|
||||
private val isForVarargParameter get() = typeContainer.safeAs<ValueParameterDescriptor>()?.varargElementType != null
|
||||
@@ -275,15 +279,21 @@ class SignatureEnhancement(
|
||||
}
|
||||
}
|
||||
|
||||
val containsFunctionN = TypeUtils.contains(fromOverride) {
|
||||
val classifier = it.constructor.declarationDescriptor ?: return@contains false
|
||||
fun containsFunctionN(type: UnwrappedType): Boolean {
|
||||
val classifier = type.constructor.declarationDescriptor ?: return false
|
||||
|
||||
classifier.name == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME.shortName() &&
|
||||
return classifier.name == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME.shortName() &&
|
||||
classifier.fqNameOrNull() == JavaToKotlinClassMap.FUNCTION_N_FQ_NAME
|
||||
}
|
||||
|
||||
val containsFunctionN = if (isSuperTypesEnhancement) {
|
||||
TypeUtils.containsStoppingAt(fromOverride, ::containsFunctionN) { it is RawType }
|
||||
} else {
|
||||
TypeUtils.contains(fromOverride, ::containsFunctionN)
|
||||
}
|
||||
|
||||
return with(typeEnhancement) {
|
||||
fromOverride.enhance(qualifiersWithPredefined ?: qualifiers)?.let { enhanced ->
|
||||
fromOverride.enhance(qualifiersWithPredefined ?: qualifiers, isSuperTypesEnhancement)?.let { enhanced ->
|
||||
PartEnhancementResult(enhanced, wereChanges = true, containsFunctionN = containsFunctionN)
|
||||
} ?: PartEnhancementResult(fromOverride, wereChanges = false, containsFunctionN = containsFunctionN)
|
||||
}
|
||||
@@ -531,6 +541,8 @@ class SignatureEnhancement(
|
||||
)
|
||||
)
|
||||
|
||||
if (isSuperTypesEnhancement && type is RawType) return
|
||||
|
||||
for ((arg, parameter) in type.arguments.zip(type.constructor.parameters)) {
|
||||
if (arg.isStarProjection) {
|
||||
// TODO: sort out how to handle wildcards
|
||||
|
||||
+37
-20
@@ -52,15 +52,24 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
||||
// Example: for `A<B, C<D, E>>`, indices go as follows: `0 - A<...>, 1 - B, 2 - C<D, E>, 3 - D, 4 - E`,
|
||||
// which corresponds to the left-to-right breadth-first walk of the tree representation of the type.
|
||||
// For flexible types, both bounds are indexed in the same way: `(A<B>..C<D>)` gives `0 - (A<B>..C<D>), 1 - B and D`.
|
||||
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers) = unwrap().enhancePossiblyFlexible(qualifiers, 0).type
|
||||
fun KotlinType.enhance(qualifiers: (Int) -> JavaTypeQualifiers, isSuperTypesEnhancement: Boolean = false) =
|
||||
unwrap().enhancePossiblyFlexible(qualifiers, 0, isSuperTypesEnhancement).type
|
||||
|
||||
private fun UnwrappedType.enhancePossiblyFlexible(qualifiers: (Int) -> JavaTypeQualifiers, index: Int): Result {
|
||||
private fun UnwrappedType.enhancePossiblyFlexible(
|
||||
qualifiers: (Int) -> JavaTypeQualifiers,
|
||||
index: Int,
|
||||
isSuperTypesEnhancement: Boolean = false
|
||||
): Result {
|
||||
if (isError) return Result(null, 1)
|
||||
return when (this) {
|
||||
is FlexibleType -> {
|
||||
val isRawType = this is RawType
|
||||
val lowerResult = lowerBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER, isRawType)
|
||||
val upperResult = upperBound.enhanceInflexible(qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER, isRawType)
|
||||
val lowerResult = lowerBound.enhanceInflexible(
|
||||
qualifiers, index, TypeComponentPosition.FLEXIBLE_LOWER, isRawType, isSuperTypesEnhancement
|
||||
)
|
||||
val upperResult = upperBound.enhanceInflexible(
|
||||
qualifiers, index, TypeComponentPosition.FLEXIBLE_UPPER, isRawType, isSuperTypesEnhancement
|
||||
)
|
||||
assert(lowerResult.subtreeSize == upperResult.subtreeSize) {
|
||||
"Different tree sizes of bounds: " +
|
||||
"lower = ($lowerBound, ${lowerResult.subtreeSize}), " +
|
||||
@@ -80,7 +89,9 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
||||
Result(type, lowerResult.subtreeSize)
|
||||
}
|
||||
is SimpleType -> {
|
||||
val result = enhanceInflexible(qualifiers, index, TypeComponentPosition.INFLEXIBLE)
|
||||
val result = enhanceInflexible(
|
||||
qualifiers, index, TypeComponentPosition.INFLEXIBLE, isSuperTypesEnhancement = isSuperTypesEnhancement
|
||||
)
|
||||
Result(if (result.forWarnings) wrapEnhancement(result.type) else result.type, result.subtreeSize)
|
||||
}
|
||||
}
|
||||
@@ -90,7 +101,8 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
||||
qualifiers: (Int) -> JavaTypeQualifiers,
|
||||
index: Int,
|
||||
position: TypeComponentPosition,
|
||||
isBoundOfRawType: Boolean = false
|
||||
isBoundOfRawType: Boolean = false,
|
||||
isSuperTypesEnhancement: Boolean = false
|
||||
): SimpleResult {
|
||||
val shouldEnhance = position.shouldEnhance()
|
||||
if (!shouldEnhance && arguments.isEmpty()) return SimpleResult(null, 1, false)
|
||||
@@ -105,24 +117,29 @@ class JavaTypeEnhancement(private val javaResolverSettings: JavaResolverSettings
|
||||
|
||||
var globalArgIndex = index + 1
|
||||
var wereChanges = enhancedMutabilityAnnotations != null
|
||||
val enhancedArguments = arguments.mapIndexed { localArgIndex, arg ->
|
||||
if (arg.isStarProjection) {
|
||||
val qualifiersForStarProjection = qualifiers(globalArgIndex)
|
||||
globalArgIndex++
|
||||
val enhancedArguments = if (!isSuperTypesEnhancement || !isBoundOfRawType) {
|
||||
arguments.mapIndexed { localArgIndex, arg ->
|
||||
if (arg.isStarProjection) {
|
||||
val qualifiersForStarProjection = qualifiers(globalArgIndex)
|
||||
globalArgIndex++
|
||||
|
||||
if (qualifiersForStarProjection.nullability == NOT_NULL && !isBoundOfRawType) {
|
||||
val enhanced = arg.type.unwrap().makeNotNullable()
|
||||
createProjection(enhanced, arg.projectionKind, typeParameterDescriptor = typeConstructor.parameters[localArgIndex])
|
||||
if (qualifiersForStarProjection.nullability == NOT_NULL && !isBoundOfRawType) {
|
||||
val enhanced = arg.type.unwrap().makeNotNullable()
|
||||
createProjection(enhanced, arg.projectionKind, typeParameterDescriptor = typeConstructor.parameters[localArgIndex])
|
||||
} else {
|
||||
TypeUtils.makeStarProjection(enhancedClassifier.typeConstructor.parameters[localArgIndex])
|
||||
}
|
||||
} else {
|
||||
TypeUtils.makeStarProjection(enhancedClassifier.typeConstructor.parameters[localArgIndex])
|
||||
}
|
||||
} else {
|
||||
val unwrapped = arg.type.unwrap()
|
||||
val enhanced = unwrapped.enhancePossiblyFlexible(qualifiers, globalArgIndex)
|
||||
globalArgIndex += enhanced.subtreeSize
|
||||
val type = enhanced.type?.also { wereChanges = true } ?: unwrapped
|
||||
val unwrapped = arg.type.unwrap()
|
||||
val enhanced = unwrapped.enhancePossiblyFlexible(qualifiers, globalArgIndex, isSuperTypesEnhancement)
|
||||
globalArgIndex += enhanced.subtreeSize
|
||||
val type = enhanced.type?.also { wereChanges = true } ?: unwrapped
|
||||
createProjection(type, arg.projectionKind, typeParameterDescriptor = typeConstructor.parameters[localArgIndex])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
globalArgIndex += arguments.size
|
||||
arguments
|
||||
}
|
||||
|
||||
val (enhancedNullability, enhancedNullabilityAnnotations) = this.getEnhancedNullability(effectiveQualifiers, position)
|
||||
|
||||
@@ -425,12 +425,21 @@ public class TypeUtils {
|
||||
@Nullable KotlinType type,
|
||||
@NotNull Function1<UnwrappedType, Boolean> isSpecialType
|
||||
) {
|
||||
return contains(type, isSpecialType, null);
|
||||
return contains(type, isSpecialType, null, null);
|
||||
}
|
||||
|
||||
public static boolean containsStoppingAt(
|
||||
@Nullable KotlinType type,
|
||||
@NotNull Function1<UnwrappedType, Boolean> isSpecialType,
|
||||
@NotNull Function1<KotlinType, Boolean> shouldStopAt
|
||||
) {
|
||||
return contains(type, isSpecialType, shouldStopAt, null);
|
||||
}
|
||||
|
||||
private static boolean contains(
|
||||
@Nullable KotlinType type,
|
||||
@NotNull Function1<UnwrappedType, Boolean> isSpecialType,
|
||||
@Nullable Function1<KotlinType, Boolean> shouldStopAt,
|
||||
SmartSet<KotlinType> visited
|
||||
) {
|
||||
if (type == null) return false;
|
||||
@@ -440,6 +449,7 @@ public class TypeUtils {
|
||||
if (noExpectedType(type)) return isSpecialType.invoke(unwrappedType);
|
||||
if (visited != null && visited.contains(type)) return false;
|
||||
if (isSpecialType.invoke(unwrappedType)) return true;
|
||||
if (shouldStopAt != null && shouldStopAt.invoke(unwrappedType)) return false;
|
||||
|
||||
if (visited == null) {
|
||||
visited = SmartSet.create();
|
||||
@@ -448,12 +458,13 @@ public class TypeUtils {
|
||||
|
||||
FlexibleType flexibleType = unwrappedType instanceof FlexibleType ? (FlexibleType) unwrappedType : null;
|
||||
if (flexibleType != null
|
||||
&& (contains(flexibleType.getLowerBound(), isSpecialType, visited) || contains(flexibleType.getUpperBound(), isSpecialType, visited))) {
|
||||
&& (contains(flexibleType.getLowerBound(), isSpecialType, shouldStopAt, visited)
|
||||
|| contains(flexibleType.getUpperBound(), isSpecialType, shouldStopAt, visited))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (unwrappedType instanceof DefinitelyNotNullType &&
|
||||
contains(((DefinitelyNotNullType) unwrappedType).getOriginal(), isSpecialType, visited)) {
|
||||
contains(((DefinitelyNotNullType) unwrappedType).getOriginal(), isSpecialType, shouldStopAt, visited)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -461,13 +472,14 @@ public class TypeUtils {
|
||||
if (typeConstructor instanceof IntersectionTypeConstructor) {
|
||||
IntersectionTypeConstructor intersectionTypeConstructor = (IntersectionTypeConstructor) typeConstructor;
|
||||
for (KotlinType supertype : intersectionTypeConstructor.getSupertypes()) {
|
||||
if (contains(supertype, isSpecialType, visited)) return true;
|
||||
if (contains(supertype, isSpecialType, shouldStopAt, visited)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (TypeProjection projection : type.getArguments()) {
|
||||
if (!projection.isStarProjection() && contains(projection.getType(), isSpecialType, visited)) return true;
|
||||
if (projection.isStarProjection()) continue;
|
||||
if (contains(projection.getType(), isSpecialType, shouldStopAt, visited)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
class Bar<K> {
|
||||
}
|
||||
Vendored
+27
@@ -0,0 +1,27 @@
|
||||
// WITH_RUNTIME
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
/*
|
||||
ServletOpenApiContextBuilder<
|
||||
T : raw (
|
||||
ServletOpenApiContextBuilder<ServletOpenApiContextBuilder<*>>
|
||||
..
|
||||
ServletOpenApiContextBuilder<out ServletOpenApiContextBuilder<*>>?
|
||||
)
|
||||
>
|
||||
: GenericOpenApiContextBuilder<
|
||||
raw (
|
||||
ServletOpenApiContextBuilder<[ERROR : <LOOP IN SUPERTYPES>]> // exception on this error type during serialization
|
||||
..
|
||||
ServletOpenApiContextBuilder<*>?
|
||||
)
|
||||
>
|
||||
*/
|
||||
public class Foo<T extends Foo> extends Bar<Foo> {
|
||||
String ctxId = "";
|
||||
|
||||
public T ctxId(String ctxId) {
|
||||
this.ctxId = ctxId;
|
||||
return (T) this;
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// WITH_RUNTIME
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
public class Foo<T extends Foo> extends Bar<Foo> {
|
||||
String ctxId = "";
|
||||
|
||||
public T ctxId(String ctxId) {
|
||||
this.ctxId = ctxId;
|
||||
return (T) this;
|
||||
}
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Compiling files:
|
||||
End of files
|
||||
Exit code: OK
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
================ Step #1 =================
|
||||
|
||||
Compiling files:
|
||||
src/main.kt
|
||||
End of files
|
||||
Exit code: OK
|
||||
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
class Main {
|
||||
fun init() {
|
||||
Foo<Foo<*>>() //this is the call that causes the build exception, if you comment it out everything works fine
|
||||
.ctxId("")
|
||||
}
|
||||
}
|
||||
fun box() = "OK"
|
||||
Reference in New Issue
Block a user