KCL: Improve error messages for var referenced in own definition (#7374)

Jon pointed out that my new error message wasn't showing up in some
cases, and it should store/restore the previous var being defined.
This commit is contained in:
Adam Chalmers
2025-06-04 23:48:15 -05:00
committed by GitHub
parent 33d5a9cdc1
commit 9136fb0d1b
10 changed files with 299 additions and 1 deletions

View File

@ -307,6 +307,7 @@ impl ExecutorContext {
// During the evaluation of the variable's RHS, set context that this is all happening inside a variable
// declaration, for the given name. This helps improve user-facing error messages.
let lhs = variable_declaration.inner.name().to_owned();
let prev_being_declared = exec_state.mod_local.being_declared.clone();
exec_state.mod_local.being_declared = Some(lhs);
let rhs_result = self
.execute_expr(
@ -318,7 +319,7 @@ impl ExecutorContext {
)
.await;
// Declaration over, so unset this context.
exec_state.mod_local.being_declared = None;
exec_state.mod_local.being_declared = prev_being_declared;
let rhs = rhs_result?;
exec_state
@ -836,6 +837,17 @@ impl Node<Name> {
&self,
exec_state: &'a mut ExecState,
ctx: &ExecutorContext,
) -> Result<&'a KclValue, KclError> {
let being_declared = exec_state.mod_local.being_declared.clone();
self.get_result_inner(exec_state, ctx)
.await
.map_err(|e| var_in_own_ref_err(e, &being_declared))
}
async fn get_result_inner<'a>(
&self,
exec_state: &'a mut ExecState,
ctx: &ExecutorContext,
) -> Result<&'a KclValue, KclError> {
if self.abs_path {
return Err(KclError::new_semantic(KclErrorDetails::new(

View File

@ -3525,3 +3525,24 @@ mod ascription_unknown_type {
super::execute(TEST_NAME, true).await
}
}
mod var_ref_in_own_def_decl {
const TEST_NAME: &str = "var_ref_in_own_def_decl";
/// Test parsing KCL.
#[test]
fn parse() {
super::parse(TEST_NAME)
}
/// Test that parsing and unparsing KCL produces the original KCL input.
#[tokio::test(flavor = "multi_thread")]
async fn unparse() {
super::unparse(TEST_NAME).await
}
/// Test that KCL is executed correctly.
#[tokio::test(flavor = "multi_thread")]
async fn kcl_test_execute() {
super::execute(TEST_NAME, true).await
}
}