feat: Reject with keyword usage

RVM does not plan to support the `with` keyword which is mainly used
for testing.

- introduce CompilerError::WithKeywordUnsupported and fail query compilation
  when any literal carries with_mods
- skip OPA test cases that hit the error

The "withkeyword" folder is retained in the TODO list to indicate its
lack of support.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
This commit is contained in:
Anand Krishnamoorthi
2025-12-03 15:22:12 -06:00
parent a514e8da83
commit d0fa639bb8
4 changed files with 24 additions and 3 deletions

View File

@@ -15,6 +15,9 @@ pub enum CompilerError {
#[error("Unknown builtin function: {name}")] #[error("Unknown builtin function: {name}")]
UnknownBuiltinFunction { name: String }, UnknownBuiltinFunction { name: String },
#[error("the `with` keyword is not supported by the compiler yet")]
WithKeywordUnsupported,
#[error("internal: missing context for yield")] #[error("internal: missing context for yield")]
MissingYieldContext, MissingYieldContext,

View File

@@ -10,7 +10,7 @@ mod queries;
mod references; mod references;
mod rules; mod rules;
pub use error::{CompilerError, Result}; pub use error::{CompilerError, Result, SpannedCompilerError};
use crate::ast::ExprRef; use crate::ast::ExprRef;
use crate::lexer::Span; use crate::lexer::Span;

View File

@@ -38,6 +38,9 @@ impl<'a> Compiler<'a> {
stmts: &[&LiteralStmt], stmts: &[&LiteralStmt],
) -> Result<()> { ) -> Result<()> {
for (idx, stmt) in stmts.iter().enumerate() { for (idx, stmt) in stmts.iter().enumerate() {
if !stmt.with_mods.is_empty() {
return Err(CompilerError::WithKeywordUnsupported.at(&stmt.span));
}
let loop_exprs = self.get_statement_loops(stmt)?; let loop_exprs = self.get_statement_loops(stmt)?;
if !loop_exprs.is_empty() { if !loop_exprs.is_empty() {

View File

@@ -32,10 +32,9 @@ const OPA_TODO_FOLDERS: &[&str] = &[
"partialobjectdoc", "partialobjectdoc",
"planner-ir", "planner-ir",
"refheads", "refheads",
"sets",
"type",
"virtualdocs", "virtualdocs",
"walkbuiltin", "walkbuiltin",
// RVM Compiler does not support 'with' keyword yet.
"withkeyword", "withkeyword",
]; ];
@@ -267,6 +266,14 @@ fn is_not_valid_rule_path_error(err: &anyhow::Error) -> bool {
.any(|cause| cause.to_string().contains("not a valid rule path")) .any(|cause| cause.to_string().contains("not a valid rule path"))
} }
fn is_with_keyword_unsupported_error(err: &anyhow::Error) -> bool {
err.chain().any(|cause| {
cause
.to_string()
.contains("`with` keyword is not supported")
})
}
fn maybe_verify_rvm_case(case: &TestCase, is_rego_v0_test: bool, actual: &Value) -> Result<()> { fn maybe_verify_rvm_case(case: &TestCase, is_rego_v0_test: bool, actual: &Value) -> Result<()> {
if case.note == "defaultkeyword/function with var arg, ref head query" { if case.note == "defaultkeyword/function with var arg, ref head query" {
println!( println!(
@@ -292,6 +299,14 @@ fn maybe_verify_rvm_case(case: &TestCase, is_rego_v0_test: bool, actual: &Value)
return Ok(()); return Ok(());
} }
if is_with_keyword_unsupported_error(&err) {
println!(
" skipping RVM check for '{}' (with keyword unsupported)",
case.note
);
return Ok(());
}
return Err(err); return Err(err);
} }
}; };