microsoft / microsoft/regorus

bug: RVM compiler misclassifies bracket-syntax default rules (config["key"]) as PartialObject

Open
#662 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Rust
Stars
346
Forks
75
Avg merge
1d 3h
Merged PRs (30d)
15

Description

Summary

Rules using bracket-syntax with defaults (e.g., default config["timeout"] := 30) are misclassified by the RVM compiler as PartialObject instead of Complete. This causes incorrect evaluation when querying the specific rule path.

Reproduction
package test

default config["timeout"] := 30

config["timeout"] := 60 if {
  false
}
Expected
Query Expected Result
data.test.config.timeout 30
data.test.config {"timeout": 30}
data.test {"config": {"timeout": 30}}
Actual
Query Interpreter RVM
data.test.config.timeout {} (wrong) {} (wrong)
data.test.config {"timeout": 30} N/A (package query)
data.test {"config": {"timeout": 30}} N/A (package query)

Both the interpreter and RVM return incorrect results for the specific rule query data.test.config.timeout. Only the interpreter's package-level evaluation produces the correct result.

Root Cause

In compute_rule_type() (src/languages/rego/compiler/rules.rs), the rule type classification matches RefBrack with assignment as PartialObject:

RuleHead::Compr { refr, assign, .. } => match refr.as_ref() {
    crate::ast::Expr::RefBrack { .. } if assign.is_some() => {
        RuleType::PartialObject  // ← incorrect for literal keys
    }
    crate::ast::Expr::RefBrack { .. } => RuleType::PartialSet,
    _ => RuleType::Complete,
},

The pattern config["timeout"] := 30 is parsed as RefBrack { index: Expr::String("timeout"), .. } with an assignment. The current code treats all RefBrack + assignment as PartialObject, but only variable keys produce partial objects. A string literal key is semantically equivalent to config.timeout — a complete rule assigned to a specific object key.

The distinction:

  • config[key] := value where key is Expr::VarPartialObject (dynamic key, generates entries for multiple keys)
  • config["timeout"] := value where "timeout" is Expr::StringComplete (static key, equivalent to dot access)
Proposed Fix

In compute_rule_type(), inspect the RefBrack.index expression to distinguish literal keys from variable keys:

RuleHead::Compr { refr, assign, .. } => match refr.as_ref() {
    crate::ast::Expr::RefBrack { index, .. } if assign.is_some() => {
        match index.as_ref() {
            // Literal key like config["timeout"] — treated as complete rule
            crate::ast::Expr::String { .. }
            | crate::ast::Expr::RawString { .. }
            | crate::ast::Expr::Number { .. } => RuleType::Complete,
            // Variable key like config[key] — partial object
            _ => RuleType::PartialObject,
        }
    }
    crate::ast::Expr::RefBrack { .. } => RuleType::PartialSet,
    _ => RuleType::Complete,
},

This same fix should also be verified in the interpreter's eval_rule_in_path code path, which currently also returns {} for the specific query.

The skipped test case default_rule_with_object_key in tests/rvm/rego/cases/default_rules.yaml validates this scenario and should be unskipped after the fix.

Impact

Low — this pattern is uncommon in practice.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/languages/rego/compiler/rules.rs at compute_rule_type(), then inspect the interpreter's eval_rule_in_path path. Run the skipped default_rule_with_object_key case in tests/rvm/rego/cases/default_rules.yaml; done means the test is enabled and bracket-syntax defaults return the expected specific rule value in both execution paths.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.