Skip to content

Fix undefined assignments and comprehension heads in RVM - #883

Open
Mark Birger (kusha) wants to merge 1 commit into
microsoft:mainfrom
kusha:markbirger-microsoft-rvm-undefined-fixes
Open

Mark Birger (kusha) wants to merge 1 commit into
microsoft:mainfrom
kusha:markbirger-microsoft-rvm-undefined-fixes

Conversation

@kusha

Copy link
Copy Markdown
Contributor

Summary

Fix two RVM compiler paths that allow undefined values to survive where Rego requires the current rule-body attempt or comprehension iteration to fail.

  • Emit a GuardMode::NotUndefined check after compiling the RHS of :=, before destructuring. This covers named variables and _.
  • Guard array comprehension values and object comprehension keys and values before yielding.
  • Add four generic regression cases covering both run-to-completion and suspendable execution, with results compared against the interpreter.

For example, with input {}, this rule must be undefined rather than return true:

package repro
import rego.v1

result := true if {
    _ := input.missing
}

Separately, [input.missing | true] must return [], not an array containing internal Undefined. Object comprehension entries with undefined keys or values must likewise be omitted.

The guards check definedness, not truthiness: false, null, zero, empty strings, and empty collections remain valid values. Regression coverage also verifies fallback behavior and that valid comprehension iterations survive alongside missing values.

This is RVM-only. The interpreter, existing set-comprehension runtime filtering, dependencies, and public APIs are unchanged.

Validation

Validated on upstream main at 32689cb71dd53e8943cbc231f1670c76f41b3273 using Rust 1.95.0:

  • The new regression suite fails on the unchanged base.
  • Applying only the assignment guard passes the assignment cases but still fails the direct-comprehension-head case.
  • With both fixes, all four regression cases pass.
  • cargo +1.95.0 test --quiet --test mod undefined_values -- --nocapture
  • cargo +1.95.0 test --quiet --test mod rvm::rego (45 tests)
  • cargo +1.95.0 fmt --all -- --check
  • cargo +1.95.0 xtask ci-debug
  • git diff --check

Separate language-binding smoke tests were not run.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Critical nested-comprehension failures route control to the wrong loop or leave inner contexts active, producing incorrect results in run-to-completion mode and requiring fixes with regressions in both execution modes.

2 open issues
What changed in this PR

This PR updates the Rego-to-RVM compiler to reject undefined assignments and omit undefined comprehension entries, aligning these paths with interpreter behavior while preserving valid false-like values.

Changes:

  • Add definedness guards before assignment destructuring, including wildcard assignments.
  • Guard array comprehension values and object comprehension keys and values before yielding.
  • Add four regression cases covering run-to-completion and suspendable execution, compared against the interpreter.
File Description
tests/​rvm/​rego/​cases/​undefined_values.yaml Adds regression coverage for undefined values, fallback behavior, and valid false-like values.
src/​languages/​rego/​compiler/​queries.rs Adds definedness guards to array and object comprehension heads.
src/​languages/​rego/​compiler/​destructuring.rs Guards assignment right-hand sides before destructuring.

Review effort: Balanced

Comment on lines +46 to +50
self.emit_instruction(
Instruction::Guard {
register: rhs_reg,
mode: GuardMode::NotUndefined,
},
Comment on lines +174 to +178
self.emit_instruction(
Instruction::Guard {
register: value_register,
mode: GuardMode::NotUndefined,
},
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.

2 participants