https://kotlinlang.org logo
n

natpryce

02/21/2019, 8:46 AM
Is there document that outlines which language features are supported on different platforms? E.g. I’ve got a multiplatform project, and the tests are failing on native platforms for code that uses reified generics. Are they implemented on native? Will they be?
g

gildor

02/21/2019, 8:51 AM
Reified generics should work. What kind error do you have?
n

natpryce

02/21/2019, 8:52 AM
I’m diagnosing the cause now. I’ve not been able to debug native code in a multiplatform project, so it’s slow to narrow down the cause.
Found it. The
is
operator doesn’t work with reified types in an object expression within the inline function. These tests fail on native:
Copy code
@Test
    fun is_from_object() {
        inline fun <reified T> isA() = object {
            operator fun invoke(value: Any) = value is T
        }
        
        assertTrue(isA<String>()("a string"), "a string is a string")
        assertFalse(isA<String>()(10), "an int is not a string")
        
        assertTrue(isA<Int>()(10), "an int is an int")
        assertFalse(isA<Int>()("a string"), "a string is not an int")
    }
    
    @Test
    fun not_is_from_object() {
        inline fun <reified T> isNotA() = object {
            operator fun invoke(value: Any) = value !is T
        }
        
        assertFalse(isNotA<String>()("a string"), "a string is a string")
        assertTrue(isNotA<String>()(10), "an int is not a string")
        
        assertFalse(isNotA<Int>()(10), "an int is an int")
        assertTrue(isNotA<Int>()("a string"), "a string is not an int")
    }
Hmm... That code doesn’t even compile on the JVM platform (I get an error that inline functions are not supported in inline functions!).
I’ll make the tests also compile on the JVM and see if that makes a difference
Ok… I’ve reproduced the error in a small test. Reified types do not work when the inline function returns an object expression with methods that refer to the type parameter, and the inline function is defined in one compilation unit and called from another.
But do work when they are both in the same compilation unit
s

svyatoslav.scherbina

02/21/2019, 2:15 PM
This is known issue and will be fixed in 1.3.30.
n

natpryce

02/21/2019, 2:56 PM
👍
What’s the workaround?
s

svyatoslav.scherbina

02/21/2019, 4:22 PM
The workaround is to avoid using
inline
functions with reified parameters and object expressions declared in other compilation unit.
n

natpryce

02/21/2019, 5:00 PM
:-D
A workaround is to split the inline function with reified type into two parts, one which turns the reified type to a KClass, and the other which uses the KClass. It requires some unchecked cast warnings to be suppressed — only isInstance is defined on KClass, not safe downcast. But it does work.
👍 1
Thanks for your help.
6 Views