Add lint check to specialize mutableStateOf calls

This CL adds an inspection to warn users when they are creating a state
using the generic `mutableStateOf<T>()` function that could be
specialized to a different state builder function which will not box
type `T`. To make this conversion, a few things must be true (which
this inspection looks for when reporting errors):
 - `T` must not be nullable
 - `T` must have a known specialized state builder function
 - The snapshot mutation policy argument must not be specified or must
   be the `structuralEqualityPolicy()`

For AndroidX, this inspection will be treated as an error.

Test: AutoboxingStateCreationDetectorTest
Change-Id: I4781c5b7bb48d177619fe5dece3b23f3989d41ee
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
index f60a494..c596da5 100644
--- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
+++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXComposeImplPlugin.kt
@@ -153,6 +153,7 @@
                     error.add("ComposableLambdaParameterPosition")
                     error.add("CompositionLocalNaming")
                     error.add("ComposableModifierFactory")
+                    error.add("AutoboxingStateCreation")
                     error.add("AutoboxingStateValueProperty")
                     error.add("InvalidColorHexValue")
                     error.add("MissingColorAlphaChannel")
diff --git a/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt b/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
index 5c61695..092f11da 100644
--- a/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
+++ b/compose/lint/common-test/src/main/java/androidx/compose/lint/test/Stubs.kt
@@ -519,7 +519,7 @@
     val SnapshotState: TestFile = bytecodeStub(
         filename = "SnapshotState.kt",
         filepath = "androidx/compose/runtime",
-        checksum = 0x3a5656cc,
+        checksum = 0x6f0a3199,
         source = """
         package androidx.compose.runtime
 
@@ -543,7 +543,10 @@
 
         private class MutableStateImpl<T>(override var value: T) : MutableState<T>
 
-        fun <T> mutableStateOf(value: T): MutableState<T> = MutableStateImpl(value)
+        fun <T> mutableStateOf(
+            value: T,
+            policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
+        ): MutableState<T> = MutableStateImpl(value)
 
         fun <T> mutableStateListOf() = SnapshotStateList<T>()
         class SnapshotStateList<T>
@@ -598,12 +601,44 @@
         ) {
             this.value = value
         }
+
+        interface SnapshotMutationPolicy<T> {
+            fun equivalent(a: T, b: T): Boolean
+            fun merge(previous: T, current: T, applied: T): T? = null
+        }
+
+        @Suppress("UNCHECKED_CAST")
+        fun <T> referentialEqualityPolicy(): SnapshotMutationPolicy<T> =
+            ReferentialEqualityPolicy as SnapshotMutationPolicy<T>
+
+        private object ReferentialEqualityPolicy : SnapshotMutationPolicy<Any?> {
+            override fun equivalent(a: Any?, b: Any?) = a === b
+            override fun toString() = "ReferentialEqualityPolicy"
+        }
+
+        @Suppress("UNCHECKED_CAST")
+        fun <T> structuralEqualityPolicy(): SnapshotMutationPolicy<T> =
+            StructuralEqualityPolicy as SnapshotMutationPolicy<T>
+
+        private object StructuralEqualityPolicy : SnapshotMutationPolicy<Any?> {
+            override fun equivalent(a: Any?, b: Any?) = a == b
+            override fun toString() = "StructuralEqualityPolicy"
+        }
+        @Suppress("UNCHECKED_CAST")
+        fun <T> neverEqualPolicy(): SnapshotMutationPolicy<T> =
+            NeverEqualPolicy as SnapshotMutationPolicy<T>
+
+        private object NeverEqualPolicy : SnapshotMutationPolicy<Any?> {
+            override fun equivalent(a: Any?, b: Any?) = false
+            override fun toString() = "NeverEqualPolicy"
+        }
         """,
         """
                 META-INF/main.kotlin_module:
-                H4sIAAAAAAAA/2NgYGBmYGBgBGIOBijgMueSSMxLKcrPTKnQS87PLcgvTtUr
-                Ks0rycxNFeIKSs1NzU1KLfIuEeIPzkssKM7ILwkuSSxJ9S7h4uNiKUktLhFi
-                CwGS3iVKDFoMAJF5eAthAAAA
+                H4sIAAAAAAAA/3XLvQvCQAwF8IiiEkThBhERBBfBoS6Cszh2s+KetqE9uI9y
+                TcE/3xN1KgZehsf7AcAQAAYxU/gennBNrgxel8+k8LbxLSfktCXR3qllpl1l
+                +EGm48uvTQWPuP2vYhNYzT57yg1HcMZVD4TOibas8MaWbc4hFbXIHDVt7SUT
+                kjfc46YHO51UgZpaF62aXL3xUeIcR8KtqPE9/lR2cIAXjm1D/fEAAAA=
                 """,
                 """
                 androidx/compose/runtime/DerivedState.class:
@@ -667,6 +702,30 @@
                 3MPKIZjEfTw4xITEtMSqxEOJtNThjMSsxLxE5hfups0nUgQAAA==
                 """,
                 """
+                androidx/compose/runtime/NeverEqualPolicy.class:
+                H4sIAAAAAAAA/5VU3W8bRRD/7Z0/zhcndZyQpmn4KA3UTpqeE8pnTNoSinqR
+                ayJcBUGe1vbibnK+c+/2rCJeIv4Unnmg4qEIJBTBW/8oxOydCcFJUSLLO7Mz
+                s7/5zc7svfjr198B3MZdhir3u2Egu0+dTtAfBJFwwthXsi+cphiK8P6TmHs7
+                gSc73+bBGL5s7PMhdzzu95zP2/uiozYaL0Vo+XwQPQ7Uw1hxJQM/xamfhtjc
+                YCiNW/PIMDgXBM8jx5CrS1+qTQazUt0twkLBRhY2Q0Y9lhHDysspjxdNxGzx
+                JJZD7glfMdyonHEBpyzVrxmWGkHYc/aFaodc+hEV4gcp08hpxp7H254gdMYZ
+                yqcRyNFmsFTQUqH0ewyzleqJqNRKUdf/L0ugdCJ9t+NlWbjMkO2LsCcYts9V
+                0xlVnkW7fsGGLX0qvuGxp9z+wIvyuMrwXeWiE3UutufiX8QVvGpjEa/R5Q9C
+                MZRBTAOT78RhmPQ/zwcDT4ouuesdLxkzG4aeLcttth7da27dL+ItTBbI+DbD
+                dOMgUBTmPBSKd7nidENGf2jS62N6sfQCavYB2Z9KvauR1l1jEEeHi7Yxb6T/
+                0tGhbVhamSBpkpyy/vzemD86XLfLuXJmntWMGvskbxl//JAzSub2YimzYNSy
+                61Ypt5B4Scun2oO5batkkbfwYE4nW2dYu/CVM027eLJ5NGb/xLYoVNw6oPu6
+                +kUK4/pDGUka+Xv/Dii9x62gSwN4qSF90Yz7bRE+0s9Cv4igw71dHkq9HxmX
+                xrF2eMj7QonwP6BF1/dFuOXxKBK0LbRkz+cqDgnBbgVx2BGfSQ13ZQS3e4oY
+                atS9LNVHnzwaCGonyfepNzmScySz5KevCu0+oJ2jG6ity88x8YwUAx+OgoE+
+                PqK1mAaQnEz6PYVLFKUP36Wdbrth/jh20k9OvpF6Rye1No1y4jcwQ5qBDdIn
+                DTKVEuh0ncUrowSrI3Zmef6nsQzBCW7mKMPJMnXxC+TRMDvI0I8mdnnl5uov
+                eH0cK61zOY05ZmsR/5SthWsJW629SZp5nEkT1jXMmGM1lJLg68f3fDk5Dkz8
+                BuOr51j6GTeeJYYM6rTaFLZILXuXWH+csDOxmcj3cIekS/4K9aC6B9PFsosV
+                FzexSipuudTE2h5YhDWs78GOMBnhnQi3IxQiTCXKdISZCLOk/w1bh/c6QAcA
+                AA==
+                """,
+                """
                 androidx/compose/runtime/ProduceStateScope.class:
                 H4sIAAAAAAAA/41T328SQRCeXSgcSPWKv4BWq7ZGJcY7iU9CiEbTFENrI+gL
                 T8tx4MKxS273sI/EP8UH/wbjgyH45h9lnINeG4u1fbid2ZlvvtnZ/e7X7+8/
@@ -683,128 +742,195 @@
                 gzXIogtXa3ANrreAKLgBN1uQUpBTkFdQUGAoWFewoeDW3En9Ae+dQkpABAAA
                 """,
                 """
+                androidx/compose/runtime/ReferentialEqualityPolicy.class:
+                H4sIAAAAAAAA/5VUW28bRRT+ZteX9cZOHSekSRquDdS5dR0TrjGhIRTVkROi
+                OgqCANLYnrqTrHfdvViteIn4KTzACw9UPBRRCUXwxo9CnNk1wTgJSmR5zplz
+                znznO3PO7J9//fobgFVsMJS50/Jc2XpsNd1O1/WF5YVOIDvCui8eCE+Qzu27
+                j0Juy+DJrmvL5pM0GMNntUPe45bNnbb1aeNQNIO12oVQdYd3/YdusB0GPJCu
+                E+NUzkKsrzHkh61pJBisK4KnkWJIVaQjg3UGvTi/n4WBjIkkTIZE8FD6DKsX
+                U76wemJoikeh7HGb3Ay3iufcxBnL/BcMczXXa1uHImh4XDo+VeS4MWXf2glt
+                mzdsQeiMMxTOIpCjwWAEbj3wpNNmmCjOD0TFVoq6+X9Z3EAloqjpC+szcJ0h
+                2RFeWzBsXaq4c8o9j3/lii2c+1g84KEdVDtd20/jBsM3xavO2KXYXop/FtN4
+                0cQsXqIudD3Rk25II5Ruhp4XDUKad7u2FC1yV5p2NHgmNDVtRnWnvrexs3k3
+                i9eRy5DxDYax2pEbUJi1LQLe4gGnG9I6PZ0eJlOLoRZQ14/I/liqXYm01gqD
+                ODmeNbUpLf7nT45NzVDKCEmd5Kjxx7fa1Mlx2SykCokpVtJK7KO0of3+XUrL
+                61uz+cSMVkqWjXxqJvKSlo61e5NbRt4gb+bepEpWZli58pUzRTs72Dx61P/E
+                1ilU3D6i+7pxP4apOj3pS5r9jX8nlV7optuiAbxWk47YCTsN4e2p96Gehtvk
+                9j73pNr3jTmCbR5t825/PzeMvcs93hGB8P6TJFt1HOFt2tz3BW0zddl2eBB6
+                hGDW3dBrik+kgpvuw+2fIYoSdTNJ9dJHkQaE2kvyHepViuQkyST56btDu3dp
+                Z6mGKuvCM4w8JUXDe/1g4Eu8T2s2DiCZi/o/imsUpQ7vkVRjMLK49D3SiR+Q
+                0H+krY61OE/mDhtA+ypCeyU+0UdT2hgKkX8E46RpqJCe08iUj9LF6wRe6Cdd
+                7jPWC1M/DfH9eoCv3s8wWLq6kBnyKJhdJOhHU72wuLT8C14exoprX4hjTtka
+                xD9ma+DViK3SXiNNP82kCKsaxvWhGvJR8M3Tu78eHafCn0P7/Bnmfsatp5Eh
+                gQ9oNSlsltr4FrFej9jp+DCSb+MOySr5i3TN8wfQq1ioYrGKJSyTittVamzp
+                AMzHCsoHMH3kfLzpY9VHxsdopIz5GPcxQfrfIoPaNX8HAAA=
+                """,
+                """
+                androidx/compose/runtime/SnapshotMutationPolicy$DefaultImpls.class:
+                H4sIAAAAAAAA/5VSTW/TQBB96yRNGlL6wWcotEADohwwlTiRqBIqQjJKS0VC
+                D3Da2Eu6ib1rrddREX+KMwd+AD8KMeukAhqEiGXPvnnzZmY9u99/fP0G4Bke
+                MnS4ioyW0Zkf6iTVmfBNrqxMhN9TPM1OtT3MLbdSq2Mdy/BT66X4yPPYBkka
+                Z1UwhrURn3A/5mrovxmMRGirKDFUEmGGguHzo+6CHdrdiwX/i9mdpxjed/rP
+                5/n9hffU6ffb+20y03eXPoZWV5uhPxJ2YLhUmc+V0tOkzD/K45gPYkGynX/J
+                tHVKUlVa9lRmDHsLj4uhlhoxkTqn9I2/TaEa5sYIZQnxNI2liBjWu2NtY6n8
+                Q2F5xC0nnZdMSnQvmDM1Z8DAxg7QgXpn0qGnDP6CO6yiydD4/d7QpTmX9kgp
+                noxpb+UDHdGFWe1KJY7yZCBM303Q/ZMOeXzCjXT+jFzuyaHiNjeEN99O+wdq
+                IjNJ4Re/RkzHdDF6zA1PhBXmD1kjUEqYg5hnmSC33tO5CcUr6Zo1ZyVO5spj
+                Dx7KmM5qGRUskXeHvNfkO95jX5zFFtkl4oB32Cb7eBpFHZeKbA8NrBRxD5cJ
+                eQVaJVTC3QJXcW9Wo0brffpWykXT86eEHbJ14jzcwiaaaBWJt/GA1i3i10iz
+                /gGlABsBrgS4imsBruNGgJs/AVqKC54UBAAA
+                """,
+                """
+                androidx/compose/runtime/SnapshotMutationPolicy.class:
+                H4sIAAAAAAAA/5VTzW7TQBD+1kltx2mLC6WkKeU3NCkHnFYcEK2QEAjhKgXU
+                RBzoaZNswybOOnjtqHDKs/AYHFDEkYdCjJ1WINIDlbzz/83szox//vr2HcBj
+                bDN4XHWjUHZPvU44HIVaeFGiYjkUXlPxkf4YxodJzGMZqndhIDufLTCG2n7r
+                aaPPx9wLuOp5b9t90Yn3ns2bGNx/bRbyDI74lMgxD4SKGaq1eeC8ZfsDQ6HW
+                au3Rl8oLQxH1BMPBf6EvyHfRbZfPCqQ16DBUGmHU8/oibkdcKk3dUuGsHdp7
+                kwQBbweCwlYagzAOpPIORcy7POZkM4bjHHWZpcROCRjYgOynMtXqJHV3GL5M
+                J6uOUTKc6cQxXCIZLzqGbdsnpenkYd6eTly2a9SNg003Vzbq+V3TXSgbT6YT
+                EsxMeL3146tpuNZB1bXL+RKb+QrnQc65UJxFr2XRi+kNdhl2GpfcAXoca7Hs
+                PZxOm8EeRWIsw0QzWJ0kirK5Wnw0CqToMuxfskDlpTjhSRD7w1GgLdxhWPzb
+                Qlt1jmsSTDwaULVCU/YUj5OIdmLjaJbeV2OpJY3o+Z+xUS5fKRG9CLjWglSn
+                GSZRR7ySASHXz5Dv53AmdQsL6Rhh0AaboD8BlVSDTXoBDkkzvYgHxE3yLxLP
+                Y4uoQ9pd8t3D+llUDtWM30eN+BH5lyj/8jFyPq74cH2s4CqJuOZjFdePwTTW
+                cOMYSxoljXWNsoaZ0Q2NmxqWRkFjU+OWxm0N5zfYvY915wMAAA==
+                """,
+                """
                 androidx/compose/runtime/SnapshotStateKt$produceState$1.class:
-                H4sIAAAAAAAA/41T3U4TURD+znb7w1poqYCAiqhVtkVZqCZqCiSGSNJYNaGk
-                MeFq6S7lQHuW7DltuOxT+AA+gSYaEy9Mw6UPZZyzbQwKAhc7f5n55pszsz9/
-                ff8B4CmeMDxzhRcG3Dt2GkH7KJC+E3aE4m3fqQn3SO4HqqZc5b9W+aMw8DoN
-                P3LzK0kwKq4euF3Xabmi6bzbPfAbqlz9P54uXN3eLq+XGbL/FiZhMsxdXJxE
-                giGxygVX6wyT9tnuhTol2NRDGzG7UE8jhWsW4kgzxLtuq+Mz5M7WpTGGzAgM
-                ZBlMtc8lw4sLJrnwZWi60bzmyN1WfdAx1fTV0JywC2fbEze7QKyJcyTHq4eB
-                anHhvPGV67nKpZjR7sZoaUyLlBZgYIcUP+baWybLW2FY6/dGrX7PMqYNy0iZ
-                Rdbvpazpfq+Uypk543m/t8y2prLGrDbfn3wwTz4mLMvIxmfNVCxrapASw/wl
-                WyQ69lVfJ4kHDOnTT8Swd87qzokMH+Gg23b2OqKheCCkszm0SuXCZSzTWIBN
-                t/YXo6VDxTBS403hqk5IZMyNwCOVqXLhv+20d/1w291tRXcSNPQKQ679YTBd
-                EcIPN1qulD5dSeaVaLQCyUWTVrUfeAxWLeiEDX+T6+yZrQGhOpecyl8KERAH
-                PQdW6NritEP6kZDT50d6kRZpYJo+2jH0PT4ia5O0jljFbxgtLn7F+Oco7zHJ
-                MejlP4RJo46QXiJvapBNqNf1mZA1cQrdImsyytHYjr4i0vHiF4x/+gObiIIL
-                EVx6kDCEG4DcIN+JoFnUDJjBMkmTKBSGOTEaUesiSqTXKHOGqmZ3EKvgZgW3
-                KriNOTJxp4J53N0Bk7iH+ztISG3mJcYkJiWmJDK/AeLwkAKyBAAA
+                H4sIAAAAAAAA/41TXU8TURA9d7v9YC20VECoiqhV26IsVBM1BRJDJGmsmlDS
+                mPC07C7lwvYu2b3b8Nhf4Q/wF2iiMfHBNDz6o4xzt41BQfBhZ86dzJw5987s
+                j5/fvgN4gscMTy3hBD53jk3b7x75oWsGkZC865otYR2F+75sSUu6r2TpKPCd
+                yHbjY2klDUbFzQOrZ5meJTrm290D15b15r/5VOHq9nZ9vc6Q/7swDZ1h/uLi
+                NFIMqVUuuFxnmC6f7V5pU0KZeiiQKFfaWWRwxUASWYZkz/Iil6Fwti6LCeTG
+                oCHPoMt9HjI8v+AmF74M3W68pDRyy2sPO2Y6rhzBqXLlbHvSVq6QatIc28nm
+                oS89LszXrrQcS1oU07q9BA2NKZNRBgzskOLHXJ2WCTkrDGuD/rgx6BvarGZo
+                Gb3KBv2MMTvo1zIFvaA9G/SX2dZMXisq+O7kvX7yIWUYWj5Z1DOJvK5IagwL
+                l0yR5JT/93XSuMeQPf1EDHvnjO6cyOgRDnpdcy8StuS+CM3NEarVK5epzOIB
+                yrRrfyhaOpQMYy3eEZaMAhKjb/gOuVyTC/dN1N11g21r14v3xLfVCAOuzqNg
+                tiGEG2x4Vhi6tCW5l8L2/JCLDo1q33cYjJYfBba7yVX23NZQUJuHnMpfCOGT
+                BnUPrNC2JWmG9COhoNaP/CINUsMsfTRjqH18SGiTvIoY1a8Yry5+weSnOO8R
+                2Qmo4Vego0r5FSzRaWaYTaxX1ZoQmjrFbhCajnMUt6m2iHyy+hmTH3/TpuJg
+                NabLDhNGdEOSa3Q2Y2oWNwPmsExWx30SMcxJ0BWVr6JGfo0y56iquINEA9cb
+                uNHATcwTxK0GFnB7ByzEHdzdQSpUsBRiIsR0iJkQuV9AF5e/sgQAAA==
                 """,
                 """
                 androidx/compose/runtime/SnapshotStateKt$produceState$2.class:
-                H4sIAAAAAAAA/41T0U4TURA9d7ttl7XQUgEBFVGrbouyUEzUFEgMkaSxakKb
-                xoSnZbuWC+1dsnu34bFf4Qf4BZpoTHwwDY9+lHHutjEoCjzs3DOTmTPn3pn9
-                8fPbdwCPscbwxBGtwOetY9v1u0d+6NlBJCTvenZdOEfhvi/r0pHeS1k4CvxW
-                5HqxWyinwai4duD0HLvjiLb9Zu/Ac2Wl9n8+VbjeaFQ2Kwy5vwvT0BkWzi9O
-                I8WQWueCy02Gaets92KTEizqoUDCKjYzMHDFRBIZhmTP6UQeQ/5sXQYTyI5B
-                Q45Bl/s8ZHh2zk3OfRm63XhBaeROpznsaLQ9OYJTVvFse9JmFUk1aY7tZO3Q
-                lx0u7FeedFqOdCimdXsJGhpTxlAGDOyQ4sdceSuEWqsMG4P+uDnom9qsZmqG
-                XmKDvmHODvplI6/ntaeD/grbmclp8wq+PXmvn3xImaaWS87rRiKnK5Iyw+IF
-                UyQ51mVfJ417DJnTT8Rw/I/RXSoyepaDXtd+FwlXcl+E9vYIlSvFi3Rn8AAW
-                bd8fGpcPJcNYnbeFI6OA5OlbfouObI0L73XU3fOChrPXiTfHd9VQA678UTBT
-                FcILtjpOGHq0N9kXwu34IRdtGt6+32Iw634UuN42V9lzO0NBTR5yKn8uhE8a
-                1D2wSvuXpKnSr4W8Wkg6l2i0Gmbpo6lDbehDQtt0qohZ+orx0tIXTH6K8x6R
-                nYBahzJ0rFF+GcvkzQyzifWqWhxCU6fYTULTcY7ittVe0Zksfcbkx9+0qTi4
-                FtNlhgkjuiHJNfLtmJrFzYA5rJDVcR/FUU6CrqjOEskCNihzjqrmd5Go4noV
-                N6q4iQWCuFXFIm7vgoW4g7u7SIUKFkJMhJgOMRMi+wttlNMGxAQAAA==
+                H4sIAAAAAAAA/41TXU8TURA9d7v9YC20VEDAL9Sq26IsVEFNgcQQSRqrJpQ0
+                Jjwtu2u5sL1Ldm8bHvsr/AH+Ak00Jj6Yhkd/lHHutjEoCjzszLmTmTPn3pn9
+                8fPbdwCP8YjhiS3cMODukeUE7cMg8qywIyRve1ZD2IfRXiAb0pbeS1k8DAO3
+                43jxsVhJg1Fxfd/u2pZvi5b1Znffc2S1/n8+Vbi6vV1drzLk/y5MQ2e4cXZx
+                GimG1CoXXK4zTJqnu5ealGBSDwUSZqmZRQaXDCSRZUh2bb/jMRRO12UxhtwI
+                NOQZdLnHI4ZnZ9zkzJeh240WlUZu+81Bx0zLk0M4YZZOtydtZolUk+bYjtcP
+                AulzYb3ypO3a0qaY1u4maGhMmYwyYGAHFD/i6rRIyF1iWOv3Ro1+z9CmNUPL
+                6GXW72WM6X6vkinoBe1pv7fItqby2qyCb4/f68cfUoah5ZOzeiaR1xVJhWHu
+                nCmSHPOir5PGXYbsySdiOPrH6C4UGT7LfrdtvesIR/JARNbmEFWqpfN0Z3Ef
+                Jm3fHxoXDiTDSIO3hC07IcnTNwKXXK7Ohfe60971wm171483J3DUUEOuzsNg
+                tiaEF274dhR5tDe5F8Lxg4iLFg1vL3AZjEbQCR1vk6vsma2BoCaPOJU/FyIg
+                DeoeWKL9S9JU6ddCQS0k+XkarYZp+mjqUBv6gNAmeRUxyl8xWp7/gvFPcd5D
+                smNQ67AMHSuUv4wFOk0Nson1slocQhMn2A1Ck3GO4rbUXpFPlj9j/ONv2lQc
+                XInpsoOEId2A5AqdrZiaxc2AGSyS1XEPpWFOgq6ofBkV8muUOUNVsztI1HC1
+                hms1XMcNgrhZwxxu7YBFuI07O0hFChYjjEWYjDAVIfcLwQpITcQEAAA=
                 """,
                 """
                 androidx/compose/runtime/SnapshotStateKt$produceState$3.class:
-                H4sIAAAAAAAA/41T3U4TURD+znbbLmuhpQJCVUStui3KQjFRU2hiiCSNVRNK
-                GpNeLdu1HGjPkt3Thss+hQ/gE2iiMfHCNFz6UMY528agIHix85eZb74zM/vj
-                57fvAB5jneGJI1qBz1vHtut3j/zQs4OekLzr2XXhHIX7vqxLR3ovZf4o8Fs9
-                14vc/HoSjIprB07fsTuOaNtv9g48V5Zr/8ZThRu7u+VKmSHzd2ESOsPixcVJ
-                JBgSG1xwWWGYtc52LzQowaIeyohZhUYKBq6YiCPFEO87nZ7HkD1bl8IU0hPQ
-                kGHQ5T4PGZ5d8JILJ0Ovm8wrjtzpNEYdjbYnx+aMVTjbnrhZBWJNnCM5XTv0
-                ZYcL+5UnnZYjHYpp3X6MlsaUMJQAAzuk+DFX3ipZrTWGzeFg0hwOTG1eMzVD
-                L7LhwDDnh4OSkdWz2tPhYJXtzGW0nDLfnrzXTz4kTFPLxHO6EcvoCqTEsHTJ
-                FomO9b/TSeIeQ+r0iBja56yuec4tjadw0O/a73rCldwXob09tkrlwmU0U3gA
-                i47tD0orh5Jhos7bwpG9gNjoW36LVLrGhfe6193zgl1nrxMdiu+qHQZc+eNg
-                qiqEF2x1nDD06EzSL4Tb8UMu2rSrfb/FYNb9XuB621xlL+yMCDV4yKn8uRA+
-                cVDvwBqdW5yWSH8Ssur+SC/TJjXM00dLhjrIh2Rtk1YRs/gVk8XlL5j+FOU9
-                IjkFtf1N6KhQ/iZWyJsbZRPqVXUnZM2cQjfJmo1yFLatzoh0vPgZ0x9/wyai
-                YCWCS40SxnAjkGvk2xE0i5oBC1glqeM+CuOcGD1R6SJKEUWaBlXlmohVcb2K
-                G1XcxCKZuFXFEm43wULcwd0mEqEy8yGmQsyGmAuR/gWU18KgswQAAA==
+                H4sIAAAAAAAA/41TXU8TURA9d7v9YC20VEBARdSq26IsFBM1BQIhkDRWTShp
+                TPq0dNdyob1Ldu82PPZX+AP8BZpoTHwwDY/+KOPcbWNQEHzYmTM3M2fOvTP7
+                4+e37wCeYoXhmS0c3+POidX0Osde4Fp+KCTvuFZN2MfBgSdr0pbuS5k/9j0n
+                bLpRmF9JglFx9dDu2lbbFi3rzf6h25Tl6r/5VOHq3l55vcyQ/bswCZ1h7vLi
+                JBIMiVUuuFxnmDTPdy/UKcGkHgrEzEI9jRSuGYgjzRDv2u3QZcidr0tjDJkR
+                aMgy6PKABwwvLrnJpS9DtxvNK43cbtcHHVMtVw7hhFk43560mQVSTZojO149
+                8mSbC+uVK23HljadaZ1ujIbGlEkpAwZ2ROcnXEVLhJxlhrV+b9To9wxtWjO0
+                lF5k/V7KmO73SqmcntOe93tLbHcqq80q+Pb0vX76IWEYWjY+q6diWV2RlBjm
+                r5giyTH/93WSeMCQPvtEDK0LRte4YJeGr3DY7VjvQtGU3BOBtTNEpXLhKplp
+                PIJJy/aHpMUjyTBS4y1hy9AnNfqW55DLVLlwX4edfdffs/fb0aJ4TTVDn6t4
+                eJiuCOH6W207CFxak8y2aLa9gIsWzerAcxiMmhf6TXeHq+yZ3YGgOg84lW8K
+                4ZEGdQ8s07rFaYj0JyGn9o/8Ak1SwzR9NGSohXxMaIe8OjGKXzFaXPiC8U9R
+                3hOyY1DT34COTcrfwCJFU4NsYr2u9oTQxBl2g9BklKO4LbVG5OPFzxj/+Js2
+                ER1uRnTpQcKQbkByg2IromZRM2AGS2R1PERhmBOjKypfRIn8GmXOUNVsA7EK
+                blZwq4LbmCOIOxXM424DLMA93G8gESiYDzAWYDLAVIDML8ZgJ06zBAAA
                 """,
                 """
                 androidx/compose/runtime/SnapshotStateKt.class:
-                H4sIAAAAAAAA/91XbVMb1xV+riSkZS3DshgD6xgTW7ZBGISJa7dGpXVwiFXA
-                L4HQONhNFmmBBWlX3bsiuG+haZt/0Q/tL0g/JalnOoz7rT+l/QudTs9d7UpC
-                b0j2ZKZTzazu3XvPec5zXvbs3X/8569/A3ALf2CY0K2cY5u5w1TWLhRtbqSc
-                kuWaBSO1ZulFvmu7a67uGstuDIxB2dMP9FRet3ZSj7b2jCythhn6coZjHhg5
-                T/LRNsP8xEq94PzkSktL92vU5xneT6/fbdRfmFhf7xQkTaILhHRlxXZ2UnuG
-                u+XopsVTumXZtG/aNH9ouw9L+TxJTXaEmSkU8zH0MkTTpmW6CwxDzbzciOMM
-                4jJknGW42hFyDP0MPQd6vmQwqI2YFOBCydW38sbrBni1Rv21A1wLEgS4dehq
-                pcuhOy9juH1QanViGKVg1Pq9YnJX+D4z0YbkiaIVGkQy08LdbmACh5Odq8Qw
-                xhCeKFfEuIxLeJthoNajVb0oHJrumAkpEIdP0stN/Nl4Ix8JOb2+PL++cUpa
-                65ViuCbjuvAsXnTsXClb9oxhu0mFNlnZt928aaX2Dgqp7ZKVLT+aS/5srl05
-                BsX8z9bF3LW99HRre49r3FvL2kX/GZgOILO2Y5dc0zJ4atEmFavkNZp0ReBD
-                6hqkMNWE7Kl+BuV3tbXconcvaovkEu0aH3U9X0zyc+ZImGEYqwmOabmGY+n5
-                VMZyHUIwszyGWep52V0ju+/3zse6oxcMEmS43j7dawJkx+uOc3hHxk3cYrjT
-                6asnUVtaiZsx3JZxR7SSsfZRi+EHVJeiW5t6fqPcXyP7xoubDOOnVR7DYWcV
-                /F3U9L+7qun/uyp/zcKYi+HHMu6JwhBZnmPYaZLCze8kY/9qnbHuDf7PJ0iE
-                l0tYeu1UvRPDAxkZkarBJvGhzrRjuP4T++nEaeFvHWDH2M7TfWqZwlY0HPcF
-                udjEWrFF9k4Lx5QXjy7Mp5MUZFISp0h31+QLEh6V27C3LeEJw7mJJhzjWMHa
-                GdzFOsPZhJnYTlQDxDJ0QkwIuJrF8dNrNiZUCJ9Bax0vYscroLttInLijNlN
-                Rpodohk+6zoljefTLhMjjr/0gnqG+Blo+CQIdNV9P8jVhesdH7kHAsurhqvn
-                dFentVDhIEyfYUz8SeIPlMt9MQnR5qEpZvTKDeVustCfjo8+ko+P5NBISA5J
-                EW+s3Ib9MVQdFbEZLASXEqoqKAMVHLrXLpGCJqkRNfQgNMsuR6TjIyU0F1XC
-                Gi28+nM0pEQ0VempiER9EW1MiWl93mKv9y/PSuWtXhqYIhPymYpWvBnwWW1H
-                6auI9FdFFCEyJykDWmSEzao0G/Rn08o5bVJiqqwGaueD+ezI7LAaVT252SFh
-                QBp9EPv7N+z4yLOmac87s/YGNi5o++1snFfe0uKqRNhlhIuX39jimHZLuSTA
-                fVvJinHyaNz3SFbe1qIqZXv28oNXX8qe4hUtrSQ0wq9XjDdXDDJXAbj66osQ
-                lZE0Kgp1ru0jUfeZz6iV3ejuS26qq+8ktkwXtRKIr2r/8as94LUx3vCWna85
-                MrZ4xZLIWCDy3qFr0KHZtgJ76y88DOUEzZl9l96li3aOWkn/CgE+LBW2DGdd
-                NA7B2c6KY6tjint/sXfN3LF0t+TQ/MIHZbYZ68DkJm3fq57y6ROgfrdyWj8h
-                Fs9YluEs5nXODbqV1+ySkzWWTGFs1IfYaICnA3wIEdGy0ItR9CCKMH5Fd7dp
-                pIgj/hLy0+TX6DuG8pXoaPg1/Ue9PQW/ERJlOQxApfFzTyaGI19KonEUgzjX
-                iDsscEeOodXjjrTEHarDvYC3fNxx2hU/6SUuPf0al7/yunAVU/MRLtYhXEGi
-                EeE6IUzUI1z0Ea7WIUwiSREUCI8JSfR69Yaa+gbfe4k7wsPvH+PuSQ+juOZ5
-                OF6WxrznoZil6WLebAY/JI2yxSnPokyzG4IfXb+lq99752Da+w+oLPhUPiZo
-                kVZ12qdyT1B5twmVOY9KsizdlMoiXaEKqbBP6kdNSQ1FakidpHbfp7bhR2lk
-                Sn2fqAWxygiCP2kgGCeT1ViNVAiOYAnLfrXUxuq9drGSagitYNVP/HP/ERhK
-                qo89Qh/Qf3gh+S0+ZDjJpo+sBuHqoyrfwE89XkP4CE89XkMU+nLghvAEmxVe
-                Dz0eg+EKi9rgPCMOZS4FEu2hcfgEl9uR5PS3+DSEv1TYCA/7yYXzhCwY3SK1
-                foLTiZFwZhhbyHqMhiuMhn1GYiaeqiCVPwtS18gNJPSF9/iE6UsdHtt7/pjx
-                x995IL/E72n8I+nliIqxiXAG2xnsZLALM4M97GeQR2ETjMOCvYlrHD0cRY6f
-                cwxwRDkucDgcVzg4h8tR4hjkyHKc45jkeMoxz5HmOOBY5Jjh+IzjkOOFt/IL
-                jgWOJMeSd3ufY4XjY44nHJscqxzPOJ7/F4J6TSkwFwAA
+                H4sIAAAAAAAA/91Y61cbxxX/jQBJyDKs1+Yl21ixsc3DIMDESQzFsYkfKhg/
+                UHDwI8kiFlgjdolmRUzbJE7apE36btNH2qSP9N2mbdovcepzejjut/4p7R/Q
+                Lz09vTPaFULsCmQ35/j0w+7Mzty593d/985r//6fv/wVwAD+yNCumTNZy5i5
+                lUhbi0sW1xPZnGkbi3piwtSW+LxlT9iarY/aITAG5aa2rCUymjmXuDB9U09T
+                axVD3YyeNZb1GSl5YZZhsH2sVHCwY8zX0lNFwwcZzg6ljm8cP9yeSm1VyRCJ
+                DpOmA2NWdi5xU7ens5ph8oRmmhb1GxbVxy17PJfJkFTHlnQmF5cyIdQyBIcM
+                07CHGRq8vJyMYhuiEUSwneHgljSHUM9Qs6xlcjqDulEnEbyYs7XpjF4gOONh
+                2p8aN5Lnc3nnL1oZI71SjszzRfbI/kv+EanUaj40WzTtxjG4JMeG0cjQumDZ
+                GcNM3FxeTBimrWdNLZNImnaWAmykeQjNFJn0vJ5ecCJ8UctqizoJMhz2om2t
+                ZUIomZMxjGF3BC3YUy47ipHms6M1gn3l4148JoRHGPoqDhtD4/p0aJvRZ7Vc
+                xmZ45X+RFsmK5m5JpjRzO5tL27msljn9Qk7LGPZKXi3D0fYyanywRHEIhyMI
+                oD2Kndglap00R4r9HzO4LaZEz1bUF0YQ1KRPUleixk3Qzq0PCSHBUNWeXyj6
+                IuhFP8OOYo/Oa0vCoe4tI6EBhOG5oVEPfyYfyEfSPJQaHUxNSi/9p0LpoBAe
+                i+Bx4Vl0KWvN5NJ5zxhmy89At6Vojs/mzHR+xT7j1PrL5aObiP8os2RVam+o
+                29/exSL3JtLWkrNmdbsq01bWytmGqfPEiEVDzJzM76GCwNO0mdCALg+wm/rp
+                pt9Bf7kR+S1yi+Tayu2HtFQ6YmEnZtkwTjA8ttUTQltxqNv6QjgZwSmxHLaW
+                9yKEpyhPxKZqaJnJ/DZYvaCv9DHEN8sEhltby6hPIsf+XVGO/d9l3X0mRn8I
+                oxGMicQQUaY1Ys4jhNc+kYj90z9ilRt86AMk6OVhXLrvUB0NYSKClAjVTg9+
+                aKWY021nxj7fvhn9/gRn9dkMfSdGibYlPWuLs6mHtSWf6G1GR5fkowLzQ51E
+                Mg0Sh3173uDDYVzNL4uyO4zrDLvaPTBGcQXPbsNpPMewvc1om21bI4gl6SDf
+                JtQVNcY3z9mQGEL6GWL+fBE6XlA6X4aRdee1SiLidddheLHikGw831cYGHEN
+                pMPTHKLbsB83XaLX3HdIXms4vOXjawtZ1LO6KXai0vPr+P2fF72uQAz9vuMu
+                +6EI4QWKdHJ8InVyfOQ0w4C/bV8dlKQcdi2yyDG8Z9K2H0/Lg0B8Wqcat+O2
+                FTcts1t22StLetw10uMY6XGM9Pg5GLdmNx/kLDk9vpzTtHuRTgbFl7koVvI3
+                s88wJCrkPYTP0X2rzHzzvrmE8DJdXsrNU+9xkufbtXgFrzK8+xDw7Hc1I5o/
+                z6CY+rKelT1uxvuf98dLZEN4g6HLn6NSecnNl2rxRbzJ8PZDwE2p88TJl+la
+                5i5E53Vbm9FsjWZtYHG5CgATr7B4gZb2BVEJUOctQ9R6qTbTxwL/Wr39bGT1
+                diTQHIgEwtWyLHxWeX0GwvQoolFUmoseJbAmqOygMuh+x/bRgFhYrVYD5wK9
+                bH91ePW2EugPKlUxarj3fjCgVMdUpaYgEnREYq1KKFYnG2vlO9IbznfVUsGU
+                SCyhbCuMipYo7q8LB5Tthe46aaieDClrba6hOWVHoVFd07NT6gkru2LVzay3
+                gWqNTq1baYp1hJkaUd1hLW69d3dvTA2qUq63WVgN7zkX+tsdtnpbQtgbu7E1
+                aw9gozW2UM5Go7IvFlXDpDuvIb7/gS0+QsTu30isqhzY2DigtAkYzmdnASb5
+                ftDxPaIcigVVSp7ew+fuvRGRJtpjQ0pHjJCUDox6D3QToaCg895rAUrycItI
+                //6y+27JL1+WYjhS2e+bMquNx88RNkoPnVcg/rA6k7r4FlnG+Iaj/GDRvdTn
+                HE8ira7I6Vu2bnJqdO2lVqQOZR3MngWbDuwj1gydV+rHSOF4bnFaz6bE6URg
+                ttLibpw1xLfTWDthzJkaLehU3305jzZpLhvcoO6Ta1d7uveX9hb+ia4T205I
+                0gtEmGMgmjRNPTuS0TjXqTsyYeWyaf2MIfpaHJWTG8yhDwFUi4UR22mjrkEQ
+                VfgFfR2jkiKA6F1Epjo/Qt0qlA/Fuolf0jso+xT8Skjk5bADKpW/ljIh/MaR
+                ClPZIn4HkhWh9wzpDVCpdqlNd7D3LvYJ7fFV7F+vPYjdUntjXtrRLmqNOED9
+                eTsN6+z8lp7agFzk6VOpRRsOUl2YfcJxU9lT8/I7CN1Bx1hn1x105Y3+jt7k
+                bkRar4PYFZpJawwRKltwBN0OK3GJhvaSu+id+ghHP5TG1hjZ6+DqKfF/AI9u
+                1PA4aXiiVEPc0XCsRMNxDDoMXiRNAqF6RH1SMnhKMDiyitOlDHZIBuN5aWLe
+                ZfAsPUzWTuAcjchbHJIWxV/bTwl8Dp/1cv/EsMuqhJJ0oFwl1YJVtduBMiag
+                nPeA8qiE0pmX9oQyTk+gAKrKAfVpT1AN1UWg1kO74ECbdFhq7lIvEzSXq5QA
+                +PQGgFE8WcRVcwFgMy6RJiZrxVxdLMdVuAjQFTzjBP6Gk4ENneo1CegGvauG
+                Oz/G8wzr0dQRwS5ddTSXNExLXA1IY0biaoDuENeA65gt4JqSOHZWFVAUkzOH
+                eQfLIonWUNm0Dsux6s7uj7EQwJ8KaISH9eRtI/EgEA3QsHpSlyFEwpkmUmVK
+                RE0FRE0OIlETs9YNpeGGbiM2gc7CYQfdQeksLUh/xvKUeusOPruKl0rnyVVH
+                61LJPDnkpea1KfUL3mrSPmpe91Lz1pT6FW81C55qqvABvWNUnnKcHHPKlFP+
+                Xo76Of5A5Qc06qvE79euoSqJryfxjSS+iW8l8W28ncR38N1rYBzfw/evoYuj
+                huMdjh9w7OAIchzh+CHHAMe7HO9x/IhjJwct740cBzh2cbzOcZxjhuMMx1mO
+                H3OMc5zg+AnHTznely0/40hyDHJckp8XOCyOQxxXOHSO6xyzHM9wzHHM/xdf
+                uMMflh4AAA==
                 """,
                 """
                 androidx/compose/runtime/SnapshotStateList.class:
-                H4sIAAAAAAAA/41Qy0ocQRQ9VT0v24n2+IijJpqlGcRWEQQVIQrCQJuAM8xm
-                VjXThdY8qqSrRlz2t/gHWQVcSOMyHxW8Pbox2WRz7j2nDvfeU7//PD4BOMAX
-                hobQcWJUfB/2zfjWWBkmE+3UWIYtLW7tjXEtJ5yMlHVlMIatk/ZRNBB3IhwJ
-                fR3+6A1k3x2f/isxBH9rZRQYSidKK3fK4G197VRRQtlHERWGgrtRlmE7+v+L
-                aEktGho3Ujq8lE7EwgnS+PjOo3wsh0oOYGBD0u9Vznapi/coSpZWfV7nfpb6
-                PCDI0nqWNgqVLA3YPt/lZ8XnhxIPvNy/TyPaLJ8UvDtjZ+jo9HMTS4b5SGn5
-                fTLuyaQteiNSFiLTF6OOSFTO38SZlrrWwk0S6v2WmSR9eaHyh9Wr16AdZRU5
-                v2ltaIUy2mIPnH7pLUr+aYRrxMIpB4qNX5j5SQ3HOmFpKq7jE2H11QAfs1Q9
-                fJ66PGxM6yo2qR6Sp0qeD114Tcw1Md9EgBq1WGhiEUtdMItlfOyiYDFrsWJR
-                tyi/AEh/yvNKAgAA
+                H4sIAAAAAAAA/41Qy0ocQRQ9VT0v20nsUaNjYh5LHcRWEQKJCCYQGOgk4Ayz
+                mVXNdKE1jyrpqhGX/S3+gSvBRWiyzEcFb41uNJtszr3n3MN9/fl79wvAIT4w
+                tIROM6PSq3hophfGyjibaaemMu5ocWHPjes44WSirKuCMWwddT8lI3Ep4onQ
+                Z/HPwUgO3efjfyWG6LlWRYmhcqS0cscMwdZ2r44KqiHKqDGU3LmyDDvJ/29E
+                QxrJ2LiJ0vF36UQqnCCNTy8Duo95qHkAAxuTfqU826Ms3adTirwe8iYPizzk
+                EUGRN4u8VaoVecQO+B7/Uv59XeFR4P0H1KLLfKfoyRq7Y0erfzWpZFhKlJY/
+                ZtOBzLpiMCFlOTFDMemJTHn+KC501JkWbpZRHnbMLBvKb8oXNk4fDu0pq8h5
+                orWhEcpoi31w+tLjKf5phK+JxXMOlFu3WLihhOMNYWUuvsMmYf3BgBCLFAO8
+                nbsCqvq4gfcUP5KnTp4XfQRtvGxjqY0IDUqx3MYKVvtgFq+w1kfJYtFi3aJp
+                Ub0HArlo6UoCAAA=
                 """,
                 """
                 androidx/compose/runtime/SnapshotStateMap.class:
-                H4sIAAAAAAAA/42Qy04bMRSGf3tyY0hhoFxCb7S7QqUOoK4gQqKVKkUMrdRU
-                s8nKyVhgktjR2EEs51n6Bl0hdYFGLHkoxHFg08uiC//nnM+/j318e/frGsAH
-                vGHYEjrLjcou44EZT4yVcT7VTo1l3NViYs+M6zrh5ImY1MEY2u3j/eRcXIh4
-                JPRp/LV/LgfuIP0HO/wbMUR/sjoqDLW20sodMgRvt9ImaqiHqKLBUHFnyjK8
-                S/77kXTHUjI0bqR0fCKdyIQTxPj4IqCJmZeGFzCwIfFL5asdyrJdhrgsFkLe
-                4iFv0IrKIiyLVllsVxplETEKLOJ7fCf4WL35UeNRxR/bo07HtFLmm0a/Pej9
-                0NEQn0wmGRYTpeWX6bgv8++iPyKynJiBGKUiV75+hHNddaqFm+aUh10zzQfy
-                s/IbG98eRk6VVeQ80trQFcpoi11w+q/Hqfz3kT6nKp7VQHX7CnM/KeF4QVqb
-                wVd4Sdp8MCDEPMWAqHcF2JzFZ3hNcZ88TfI86SHoYKGDxQ4iLFGK5Q6eYqUH
-                ZrGKtR6qFvMW6xYtiw2L+j3Q7/VyagIAAA==
+                H4sIAAAAAAAA/41Qy04UQRQ9t3peNCM0iDr4ZieY2EBc4YRETUwmNJo4pjez
+                qpmuQDEzVZOuGsKyv4U/YEXiwnRc+lHG2wMbHwsX99x7T526rx8/v34D8Bpb
+                hG1pstzq7CIe2enMOhXnc+P1VMV9I2fu1Pq+l14dy1kTROh2jw6SM3ku44k0
+                J/Gn4Zka+TfpP7jDvylC9CfXRI3Q6Gqj/SEheLGdttFAM0QdLULNn2pHeJn8
+                95DcYy0ZWz/RJj5WXmbSS+bE9DzgjamCVgUg0Jj5C11luxxle4S4LFZC0RGh
+                aLFFZRGWRacsdmqtsoiIHUViX+wG7+rfLxsiqlXf9rnSEVtKVdHot4FejT0v
+                8d5mirCaaKM+zqdDlX+Rwwkz64kdyUkqc13lt+RSX58Y6ec5x2HfzvOR+qCr
+                h83PNyun2mlWvjXGcgttjcMeBN/rdqvqfIyPOIsXOVDfucbSFQcCjxkbC3IL
+                TxjbNwKEWGYf4OlCFeDZwj/Ec/YHrGmz5s4AQQ8rPaz2EGGNQ6z3cBcbA5DD
+                PdwfoO6w7PDAoeOw6dD8BRdS9ZhqAgAA
                 """,
                 """
                 androidx/compose/runtime/State.class:
@@ -817,6 +943,31 @@
                 a2AJMy3V18KOR1wOWsl41JWnKmaydvE+61IZdR3LP1on3KQSbTz+H0VMd+N7
                 eeC7Y42ZAx/u/8xFbYpVrDMe84sZ7gk6cBuYbWCugXkscIrFBkKUOyCDCn50
                 4BksGSwbrBismpyW3gBNs/uhAwIAAA==
+                """,
+                """
+                androidx/compose/runtime/StructuralEqualityPolicy.class:
+                H4sIAAAAAAAA/5VVW08bRxT+ZteX9WLAcVJqCE2ThjbmljWkd1xaQohi5FBU
+                R1QtT2N74gysd53dWStRX1B/Sp/70KgPiVqpQu1bf1TVM7suJQYikOU5Z845
+                c+Y7t9m///ntDwAfYoNhiXvtwJftZ07L7/b8UDhB5CnZFU5DBVFLRQF3N55G
+                3JXq+bbvytbzLBjDt/U93ueOy72O83VzT7TUSv1sTx7vhU989TBSXEnfS/xU
+                T7pYXWEoDEuzSDE4F3SeRYYhU5WeVKsMZnl2Jw8LORtp2Awp9USGDHfeAPmM
+                4AmgLZ5Gss9d4SmGW+VTEnFCMvs9w0zdDzrOnlDNgEsvpIA8P0EcOluR6/Km
+                K8j7tX1fudJz9vpdR3pKBB53nZqnAjojW2EWlxgsHogYVh6XMW6jiCsMjDMU
+                T15NiiadUH5Du+gwXCnPHrNKpGR1803wfKURklXprLxYmGZId0XQEQyb50rK
+                KWk6DX71gpWfuSce88hVtW7PpXRdZ/ihfNHWPBfac+HP4xres3EDN6kIvUD0
+                pR9R52VbURDEDZTlvZ4rRZvU1ZYb96sNQzepVdtqPFrbWt/IYw6jORLOM1yq
+                D/rjoVC8zRWnDBndvknjzPRi6QVU9H2SP5N6VyGuvcQgDg+mbaNkJP/C4YFt
+                WJoZIWoSHbP++tEoHR4s28VMMVViFaPC7mYt48+fMkbB3JwupKaMSnrZKmSm
+                Yi1x2YR7MLFpFSzS5h5M6MuW6Vm5cMqZhp0/Xjx6C/6zbZCpuL1P+br6TeKm
+                5vVlKGlm1v5vVBrsdb9NDThel57YirpNETzSc6Unw29xd4cHUu8HwplhX9s8
+                4F1BQ/ea03zN80Sw7vIwFLTNNWTH4zQD5MFu+FHQEveldjc5cLdzAhgqVL00
+                xUdvJyZ1OYlWqTYZoleJpklPzxPtvqCdowuopXMvMfKCGAOrA2NA4Eta84kB
+                0dG43mMYJyt9+B5RXfbM/MIrvPXz0OnH8enricXgtOYm8Hasz6BEnIGviB81
+                SFSI3SfrJKYGlywOEJrFd34ZuqFzDJ85uOF4qPTE4V3SaDfbSNGPunZufmHx
+                FWaGfSWxziU2R2gtvD9Aa+GDGK3mbhFnHt2kAesYLptDMRRi4/JRrpPjwMjv
+                ML57idlfsfAiFqSwRqtNZjeobJ9T8HdjdCbWY7pCmQZqpF+kOtzehVmDU0Ol
+                hiUsE4s7NfrCfrQLFuJjfLILO8RoiE9DfBYiF2IsZiZClEJMEv8v0hejE5UH
+                AAA=
                 """
     )
 
diff --git a/compose/lint/common/src/main/java/androidx/compose/lint/KotlinUtils.kt b/compose/lint/common/src/main/java/androidx/compose/lint/KotlinUtils.kt
index 9ec00a4..5a39288 100644
--- a/compose/lint/common/src/main/java/androidx/compose/lint/KotlinUtils.kt
+++ b/compose/lint/common/src/main/java/androidx/compose/lint/KotlinUtils.kt
@@ -16,12 +16,17 @@
 
 package androidx.compose.lint
 
+import org.jetbrains.kotlin.psi.KtElement
 import org.jetbrains.kotlin.psi.KtLambdaExpression
 import org.jetbrains.kotlin.psi.KtParameter
 import org.jetbrains.kotlin.psi.KtSimpleNameExpression
 import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
 import org.jetbrains.kotlin.psi.psiUtil.isAncestor
+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
 import org.jetbrains.uast.ULambdaExpression
+import org.jetbrains.uast.kotlin.KotlinUFunctionCallExpression
+import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
+import org.jetbrains.uast.sourcePsiElement
 import org.jetbrains.uast.toUElement
 
 /**
@@ -143,3 +148,10 @@
             else -> true
         }
     }
+
+fun KotlinUFunctionCallExpression.resolveCall() =
+    (sourcePsiElement as KtElement).getResolvedCall(
+        context = sourcePsi.project
+            .getService(KotlinUastResolveProviderService::class.java)
+            .getBindingContext(sourcePsi)
+    )
diff --git a/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt b/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
index 71b1990..f51de29 100644
--- a/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
+++ b/compose/lint/common/src/main/java/androidx/compose/lint/Names.kt
@@ -41,6 +41,10 @@
         val State = Name(PackageName, "State")
         val MutableState = Name(PackageName, "MutableState")
         val MutableStateOf = Name(PackageName, "mutableStateOf")
+        val MutableIntStateOf = Name(PackageName, "mutableIntStateOf")
+        val MutableLongStateOf = Name(PackageName, "mutableLongStateOf")
+        val MutableFloatStateOf = Name(PackageName, "mutableFloatStateOf")
+        val MutableDoubleStateOf = Name(PackageName, "mutableDoubleStateOf")
         val MutableStateListOf = Name(PackageName, "mutableStateListOf")
         val MutableStateMapOf = Name(PackageName, "mutableStateMapOf")
         val ProduceState = Name(PackageName, "produceState")
@@ -50,6 +54,7 @@
         val LaunchedEffect = Name(PackageName, "LaunchedEffect")
         val ReusableContent = Name(PackageName, "ReusableContent")
         val Key = Name(PackageName, "key")
+        val StructuralEqualityPolicy = Name(PackageName, "structuralEqualityPolicy")
     }
     object Ui {
         val PackageName = Package("androidx.compose.ui")
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt
new file mode 100644
index 0000000..b013276
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetector.kt
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+@file:Suppress("UnstableApiUsage")
+
+package androidx.compose.runtime.lint
+
+import androidx.compose.lint.Name
+import androidx.compose.lint.Names
+import androidx.compose.lint.isInPackageName
+import androidx.compose.lint.resolveCall
+import com.android.tools.lint.detector.api.Category
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Implementation
+import com.android.tools.lint.detector.api.Issue
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.LintFix
+import com.android.tools.lint.detector.api.Location
+import com.android.tools.lint.detector.api.Scope
+import com.android.tools.lint.detector.api.Severity
+import com.android.tools.lint.detector.api.SourceCodeScanner
+import com.intellij.psi.PsiMethod
+import java.util.EnumSet
+import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
+import org.jetbrains.kotlin.psi.KtTypeArgumentList
+import org.jetbrains.kotlin.psi.KtValueArgumentList
+import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.kotlin.KotlinUFunctionCallExpression
+import org.jetbrains.uast.skipParenthesizedExprDown
+
+/**
+ * Suggests alternative functions to mutableStateOf<T>() if all of the following are true:
+ * - a snapshot mutation policy argument is not specified (or it is structural equivalent policy)
+ * - `T` is in the [replacements] map
+ * - `T` is a non-nullable type
+ */
+class AutoboxingStateCreationDetector : Detector(), SourceCodeScanner {
+
+    /**
+     * Map of canonical PSI types to the fully-qualified function that should be used to
+     * create MutableState instances of said type.
+     */
+    private val replacements = mapOf(
+        "kotlin.Int" to Names.Runtime.MutableIntStateOf,
+        "kotlin.Long" to Names.Runtime.MutableLongStateOf,
+        "kotlin.Float" to Names.Runtime.MutableFloatStateOf,
+        "kotlin.Double" to Names.Runtime.MutableDoubleStateOf,
+    )
+
+    override fun getApplicableMethodNames() = listOf(Names.Runtime.MutableStateOf.shortName)
+
+    override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+        if (!method.isInPackageName(Names.Runtime.PackageName)) return
+
+        val replacement = getSuggestedReplacementName(node as KotlinUFunctionCallExpression)
+            ?: return
+
+        context.report(
+            issue = AutoboxingStateCreation,
+            scope = node,
+            location = context.getNameLocation(node),
+            message = "Prefer `${replacement.shortName}` instead of `${method.name}`",
+            quickfixData = createLintFix(context, node, replacement)
+        )
+    }
+
+    private fun createLintFix(
+        context: JavaContext,
+        node: UCallExpression,
+        replacementFunction: Name
+    ): LintFix {
+        val fixes = listOfNotNull(
+            // Replace the function name
+            LintFix.create()
+                .replace()
+                .range(context.getNameLocation(node))
+                .with(replacementFunction.javaFqn)
+                .shortenNames(true)
+                .build(),
+
+            // Remove the type arguments list (if present)
+            context.getLocationOfTypeArguments(node)
+                ?.let { LintFix.create().replace().range(it).with("").build() },
+
+            // Remove the SnapshotMutationPolicy argument (if present)
+            context.getLocationOfArgumentsList(node)
+                ?.takeIf { node.getArgumentForParameter(MUTATION_POLICY_PARAM_IDX) != null }
+                ?.let { argsListLocation ->
+                    node.getArgumentForParameter(VALUE_PARAM_IDX)?.sourcePsi?.text
+                        ?.let { valueArg ->
+                            LintFix.create()
+                                .replace()
+                                .range(argsListLocation)
+                                .with("($valueArg)")
+                                .build()
+                        }
+                }
+        )
+
+        return LintFix.create()
+            .name("Replace with ${replacementFunction.shortName}")
+            .composite(*fixes.toTypedArray())
+    }
+
+    private fun JavaContext.getLocationOfTypeArguments(node: UCallExpression): Location? {
+        val typeArgsList = node.sourcePsi?.children?.firstIsInstanceOrNull<KtTypeArgumentList>()
+            ?: return null
+        return getLocation(typeArgsList)
+    }
+
+    private fun JavaContext.getLocationOfArgumentsList(node: UCallExpression): Location? {
+        val argsList = node.sourcePsi?.children?.firstIsInstanceOrNull<KtValueArgumentList>()
+            ?: return null
+        return getLocation(argsList)
+    }
+
+    private fun getSuggestedReplacementName(
+        invocation: KotlinUFunctionCallExpression
+    ): Name? {
+        if (!usesStructuralEqualityPolicy(invocation)) return null
+
+        val resolvedCall = invocation.resolveCall() ?: return null
+        val stateType = resolvedCall.typeArguments.asIterable().single().value
+        return when {
+            stateType.isMarkedNullable -> null
+            else -> replacements[stateType.getJetTypeFqName(true)]
+        }
+    }
+
+    private fun usesStructuralEqualityPolicy(
+        invocation: KotlinUFunctionCallExpression
+    ): Boolean {
+        val policyExpr = invocation.valueArguments.getOrNull(MUTATION_POLICY_PARAM_IDX)
+            ?.skipParenthesizedExprDown()
+            ?: return true // No argument passed; we're using the default policy
+
+        val policyMethod = (policyExpr as? KotlinUFunctionCallExpression)?.resolve()
+            ?: return false // Argument isn't a direct function call. Assume it's a more complex
+                            // policy, or isn't always the structural equality policy.
+
+        return policyMethod.isInPackageName(Names.Runtime.PackageName) &&
+            policyMethod.name == Names.Runtime.StructuralEqualityPolicy.shortName
+    }
+
+    companion object {
+        private const val VALUE_PARAM_IDX = 0
+        private const val MUTATION_POLICY_PARAM_IDX = 1
+
+        val AutoboxingStateCreation = Issue.create(
+            id = "AutoboxingStateCreation",
+            briefDescription = "`State<T>` will autobox values assigned to this state. " +
+                "Use a specialized state type instead.",
+            explanation = "Calling `mutableStateOf<T>()` when `T` is either backed by a " +
+                "primitive type on the JVM or is a value class results in a state implementation " +
+                "that requires all state values to be boxed. This usually causes an additional " +
+                "allocation for each state write, and adds some additional work to auto-unbox " +
+                "values when reading the value of the state. Instead, prefer to use a " +
+                "specialized primitive state implementation for `Int`, `Long`, `Float`, and " +
+                "`Double` when the state does not need to track null values and does not " +
+                "override the default `SnapshotMutationPolicy`.",
+            category = Category.PERFORMANCE, priority = 3, severity = Severity.WARNING,
+            implementation = Implementation(
+                AutoboxingStateCreationDetector::class.java,
+                EnumSet.of(Scope.JAVA_FILE)
+            )
+        )
+    }
+}
\ No newline at end of file
diff --git a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
index 8a2444e..1ead6c8 100644
--- a/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
+++ b/compose/runtime/runtime-lint/src/main/java/androidx/compose/runtime/lint/RuntimeIssueRegistry.kt
@@ -31,6 +31,7 @@
     override val minApi = CURRENT_API
     override val issues get() = listOf(
         AutoboxingStateValuePropertyDetector.AutoboxingStateValueProperty,
+        AutoboxingStateCreationDetector.AutoboxingStateCreation,
         ComposableCoroutineCreationDetector.CoroutineCreationDuringComposition,
         ComposableFlowOperatorDetector.FlowOperatorInvokedInComposition,
         ComposableLambdaParameterDetector.ComposableLambdaParameterNaming,
diff --git a/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
new file mode 100644
index 0000000..06eb0d1
--- /dev/null
+++ b/compose/runtime/runtime-lint/src/test/java/androidx/compose/runtime/lint/AutoboxingStateCreationDetectorTest.kt
@@ -0,0 +1,505 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.runtime.lint
+
+import androidx.compose.lint.test.Stubs
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+/* ktlint-disable max-line-length */
+@RunWith(Parameterized::class)
+class AutoboxingStateCreationDetectorTest(
+    typeUnderTest: TypeUnderTest
+) : LintDetectorTest() {
+
+    private val fqType = typeUnderTest.fqName
+    private val type = typeUnderTest.typeName
+    private val stateValue = typeUnderTest.sampleValue
+
+    private val primitiveStateStub = kotlin(
+        """
+        package androidx.compose.runtime
+
+        import kotlin.reflect.KProperty
+        import $fqType
+
+        fun mutable${type}StateOf(value: $type): Mutable${type}State {
+            TODO("Not implemented in lint stubs.")
+        }
+
+        interface Mutable${type}State : State<$type> {
+            override var value: $type
+            var ${type.toLowerCaseAsciiOnly()}Value: $type
+        }
+
+        @Suppress("NOTHING_TO_INLINE")
+        inline operator fun Mutable${type}State.getValue(
+            thisObj: Any?,
+            property: KProperty<*>
+        ): $type = ${type.toLowerCaseAsciiOnly()}Value
+
+        @Suppress("NOTHING_TO_INLINE")
+        inline operator fun Mutable${type}State.setValue(
+            thisObj: Any?,
+            property: KProperty<*>,
+            value: $type
+        ) {
+            ${type.toLowerCaseAsciiOnly()}Value = value
+        }
+        """
+    )
+
+    override fun getDetector(): Detector = AutoboxingStateCreationDetector()
+
+    override fun getIssues(): MutableList<Issue> =
+        mutableListOf(AutoboxingStateCreationDetector.AutoboxingStateCreation)
+
+    @Test
+    fun testTrivialMutableStateOf_thatCouldBeMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun valueAssignment() {
+                        val state = mutableStateOf<$type>($stateValue)
+                        state.value = $stateValue
+                    }
+                """
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                        val state = mutableStateOf<$type>($stateValue)
+                                    ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                         val state = mutableStateOf<$type>($stateValue)
++                         val state = mutable${type}StateOf($stateValue)
+            """
+        )
+    }
+
+    @Test
+    fun testInferredMutableStateOf_thatCouldBeMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun valueAssignment() {
+                        val state = mutableStateOf($stateValue)
+                        state.value = $stateValue
+                    }
+                """
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                        val state = mutableStateOf($stateValue)
+                                    ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                         val state = mutableStateOf($stateValue)
++                         val state = mutable${type}StateOf($stateValue)
+            """
+        )
+    }
+
+    @Test
+    fun testFqMutableStateOf_thatCouldBeMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun valueAssignment() {
+                        val state = mutableStateOf<$fqType>($stateValue)
+                        state.value = $stateValue
+                    }
+                """
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                        val state = mutableStateOf<$fqType>($stateValue)
+                                    ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                         val state = mutableStateOf<$fqType>($stateValue)
++                         val state = mutable${type}StateOf($stateValue)
+            """
+        )
+    }
+
+    @Test
+    fun testStateDelegate_withExplicitType_thatCouldBeMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun propertyDelegation() {
+                        var state by mutableStateOf<$type>($stateValue)
+                        state = $stateValue
+                    }
+                """
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                        var state by mutableStateOf<$type>($stateValue)
+                                     ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                         var state by mutableStateOf<$type>($stateValue)
++                         var state by mutable${type}StateOf($stateValue)
+            """
+        )
+    }
+
+    @Test
+    fun testStateDelegate_withInferredType_thatCouldBeMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun propertyDelegation() {
+                        var state by mutableStateOf($stateValue)
+                        state = $stateValue
+                    }
+                """
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                        var state by mutableStateOf($stateValue)
+                                     ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                         var state by mutableStateOf($stateValue)
++                         var state by mutable${type}StateOf($stateValue)
+            """
+        )
+    }
+
+    @Test
+    fun testStateDelegate_withInferredType_andInternalSetter_thatCouldBeMutablePrimitiveStateOf() {
+        lint().files(
+                primitiveStateStub,
+                Stubs.Composable,
+                Stubs.SnapshotState,
+                kotlin(
+                    """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    class Test(initialValue: $type = $stateValue) {
+                        var state by mutableStateOf(initialValue)
+                            private set
+                    }
+                """
+                )
+            ).run().expect(
+                """
+src/androidx/compose/runtime/lint/test/Test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                        var state by mutableStateOf(initialValue)
+                                     ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+            """
+            ).expectFixDiffs(
+                """
+Fix for src/androidx/compose/runtime/lint/test/Test.kt line 7: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                         var state by mutableStateOf(initialValue)
++                         var state by mutable${type}StateOf(initialValue)
+            """
+            )
+    }
+
+    @Test
+    fun testStateDelegate_withTypeInferredFromProperty_thatCouldBeMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun propertyDelegation() {
+                        var state: $type by mutableStateOf($stateValue)
+                        state = $stateValue
+                    }
+                """
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                        var state: $type by mutableStateOf($stateValue)
+                                   ${" ".repeat(type.length)}    ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                         var state: $type by mutableStateOf($stateValue)
++                         var state: $type by mutable${type}StateOf($stateValue)
+            """
+        )
+    }
+
+    @Test
+    fun testStateDelegate_withNullableInferredType_cannotBeReplacedWithMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun propertyDelegation() {
+                        var state: $type? by mutableStateOf($stateValue)
+                        state = $stateValue
+                    }
+                """
+            )
+        ).run().expectClean()
+    }
+
+    @Test
+    fun testInferredMutableStateOf_withExplicitEqualityPolicy_thatCouldBeMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun valueAssignment() {
+                        val state = mutableStateOf($stateValue, structuralEqualityPolicy())
+                        state.value = $stateValue
+                    }
+                """
+            )
+        ).run().expect(
+            """
+src/androidx/compose/runtime/lint/test/test.kt:8: Warning: Prefer mutable${type}StateOf instead of mutableStateOf [AutoboxingStateCreation]
+                        val state = mutableStateOf($stateValue, structuralEqualityPolicy())
+                                    ~~~~~~~~~~~~~~
+0 errors, 1 warnings
+            """
+        ).expectFixDiffs(
+            """
+Fix for src/androidx/compose/runtime/lint/test/test.kt line 8: Replace with mutable${type}StateOf:
+@@ -8 +8
+-                         val state = mutableStateOf($stateValue, structuralEqualityPolicy())
++                         val state = mutable${type}StateOf($stateValue)
+            """
+        )
+    }
+
+    @Test
+    fun testNonStructuralEqualityPolicy_cannotBeReplacedWithMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun valueAssignment() {
+                        val state = mutableStateOf($stateValue, neverEqualPolicy())
+                        state.value = $stateValue
+                    }
+                """
+            )
+        ).run().expectClean()
+    }
+
+    @Test
+    fun testNullableMutableStateOf_cannotBeReplacedWithMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun valueAssignment() {
+                        val state = mutableStateOf<$type?>($stateValue)
+                        state.value = $stateValue
+                    }
+                """
+            )
+        ).run().expectClean()
+    }
+
+    @Test
+    fun testInferredNullableMutableStateOf_cannotBeReplacedWithMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun valueAssignment() {
+                        val state: MutableState<$type?> = mutableStateOf($stateValue)
+                        state.value = $stateValue
+                    }
+                """
+            )
+        ).run().expectClean()
+    }
+
+    @Test
+    fun testInferredByCastNullableMutableStateOf_cannotBeReplacedWithMutablePrimitiveStateOf() {
+        lint().files(
+            primitiveStateStub,
+            Stubs.Composable,
+            Stubs.SnapshotState,
+            kotlin(
+                """
+                    package androidx.compose.runtime.lint.test
+
+                    import androidx.compose.runtime.*
+                    import $fqType
+
+                    fun valueAssignment() {
+                        val state = mutableStateOf($stateValue as $type?)
+                        state.value = $stateValue
+                    }
+                """
+            )
+        ).run().expectClean()
+    }
+
+    companion object {
+        @JvmStatic
+        @Parameterized.Parameters(name = "{0}")
+        fun initParameters() = listOf(
+            testCase("kotlin.Int", "42"),
+            testCase("kotlin.Long", "0xABCDEF1234"),
+            testCase("kotlin.Float", "1.5f"),
+            testCase("kotlin.Double", "1.024")
+        )
+
+        private fun testCase(fqName: String, value: String): TypeUnderTest {
+            val parts = fqName.split('.')
+            return TypeUnderTest(
+                fqName = fqName,
+                typeName = parts.last(),
+                packageName = parts.dropLast(1).joinToString(separator = "."),
+                sampleValue = value
+            )
+        }
+    }
+
+    data class TypeUnderTest(
+        val fqName: String,
+        val typeName: String,
+        val packageName: String,
+        val sampleValue: String,
+    ) {
+        // Formatting for test parameter list.
+        override fun toString() = "type = $fqName"
+    }
+}
+/* ktlint-enable max-line-length */
\ No newline at end of file