False positive: Calling a Google Map Composable composable function where a UI Composable composable was expected
I am using version 5.0.4 of this library. On my map, I need to add a composable marker which I am doing via MarkerComposable. This composable is marked with @GoogleMapComposable that should enforce correct usage (introduced in https://github.com/googlemaps/android-maps-compose/pull/130). I think there is an issue here as this gets triggered if I use a standard/non maps composable inside the MarkerComposable as this is then not marked with the @GoogleMapComposable annotation. Probably, there should be an exclude for this specific case as I cannot annotate all composables that I want to use with that annotation (for example a simple Text). Or is there a simple way to suppress it?
For me, this is quite annoying as we enforce our builds to not have any warnings.
Steps to reproduce
- Use some composable (Card, Text, ...) inside the
MarkerComposable - The build warning "Calling a Google Map Composable composable function where a UI Composable composable was expected" is triggered
Code example
MarkerComposable( // <-- has the @GoogleMapComposable annotation
// ...
) {
Text(text = "Hello World") // <-- does not have the @GoogleMapComposable annotation, but is a valid use case
}
@ln-12 Hello, from what I tested in the latest version 6.1.1 of Compose maps this does not happen.
I just checked again after updating to version 6.1.1 and for me this still gives the warning mentioned above when I rebuild my project. It happens in the compileDebugKotlin task.
Still happens for me in version 6.8.0
Happens to me after switching to Kotlin 2.2.20. I checked android-maps-compose versions from 6.7.2 to 6.10.0
Hi folks,
@ln-12 , I am not able to trigger this warning with the version 2.2.20 from Kotlin, as @mrmike stated:
Would you happen to have a repo where this can be reproduced?
@kikoso no repo on hand, but this triggers the warning on this repo with this patch:
❯ git diff HEAD^1..HEAD
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index cc3a9b5..50428fd 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -11,7 +11,7 @@ gradleMavenPublishPlugin = "0.34.0"
jacoco-plugin = "0.2.1"
junit = "4.13.2"
junitktx = "1.3.0"
+kotlin = "2.2.20"
- kotlin = "2.2.10"
kotlinxCoroutines = "1.10.2"
leakcanaryAndroid = "2.14"
mapsecrets = "2.0.1"
❯ ./gradlew :maps-app-compileDebugKotlin
...
> Task :maps-app:compileDebugKotlin
w: Argument -Xopt-in is deprecated. Please use -opt-in instead
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt:198:17 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt:206:17 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt:219:17 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt:227:21 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt:239:21 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt:242:17 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/BasicMapActivity.kt:250:21 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/GoogleMapComposeFragment.kt:103:25 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/MapInColumnActivity.kt:216:13 Calling a UI Composable composable function where a Google Map Composable composable was expected
w: file:///home/florian/projects/android-maps-compose/maps-app/src/main/java/com/google/maps/android/compose/markerexamples/AdvancedMarkersActivity.kt:186:13 'when' is exhaustive so 'else' is redundant here.
The warning is silenced when indicating that content is a @UiComposable.
❯ git diff HEAD^1..HEAD
diff --git a/maps-compose/src/main/java/com/google/maps/android/compose/Marker.kt b/maps-compose/src/main/java/com/google/maps/android/compose/Marker.kt
index f27d331..2e17c99 100644
--- a/maps-compose/src/main/java/com/google/maps/android/compose/Marker.kt
+++ b/maps-compose/src/main/java/com/google/maps/android/compose/Marker.kt
@@ -29,7 +29,6 @@ import androidx.compose.runtime.saveable.Saver
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.snapshots.StateFactoryMarker
+import androidx.compose.ui.UiComposable
import androidx.compose.ui.geometry.Offset
import com.google.android.gms.maps.model.AdvancedMarkerOptions
import com.google.android.gms.maps.model.BitmapDescriptor
@@ -555,7 +554,7 @@ public fun MarkerInfoWindowContent(
onInfoWindowClick: (Marker) -> Unit = {},
onInfoWindowClose: (Marker) -> Unit = {},
onInfoWindowLongClick: (Marker) -> Unit = {},
+ content: (@UiComposable @Composable (Marker) -> Unit)? = null
- content: (@Composable (Marker) -> Unit)? = null
) {
MarkerImpl(
state = state,
Hi @pikzen ,
I am able to reproduce the issue on the new Kotlin version, thanks for the patch.
The documentation for @UiComposable states the following:
Using this annotation explicitly is rarely necessary as the Compose compiler plugin will infer the necessary equivalent annotations automatically
My assumption is that something has changed in the new Kotlin version that invalidates this inference. I will verify that there are no undesired side effects and create a pull request.
Thank you all.
@ComposableTarget (which @UiComposable/@GoogleMapComposable are) adds some additional information in its documentation:
[...] if a composable function calls another composable function then both must be of the same group of composable functions (that is, have declared or inferred the same applier value). This means that, if the function called is already determined to be in a group, them the function that calls it must also be in the same group. If two functions are called of different groups then the Compose compiler plugin will generate an diagnostic message describing which group was received and which group was expected.
...
In most cases this annotation can be inferred. However, this annotation is required for Composable functions that call ComposeNode directly, for abstract methods, such as interfaces functions (which do not contain a body from which the plugin can infer the annotation), when using a composable lambda in sub-composition, or when a composable lambda is stored in a class field or global variable.
I'd assume the most recent @ComposableTarget is assumed to be true for the entire tree it affects unless specified otherwise, and might even hit the "composable lambda in sub-composition" condition
:tada: This issue has been resolved in version 6.11.0 :tada:
The release is available on:
v6.11.0- GitHub release
Your semantic-release bot :package::rocket:
Release v6.11.0 has not been published yet
Hi @mrmike . There was an issue while publishing the new version, aiming to have it published soon.
:tada: This issue has been resolved in version 6.11.0 :tada:
The release is available on:
v6.11.0- GitHub release
Your semantic-release bot :package::rocket:
Hi @mrmike .The new version has been published.