Skip to content

fix: reject duplicate function parameters with correct error in all contexts#1011

Open
He-Pin wants to merge 1 commit into
databricks:masterfrom
He-Pin:fix-reject-duplicate-params
Open

fix: reject duplicate function parameters with correct error in all contexts#1011
He-Pin wants to merge 1 commit into
databricks:masterfrom
He-Pin:fix-reject-duplicate-params

Conversation

@He-Pin

@He-Pin He-Pin commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Motivation

go-jsonnet issue #873 reports that (function(x, x, x) x)(null, 3, 2)
silently returns 2 instead of rejecting duplicate parameter names.
sjsonnet already rejected duplicates in function expressions, but the
error message was misleading in local bindings and object methods
(e.g. "Expected ")"" or "Expected ":"").

Modification

The params parser correctly detects duplicates via flatMapX +
Fail. However, in bind (local f(x,x)=...) and field
({f(x,x):...}), the optional group .? around params swallowed
the "no duplicate parameter" error and backtracked, producing
misleading errors.

Two changes fix this:

  1. In field(): added ~/ (cut) after "(" to commit to the params
    path once "(" is matched: "(" ~/ params(...) ~ ")".
  2. In params(): set ctx.cut = true programmatically when a
    duplicate is detected, preventing outer .? operators from
    swallowing the error. Also captures Pos for each parameter to
    position the error at the duplicate parameter name (not at the
    closing paren).

Result

All duplicate parameter contexts now produce the correct error
"Expected no duplicate parameter: x" with accurate position info:

  • (function(x, x, x) x) -> ParseError (already worked)
  • local f(x, x) = x -> ParseError (was "Expected )")
  • { f(x, x): x } -> ParseError (was "Expected :")
  • { local f(x, x) = x } -> ParseError (was "Expected )")
  • Nested bindings also fixed as a bonus.

Tests pass on Scala 3.3.7, 2.13.18, 2.12.21.

References

@He-Pin He-Pin force-pushed the fix-reject-duplicate-params branch from 32e3062 to 83d39d9 Compare June 20, 2026 11:15
@He-Pin He-Pin marked this pull request as draft June 20, 2026 11:18
@He-Pin He-Pin force-pushed the fix-reject-duplicate-params branch from 83d39d9 to b7288e6 Compare June 20, 2026 11:29
…ontexts

Motivation:
go-jsonnet issue databricks#873 reports that (function(x, x, x) x)(null, 3, 2)
silently returns 2 instead of rejecting duplicate parameter names.
sjsonnet already rejected duplicates in function expressions, but the
error message was misleading in local bindings and object methods.

Modification:
The params parser correctly detects duplicates via flatMapX + Fail.
However, in bind (local f(x,x)=...) and field ({f(x,x):...}), the
optional group .? around params swallowed the "no duplicate parameter"
error and backtracked, producing misleading errors like "Expected )".

Replaced .? with ./ (committed-or): "(" ~/ params ~ ")" ./ | Pass(null).
The cut ~/ after "(" commits to the params path, and ./ prevents the |
alternative from trying the fallback when the committed path fails.

Result:
All duplicate parameter contexts now produce the correct error:
"Expected no duplicate parameter: x" with accurate position info.
- (function(x, x, x) x) -> ParseError (already worked)
- local f(x, x) = x     -> ParseError (was "Expected )")
- { f(x, x): x }        -> ParseError (was "Expected :")
- { local f(x, x) = x } -> ParseError (was "Expected )")

Tests pass on Scala 3.3.7, 2.13.18, 2.12.21.

References:
- google/go-jsonnet#873
@He-Pin He-Pin force-pushed the fix-reject-duplicate-params branch from b7288e6 to c7b60b3 Compare June 20, 2026 11:43
@He-Pin He-Pin marked this pull request as ready for review June 20, 2026 11:47
@He-Pin He-Pin closed this Jun 20, 2026
@He-Pin He-Pin reopened this Jun 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant