From edaa710c0e8d7c2818d8d8c31347eadccd7a2fcf Mon Sep 17 00:00:00 2001 From: Anders Fugmann Date: Sun, 12 Jul 2026 06:29:42 +0200 Subject: [PATCH] Kotlin: converge explicit `_` setter parameter name onto K2 An explicit property setter written `set(_)` produces a value parameter whose source spelling is the Kotlin discard placeholder `_`. The two frontends model this differently: * K2 preserves the source name and exposes the parameter as `_`. * K1 additionally flags the parameter with `IrDeclarationOrigin.UNDERSCORE_PARAMETER`, which the extractor treats as a synthesized name (no name is written and QL synthesizes `p0`). This made `test-kotlin1` report `p0` while `test-kotlin2` reported `_` for the same source (library-tests/underscore-parameters). The `UNDERSCORE_PARAMETER` origin is *also* set by K1 (and, for the synthesized cases, by K2) on discarded parameters that do not retain a `_` source spelling, most importantly: * lambda placeholder parameters, e.g. `{ index, _ -> ... }` * the synthesized `invoke` parameters of function types (funcExprs.kt lines 27/30/31/90/94) For those, the two frontends assign *different* internal names (`` under K1 vs `` under K2), so the synthetic-name treatment is exactly what keeps them converged at `pN`. Removing the origin check wholesale therefore replaces one small divergence with a much larger one. To converge only the case both frontends agree on, we suppress the synthetic-name treatment only when the parameter's own name is exactly `_` (the source discard spelling that both K1 and K2 preserve). This makes K1 emit `_` for `set(_)` (matching K2) while leaving every other discarded parameter synthetic in both suites. Scope of the change (verified by a full dual-suite `--learn` with database-consistency checks, all 3333 tests passing): * test-kotlin1 library-tests/underscore-parameters: `p0` -> `_` (now identical to test-kotlin2). * test-kotlin2: byte-for-byte unchanged. * No other expected file changes (lambda / function-type discard parameters remain `pN` in both suites). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt | 3 ++- .../library-tests/underscore-parameters/test.expected | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 14017a8b6c8..708600f6b22 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -1365,7 +1365,8 @@ open class KotlinFileExtractor( extractTypeAccessRecursive(substitutedType, location, id, -1) } val syntheticParameterNames = - vp.origin == IrDeclarationOrigin.UNDERSCORE_PARAMETER || + (vp.origin == IrDeclarationOrigin.UNDERSCORE_PARAMETER && + vp.name.asString() != "_") || ((vp.parent as? IrFunction)?.let { hasSynthesizedParameterNames(it) } ?: true) val javaParameter = when (val callable = (vp.parent as? IrFunction)?.let { getJavaCallable(it) }) { diff --git a/java/ql/test-kotlin1/library-tests/underscore-parameters/test.expected b/java/ql/test-kotlin1/library-tests/underscore-parameters/test.expected index ba0fd4346e4..7f53cabf845 100644 --- a/java/ql/test-kotlin1/library-tests/underscore-parameters/test.expected +++ b/java/ql/test-kotlin1/library-tests/underscore-parameters/test.expected @@ -1 +1 @@ -| test.kt:5:9:5:9 | p0 | p0 | +| test.kt:5:9:5:9 | _ | _ |