Skip to content

Commit

Permalink
Allow memoizing lambdas in composable inline functions
Browse files Browse the repository at this point in the history
Memoization was disabled in inline functions for legacy reasons while technically it can be allowed.

Test: compiler tests
Fixes: 340606661 ( https://issuetracker.google.com/issues/340606661 )
Change-Id: Iee8edda58f1e3a2b7e7dcc5ef1abcc663fab7fda ( https://android-review.googlesource.com/q/Iee8edda58f1e3a2b7e7dcc5ef1abcc663fab7fda )

Moved from: androidx/androidx@dc92291
  • Loading branch information
ShikaSD authored and Space Cloud committed Jun 5, 2024
1 parent a3982f2 commit a8249d6
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,21 @@ class LambdaMemoizationRegressionTests(useFir: Boolean) : AbstractIrTransformTes
val x = @Composable {}
"""
)

// regression test for b/340606661
@Test
fun testMemoizationInInlineFunction() = verifyGoldenComposeIrTransform(
"""
import androidx.compose.runtime.*
@Composable
inline fun Test(
someBool: Boolean,
) {
val someInt = remember { 1 }
val lambda = { someInt }
println(lambda.hashCode())
}
"""
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,13 @@ private class FunctionLocalSymbol(
private class FunctionContext(
override val declaration: IrFunction,
override val composable: Boolean,
val canRemember: Boolean
) : DeclarationContext() {
override val symbol get() = declaration.symbol
override val functionContext: FunctionContext get() = this
val locals = mutableSetOf<IrValueDeclaration>()
override val captures: MutableSet<IrValueDeclaration> = mutableSetOf()
var collectors = mutableListOf<CaptureCollector>()
val canRemember: Boolean get() = composable

init {
declaration.valueParameters.forEach {
Expand Down Expand Up @@ -459,11 +459,7 @@ class ComposerLambdaMemoization(

override fun visitFunction(declaration: IrFunction): IrStatement {
val composable = declaration.allowsComposableCalls
val canRemember = composable &&
// Don't use remember in an inline function
!declaration.isInline

val context = FunctionContext(declaration, composable, canRemember)
val context = FunctionContext(declaration, composable)
if (declaration.isLocal) {
declarationContextStack.recordLocalDeclaration(context)
}
Expand Down

0 comments on commit a8249d6

Please sign in to comment.