Title: Type inference failed. Expected type mismatch: inferred type is @Composable, why can't I remember mutableStateOf Composable Function directly?

892 views Asked by At

I can have

val composeFunction = remember { mutableStateOf ({}) }

I can have

val composeFF = @Composable { Text("ABC") }
val composeFunction = remember { mutableStateOf (composeFF) }

Why can't I have

val composeFunction = remember { mutableStateOf (@Composable { Text("ABC") }) }

It errors out state

Internal Error occurred while analyzing this expression 
(Please use the "
 
" icon in the bottom-right corner to report this error):
 
jar:file:/Applications/Android%20Studio.app/Contents/lib/platform-impl.jar!/general/error.svg
Type inference failed. Expected type mismatch: inferred type is @Composable () -> Unit but () -> Unit was expected
1

There are 1 answers

2
z.g.y On BEST ANSWER

Have you tried specifying the type?

val composeFunction = remember { mutableStateOf<@Composable () -> Unit> (@Composable { Text("ABC") }) }

Looks like the compiler cannot infer an ordinary function to something that is supplied with a @Composable annotation

Update:

It turns out @Composable annotation actually modifies the function type, similar to what suspend modifier does.

Based on this arcticle,

An important thing to note is that Compose is not an annotation processor. Compose works with the aid of a Kotlin compiler plugin in the type checking and code generation phases of Kotlin: there is no annotation processor needed in order to use compose. This annotation more closely resembles a language keyword. A good analogy is Kotlin’s suspend keyword.

furthermore,

The important point here is that when you annotate a function type with @Composable you’re changing its type: the same function type without the annotation is not compatible with the annotated type. Also, suspend functions require a calling context, meaning that you can only call suspend functions inside of another suspend function.