mirror of
https://github.com/apple/pkl.git
synced 2026-05-25 16:19:20 +02:00
Do not activate power assertions when a single union member containing a type constraint fails (#1462)
Prior to this change, this code would activate powers assertions /
instrumentation permanently:
```pkl
foo: String(contains("a")) | String(contains("b")) = "boo"
```
This is because the `contains("a")` constraint would fail, triggering
power assertions, but the subsequent check of the union's
`contains("b")` branch would succeed.
As observed in #1419, once instrumentation is enabled, all subsequent
evaluation slows significantly.
As with #1419, the fix here is to disable power assertions via
`VmLocalContext` until we know that all union members failed type
checking; then, each member is re-executed with power assertions allowed
to provide the improved user-facing error.
This commit is contained in:
@@ -566,6 +566,69 @@ class EvaluatorTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `constraint failures activate instrumentation`() {
|
||||
val evaluator =
|
||||
with(EvaluatorBuilder.preconfigured()) {
|
||||
powerAssertionsEnabled = true
|
||||
build()
|
||||
}
|
||||
|
||||
val exc =
|
||||
assertThrows<PklException> {
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
foo: String(chars.first == "a") = "boo"
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
assertThat((evaluator as EvaluatorImpl).isInstrumentationEverUsed()).isTrue
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `union single-member constraint failures do not activate instrumentation`() {
|
||||
val evaluator =
|
||||
with(EvaluatorBuilder.preconfigured()) {
|
||||
powerAssertionsEnabled = true
|
||||
build()
|
||||
}
|
||||
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
foo: String(startsWith("a")) | String(startsWith("b")) | String(startsWith("c")) = "cool"
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
|
||||
assertThat((evaluator as EvaluatorImpl).isInstrumentationEverUsed()).isFalse
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `type test failures do not activate instrumentation`() {
|
||||
val evaluator =
|
||||
with(EvaluatorBuilder.preconfigured()) {
|
||||
powerAssertionsEnabled = true
|
||||
build()
|
||||
}
|
||||
|
||||
evaluator.evaluate(
|
||||
text(
|
||||
"""
|
||||
foo = "bar" is Int(this > 0)
|
||||
"""
|
||||
.trimIndent()
|
||||
)
|
||||
)
|
||||
|
||||
assertThat((evaluator as EvaluatorImpl).isInstrumentationEverUsed()).isFalse
|
||||
}
|
||||
|
||||
private fun checkModule(module: PModule) {
|
||||
assertThat(module.properties.size).isEqualTo(2)
|
||||
assertThat(module.getProperty("name")).isEqualTo("pigeon")
|
||||
|
||||
Reference in New Issue
Block a user