Skip to content

[Bug] 4.2: Class kotlin.reflect.jvm.internal.KTypeParameterImpl cannot be cast to class kotlin.reflect.KClass #1132

@ianbrandt

Description

@ianbrandt

Describe the bug

Thank you for the additional Kotlin support in 4.2! I'm attempting to upgrade from 4.1, but with 4.2 I'm hitting a ClassCastException for a class that uses interface delegation.

Steps to reproduce

Diff/reproducer here: sdkotlin/sd-kotlin-talks@bcd4c59. The test passes before the changes.

Error message and version number

EqualsVerifier found a problem in class org.sdkotlin.integral.IntegralRange.
-> class kotlin.reflect.jvm.internal.KTypeParameterImpl cannot be cast to class kotlin.reflect.KClass (kotlin.reflect.jvm.internal.KTypeParameterImpl and kotlin.reflect.KClass are in unnamed module of loader 'app')

For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
(EqualsVerifier 4.2, JDK 21.0.8 running on classpath, on Mac OS X. Mockito: available.)
java.lang.AssertionError: EqualsVerifier found a problem in class org.sdkotlin.integral.IntegralRange.
-> class kotlin.reflect.jvm.internal.KTypeParameterImpl cannot be cast to class kotlin.reflect.KClass (kotlin.reflect.jvm.internal.KTypeParameterImpl and kotlin.reflect.KClass are in unnamed module of loader 'app')

For more information, go to: https://www.jqno.nl/equalsverifier/errormessages
(EqualsVerifier 4.2, JDK 21.0.8 running on classpath, on Mac OS X. Mockito: available.)
	at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:412)
	at org.sdkotlin.integral.IntegralRangeTest.test equals, hashCode, and toString(IntegralRangeTest.kt:20)
Caused by: java.lang.ClassCastException: class kotlin.reflect.jvm.internal.KTypeParameterImpl cannot be cast to class kotlin.reflect.KClass (kotlin.reflect.jvm.internal.KTypeParameterImpl and kotlin.reflect.KClass are in unnamed module of loader 'app')
	at nl.jqno.equalsverifier.internal.reflection.kotlin.KotlinProbe.createTypeTag(KotlinProbe.java:70)
	at nl.jqno.equalsverifier.internal.reflection.kotlin.KotlinProbe.determineLazyType(KotlinProbe.java:65)
	at nl.jqno.equalsverifier.internal.reflection.TypeTag.of(TypeTag.java:57)
	at nl.jqno.equalsverifier.internal.checkers.AbstractDelegationChecker.checkAbstractDelegationInFields(AbstractDelegationChecker.java:64)
	at nl.jqno.equalsverifier.internal.checkers.AbstractDelegationChecker.check(AbstractDelegationChecker.java:36)
	at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verifyWithoutExamples(SingleTypeEqualsVerifierApi.java:509)
	at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.performVerification(SingleTypeEqualsVerifierApi.java:478)
	at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:406)
	... 1 more

class kotlin.reflect.jvm.internal.KTypeParameterImpl cannot be cast to class kotlin.reflect.KClass (kotlin.reflect.jvm.internal.KTypeParameterImpl and kotlin.reflect.KClass are in unnamed module of loader 'app')
java.lang.ClassCastException: class kotlin.reflect.jvm.internal.KTypeParameterImpl cannot be cast to class kotlin.reflect.KClass (kotlin.reflect.jvm.internal.KTypeParameterImpl and kotlin.reflect.KClass are in unnamed module of loader 'app')
	at nl.jqno.equalsverifier.internal.reflection.kotlin.KotlinProbe.createTypeTag(KotlinProbe.java:70)
	at nl.jqno.equalsverifier.internal.reflection.kotlin.KotlinProbe.determineLazyType(KotlinProbe.java:65)
	at nl.jqno.equalsverifier.internal.reflection.TypeTag.of(TypeTag.java:57)
	at nl.jqno.equalsverifier.internal.checkers.AbstractDelegationChecker.checkAbstractDelegationInFields(AbstractDelegationChecker.java:64)
	at nl.jqno.equalsverifier.internal.checkers.AbstractDelegationChecker.check(AbstractDelegationChecker.java:36)
	at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verifyWithoutExamples(SingleTypeEqualsVerifierApi.java:509)
	at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.performVerification(SingleTypeEqualsVerifierApi.java:478)
	at nl.jqno.equalsverifier.api.SingleTypeEqualsVerifierApi.verify(SingleTypeEqualsVerifierApi.java:406)
	at org.sdkotlin.integral.IntegralRangeTest.test equals, hashCode, and toString(IntegralRangeTest.kt:20)

Code: EqualsVerifier invocation

EqualsVerifier.forClass(IntegralRange::class.java)
	.withIgnoredFields("endExclusive", $$$"$$delegate_0")
	.withPrefabValues(
		Integral::class.java,
		mockk(relaxed = true),
		mockk(relaxed = true),
	)
	.verify()

https://github.com/sdkotlin/sd-kotlin-talks/blob/bcd4c59ab950b86b93cc5b19819c2cb02cf2474c/subprojects/user-defined-integrals-in-kotlin/src/test/kotlin/org/sdkotlin/integral/IntegralRangeTest.kt#L12

Code: class under test

class IntegralRange<I : Integral<I>>(
	start: I,
	endInclusive: I,
) : ClosedRange<I>, OpenEndRange<I>,
	Progression<I> by IntegralProgression(
		start,
		endInclusive,
		step = start.one
	) {

	override val start: I = first

	override val endInclusive: I = last

	override val endExclusive: I by lazy {
		check(endInclusive != endInclusive.maxValue) {
			"Cannot return the exclusive upper bound of a range that includes MAX_VALUE."
		}
		endInclusive + endInclusive.one
	}

	override fun contains(value: I): Boolean =
		value in start..endInclusive

	override fun isEmpty(): Boolean = start > endInclusive

	override fun equals(other: Any?): Boolean =
		other is IntegralRange<*> && (isEmpty() && other.isEmpty() ||
			start == other.start && endInclusive == other.endInclusive)

	override fun hashCode(): Int =
		if (isEmpty()) -1 else (31 * start.hashCode() + endInclusive.hashCode())

	override fun toString(): String = "$start..$endInclusive"
}

https://github.com/sdkotlin/sd-kotlin-talks/blob/bcd4c59ab950b86b93cc5b19819c2cb02cf2474c/subprojects/user-defined-integrals-in-kotlin/src/main/kotlin/org/sdkotlin/integral/IntegralRange.kt#L3

Progression interface delegate:

https://github.com/sdkotlin/sd-kotlin-talks/blob/bcd4c59ab950b86b93cc5b19819c2cb02cf2474c/subprojects/user-defined-integrals-in-kotlin/src/main/kotlin/org/sdkotlin/integral/IntegralProgression.kt#L3

Additional context

Kotlin 2.2.20.

Related: #1097 and #1082.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions