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:
@ -307,6 +307,7 @@ impl ExecutorContext {
|
|||||||
// During the evaluation of the variable's RHS, set context that this is all happening inside a variable
|
// 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.
|
// declaration, for the given name. This helps improve user-facing error messages.
|
||||||
let lhs = variable_declaration.inner.name().to_owned();
|
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);
|
exec_state.mod_local.being_declared = Some(lhs);
|
||||||
let rhs_result = self
|
let rhs_result = self
|
||||||
.execute_expr(
|
.execute_expr(
|
||||||
@ -318,7 +319,7 @@ impl ExecutorContext {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
// Declaration over, so unset this context.
|
// 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?;
|
let rhs = rhs_result?;
|
||||||
|
|
||||||
exec_state
|
exec_state
|
||||||
@ -836,6 +837,17 @@ impl Node<Name> {
|
|||||||
&self,
|
&self,
|
||||||
exec_state: &'a mut ExecState,
|
exec_state: &'a mut ExecState,
|
||||||
ctx: &ExecutorContext,
|
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> {
|
) -> Result<&'a KclValue, KclError> {
|
||||||
if self.abs_path {
|
if self.abs_path {
|
||||||
return Err(KclError::new_semantic(KclErrorDetails::new(
|
return Err(KclError::new_semantic(KclErrorDetails::new(
|
||||||
|
@ -3525,3 +3525,24 @@ mod ascription_unknown_type {
|
|||||||
super::execute(TEST_NAME, true).await
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Artifact commands var_ref_in_own_def_decl.kcl
|
||||||
|
---
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "edge_lines_visible",
|
||||||
|
"hidden": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "object_visible",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"hidden": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cmdId": "[uuid]",
|
||||||
|
"range": [],
|
||||||
|
"command": {
|
||||||
|
"type": "object_visible",
|
||||||
|
"object_id": "[uuid]",
|
||||||
|
"hidden": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Artifact graph flowchart var_ref_in_own_def_decl.kcl
|
||||||
|
extension: md
|
||||||
|
snapshot_kind: binary
|
||||||
|
---
|
@ -0,0 +1,3 @@
|
|||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
```
|
189
rust/kcl-lib/tests/var_ref_in_own_def_decl/ast.snap
Normal file
189
rust/kcl-lib/tests/var_ref_in_own_def_decl/ast.snap
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of parsing var_ref_in_own_def_decl.kcl
|
||||||
|
---
|
||||||
|
{
|
||||||
|
"Ok": {
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"declaration": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"id": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "declare",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"body": {
|
||||||
|
"body": [
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"declaration": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"id": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "x",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"raw": "0",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Literal",
|
||||||
|
"type": "Literal",
|
||||||
|
"value": {
|
||||||
|
"value": 0.0,
|
||||||
|
"suffix": "None"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "VariableDeclarator"
|
||||||
|
},
|
||||||
|
"end": 0,
|
||||||
|
"kind": "const",
|
||||||
|
"start": 0,
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"type": "VariableDeclaration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"argument": {
|
||||||
|
"abs_path": false,
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "x",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"path": [],
|
||||||
|
"start": 0,
|
||||||
|
"type": "Name",
|
||||||
|
"type": "Name"
|
||||||
|
},
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"start": 0,
|
||||||
|
"type": "ReturnStatement",
|
||||||
|
"type": "ReturnStatement"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"start": 0
|
||||||
|
},
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"params": [],
|
||||||
|
"start": 0,
|
||||||
|
"type": "FunctionExpression",
|
||||||
|
"type": "FunctionExpression"
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "VariableDeclarator"
|
||||||
|
},
|
||||||
|
"end": 0,
|
||||||
|
"kind": "fn",
|
||||||
|
"start": 0,
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"type": "VariableDeclaration"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"declaration": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"id": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "x",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"init": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"left": {
|
||||||
|
"abs_path": false,
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "x",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"path": [],
|
||||||
|
"start": 0,
|
||||||
|
"type": "Name",
|
||||||
|
"type": "Name"
|
||||||
|
},
|
||||||
|
"operator": "+",
|
||||||
|
"right": {
|
||||||
|
"callee": {
|
||||||
|
"abs_path": false,
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": {
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"name": "declare",
|
||||||
|
"start": 0,
|
||||||
|
"type": "Identifier"
|
||||||
|
},
|
||||||
|
"path": [],
|
||||||
|
"start": 0,
|
||||||
|
"type": "Name"
|
||||||
|
},
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"start": 0,
|
||||||
|
"type": "CallExpressionKw",
|
||||||
|
"type": "CallExpressionKw",
|
||||||
|
"unlabeled": null
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "BinaryExpression",
|
||||||
|
"type": "BinaryExpression"
|
||||||
|
},
|
||||||
|
"start": 0,
|
||||||
|
"type": "VariableDeclarator"
|
||||||
|
},
|
||||||
|
"end": 0,
|
||||||
|
"kind": "const",
|
||||||
|
"start": 0,
|
||||||
|
"type": "VariableDeclaration",
|
||||||
|
"type": "VariableDeclaration"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"nonCodeMeta": {
|
||||||
|
"nonCodeNodes": {
|
||||||
|
"0": [
|
||||||
|
{
|
||||||
|
"commentStart": 0,
|
||||||
|
"end": 0,
|
||||||
|
"start": 0,
|
||||||
|
"type": "NonCodeNode",
|
||||||
|
"value": {
|
||||||
|
"type": "newLine"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"startNodes": []
|
||||||
|
},
|
||||||
|
"start": 0
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Error from executing var_ref_in_own_def_decl.kcl
|
||||||
|
---
|
||||||
|
KCL UndefinedValue error
|
||||||
|
|
||||||
|
× undefined value: You can't use `x` because you're currently trying to
|
||||||
|
│ define it. Use a different variable here instead.
|
||||||
|
╭─[6:5]
|
||||||
|
5 │
|
||||||
|
6 │ x = x + declare()
|
||||||
|
· ┬
|
||||||
|
· ╰── tests/var_ref_in_own_def_decl/input.kcl
|
||||||
|
╰────
|
6
rust/kcl-lib/tests/var_ref_in_own_def_decl/input.kcl
Normal file
6
rust/kcl-lib/tests/var_ref_in_own_def_decl/input.kcl
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
fn declare() {
|
||||||
|
x = 0
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
x = x + declare()
|
5
rust/kcl-lib/tests/var_ref_in_own_def_decl/ops.snap
Normal file
5
rust/kcl-lib/tests/var_ref_in_own_def_decl/ops.snap
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Operations executed var_ref_in_own_def_decl.kcl
|
||||||
|
---
|
||||||
|
[]
|
10
rust/kcl-lib/tests/var_ref_in_own_def_decl/unparsed.snap
Normal file
10
rust/kcl-lib/tests/var_ref_in_own_def_decl/unparsed.snap
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
source: kcl-lib/src/simulation_tests.rs
|
||||||
|
description: Result of unparsing var_ref_in_own_def_decl.kcl
|
||||||
|
---
|
||||||
|
fn declare() {
|
||||||
|
x = 0
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
x = x + declare()
|
Reference in New Issue
Block a user