Skip to content

Commit 7ca05a8

Browse files
authored
Add argument variant of KCL error (#7801)
* Add argument variant of KCL error * Change function call and return errors to use different error types * Update sim test output
1 parent 4fa72b8 commit 7ca05a8

File tree

9 files changed

+79
-37
lines changed

9 files changed

+79
-37
lines changed

rust/kcl-lib/src/errors.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ pub enum KclError {
100100
Semantic { details: KclErrorDetails },
101101
#[error("import cycle: {details:?}")]
102102
ImportCycle { details: KclErrorDetails },
103+
#[error("argument: {details:?}")]
104+
Argument { details: KclErrorDetails },
103105
#[error("type: {details:?}")]
104106
Type { details: KclErrorDetails },
105107
#[error("i/o: {details:?}")]
@@ -312,6 +314,7 @@ impl miette::Diagnostic for ReportWithOutputs {
312314
KclError::Syntax { .. } => "Syntax",
313315
KclError::Semantic { .. } => "Semantic",
314316
KclError::ImportCycle { .. } => "ImportCycle",
317+
KclError::Argument { .. } => "Argument",
315318
KclError::Type { .. } => "Type",
316319
KclError::Io { .. } => "I/O",
317320
KclError::Unexpected { .. } => "Unexpected",
@@ -362,6 +365,7 @@ impl miette::Diagnostic for Report {
362365
KclError::Syntax { .. } => "Syntax",
363366
KclError::Semantic { .. } => "Semantic",
364367
KclError::ImportCycle { .. } => "ImportCycle",
368+
KclError::Argument { .. } => "Argument",
365369
KclError::Type { .. } => "Type",
366370
KclError::Io { .. } => "I/O",
367371
KclError::Unexpected { .. } => "Unexpected",
@@ -439,6 +443,10 @@ impl KclError {
439443
KclError::ImportCycle { details }
440444
}
441445

446+
pub fn new_argument(details: KclErrorDetails) -> KclError {
447+
KclError::Argument { details }
448+
}
449+
442450
pub fn new_semantic(details: KclErrorDetails) -> KclError {
443451
KclError::Semantic { details }
444452
}
@@ -482,6 +490,7 @@ impl KclError {
482490
KclError::Syntax { .. } => "syntax",
483491
KclError::Semantic { .. } => "semantic",
484492
KclError::ImportCycle { .. } => "import cycle",
493+
KclError::Argument { .. } => "argument",
485494
KclError::Type { .. } => "type",
486495
KclError::Io { .. } => "i/o",
487496
KclError::Unexpected { .. } => "unexpected",
@@ -499,6 +508,7 @@ impl KclError {
499508
KclError::Syntax { details: e } => e.source_ranges.clone(),
500509
KclError::Semantic { details: e } => e.source_ranges.clone(),
501510
KclError::ImportCycle { details: e } => e.source_ranges.clone(),
511+
KclError::Argument { details: e } => e.source_ranges.clone(),
502512
KclError::Type { details: e } => e.source_ranges.clone(),
503513
KclError::Io { details: e } => e.source_ranges.clone(),
504514
KclError::Unexpected { details: e } => e.source_ranges.clone(),
@@ -517,6 +527,7 @@ impl KclError {
517527
KclError::Syntax { details: e } => &e.message,
518528
KclError::Semantic { details: e } => &e.message,
519529
KclError::ImportCycle { details: e } => &e.message,
530+
KclError::Argument { details: e } => &e.message,
520531
KclError::Type { details: e } => &e.message,
521532
KclError::Io { details: e } => &e.message,
522533
KclError::Unexpected { details: e } => &e.message,
@@ -534,6 +545,7 @@ impl KclError {
534545
| KclError::Syntax { details: e }
535546
| KclError::Semantic { details: e }
536547
| KclError::ImportCycle { details: e }
548+
| KclError::Argument { details: e }
537549
| KclError::Type { details: e }
538550
| KclError::Io { details: e }
539551
| KclError::Unexpected { details: e }
@@ -552,6 +564,7 @@ impl KclError {
552564
| KclError::Syntax { details: e }
553565
| KclError::Semantic { details: e }
554566
| KclError::ImportCycle { details: e }
567+
| KclError::Argument { details: e }
555568
| KclError::Type { details: e }
556569
| KclError::Io { details: e }
557570
| KclError::Unexpected { details: e }
@@ -581,6 +594,7 @@ impl KclError {
581594
| KclError::Syntax { details: e }
582595
| KclError::Semantic { details: e }
583596
| KclError::ImportCycle { details: e }
597+
| KclError::Argument { details: e }
584598
| KclError::Type { details: e }
585599
| KclError::Io { details: e }
586600
| KclError::Unexpected { details: e }

rust/kcl-lib/src/execution/fn_call.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ fn type_check_params_kw(
612612
// TODO if we have access to the AST for the argument we could choose which example to suggest.
613613
message = format!("{message}\n\nYou may need to add information about the type of the argument, for example:\n using a numeric suffix: `42{ty}`\n or using type ascription: `foo(): number({ty})`");
614614
}
615-
KclError::new_semantic(KclErrorDetails::new(
615+
KclError::new_argument(KclErrorDetails::new(
616616
message,
617617
vec![arg.source_range],
618618
))
@@ -664,15 +664,15 @@ fn type_check_params_kw(
664664
let first = errors.next().unwrap();
665665
errors.for_each(|e| exec_state.err(e));
666666

667-
return Err(KclError::new_semantic(first.into()));
667+
return Err(KclError::new_argument(first.into()));
668668
}
669669

670670
if let Some(arg) = &mut args.unlabeled {
671671
if let Some((_, Some(ty))) = &fn_def.input_arg {
672672
let rty = RuntimeType::from_parsed(ty.clone(), exec_state, arg.1.source_range)
673673
.map_err(|e| KclError::new_semantic(e.into()))?;
674674
arg.1.value = arg.1.value.coerce(&rty, true, exec_state).map_err(|_| {
675-
KclError::new_semantic(KclErrorDetails::new(
675+
KclError::new_argument(KclErrorDetails::new(
676676
format!(
677677
"The input argument of {} requires {}",
678678
fn_name
@@ -728,7 +728,7 @@ fn assign_args_to_params_kw(
728728
.add(name.clone(), value, default_val.source_range())?;
729729
}
730730
None => {
731-
return Err(KclError::new_semantic(KclErrorDetails::new(
731+
return Err(KclError::new_argument(KclErrorDetails::new(
732732
format!("This function requires a parameter {name}, but you haven't passed it one."),
733733
source_ranges,
734734
)));
@@ -742,14 +742,14 @@ fn assign_args_to_params_kw(
742742

743743
let Some(unlabeled) = unlabelled else {
744744
return Err(if args.kw_args.labeled.contains_key(param_name) {
745-
KclError::new_semantic(KclErrorDetails::new(
745+
KclError::new_argument(KclErrorDetails::new(
746746
format!(
747747
"The function does declare a parameter named '{param_name}', but this parameter doesn't use a label. Try removing the `{param_name}:`"
748748
),
749749
source_ranges,
750750
))
751751
} else {
752-
KclError::new_semantic(KclErrorDetails::new(
752+
KclError::new_argument(KclErrorDetails::new(
753753
"This function expects an unlabeled first parameter, but you haven't passed it one.".to_owned(),
754754
source_ranges,
755755
))
@@ -775,7 +775,7 @@ fn coerce_result_type(
775775
let ty = RuntimeType::from_parsed(ret_ty.inner.clone(), exec_state, ret_ty.as_source_range())
776776
.map_err(|e| KclError::new_semantic(e.into()))?;
777777
let val = val.coerce(&ty, true, exec_state).map_err(|_| {
778-
KclError::new_semantic(KclErrorDetails::new(
778+
KclError::new_type(KclErrorDetails::new(
779779
format!(
780780
"This function requires its result to be {}",
781781
type_err_str(ret_ty, &val, &(&val).into(), exec_state)
@@ -858,7 +858,7 @@ mod test {
858858
"all params required, none given, should error",
859859
vec![req_param("x")],
860860
vec![],
861-
Err(KclError::new_semantic(KclErrorDetails::new(
861+
Err(KclError::new_argument(KclErrorDetails::new(
862862
"This function requires a parameter x, but you haven't passed it one.".to_owned(),
863863
vec![SourceRange::default()],
864864
))),
@@ -873,7 +873,7 @@ mod test {
873873
"mixed params, too few given",
874874
vec![req_param("x"), opt_param("y")],
875875
vec![],
876-
Err(KclError::new_semantic(KclErrorDetails::new(
876+
Err(KclError::new_argument(KclErrorDetails::new(
877877
"This function requires a parameter x, but you haven't passed it one.".to_owned(),
878878
vec![SourceRange::default()],
879879
))),

rust/kcl-lib/tests/argument_error/execution_error.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
source: kcl-lib/src/simulation_tests.rs
33
description: Error from executing argument_error.kcl
44
---
5-
KCL Semantic error
5+
KCL Argument error
66

7-
× semantic: f requires a value with type `fn(any): any`, but found an array
7+
× argument: f requires a value with type `fn(any): any`, but found an array
88
of `number`, `number` (with type `[any; 2]`).
99
╭─[5:1]
1010
4
@@ -13,9 +13,9 @@ KCL Semantic error
1313
· │ ╰── tests/argument_error/input.kcl
1414
· ╰── tests/argument_error/input.kcl
1515
╰────
16-
╰─▶ KCL Semantic error
16+
╰─▶ KCL Argument error
1717

18-
× semantic: f requires a value with type `fn(any): any`, but found an
18+
× argument: f requires a value with type `fn(any): any`, but found an
1919
array of `number`, `number` (with type `[any; 2]`).
2020
╭─[5:12]
2121
4

rust/kcl-lib/tests/array_elem_pop_empty_fail/execution_error.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
source: kcl-lib/src/simulation_tests.rs
33
description: Error from executing array_elem_pop_empty_fail.kcl
44
---
5-
KCL Semantic error
5+
KCL Argument error
66

7-
× semantic: The input argument of `pop` requires one or more values (`[any;
7+
× argument: The input argument of `pop` requires one or more values (`[any;
88
│ 1+]`), but found an empty array (with type `[any; 0]`).
99
╭─[2:8]
1010
1arr = []
@@ -13,9 +13,9 @@ KCL Semantic error
1313
· │ ╰── tests/array_elem_pop_empty_fail/input.kcl
1414
· ╰── tests/array_elem_pop_empty_fail/input.kcl
1515
╰────
16-
╰─▶ KCL Semantic error
16+
╰─▶ KCL Argument error
1717

18-
× semantic: The input argument of `pop` requires one or more values
18+
× argument: The input argument of `pop` requires one or more values
1919
│ (`[any; 1+]`), but found an empty array (with type `[any; 0]`).
2020
╭─[2:12]
2121
1arr = []

rust/kcl-lib/tests/error_inside_fn_also_has_source_range_of_call_site_recursive/execution_error.snap

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
source: kcl-lib/src/simulation_tests.rs
33
description: Error from executing error_inside_fn_also_has_source_range_of_call_site_recursive.kcl
44
---
5-
KCL Semantic error
5+
KCL Argument error
66

7-
× semantic: The input argument of `startSketchOn` requires a value with type
7+
× argument: The input argument of `startSketchOn` requires a value with type
88
`Solid` or a value with type `Plane` (`Solid | Plane`), but found a value
99
with type `string`.
1010
╭─[3:9]
@@ -24,9 +24,9 @@ KCL Semantic error
2424
· ───────────┬───────────
2525
· ╰── tests/error_inside_fn_also_has_source_range_of_call_site_recursive/input.kcl
2626
╰────
27-
├─▶ KCL Semantic error
27+
├─▶ KCL Argument error
2828
29-
│ × semantic: The input argument of `startSketchOn` requires a value
29+
│ × argument: The input argument of `startSketchOn` requires a value
3030
│ │ with type `Solid` or a value with type `Plane` (`Solid | Plane`),
3131
│ │ but found a value with type `string`.
3232
│ ╭─[3:23]
@@ -37,9 +37,9 @@ KCL Semantic error
3737
error_inside_fn_also_has_source_range_of_call_site_recursive/input.kcl
3838
4 │ }
3939
│ ╰────
40-
├─▶ KCL Semantic error
40+
├─▶ KCL Argument error
4141
42-
│ × semantic: The input argument of `startSketchOn` requires a value
42+
│ × argument: The input argument of `startSketchOn` requires a value
4343
│ │ with type `Solid` or a value with type `Plane` (`Solid | Plane`),
4444
│ │ but found a value with type `string`.
4545
│ ╭─[3:9]
@@ -50,9 +50,9 @@ KCL Semantic error
5050
error_inside_fn_also_has_source_range_of_call_site_recursive/input.kcl
5151
4 │ }
5252
│ ╰────
53-
╰─▶ KCL Semantic error
53+
╰─▶ KCL Argument error
5454

55-
× semantic: The input argument of `startSketchOn` requires a value
55+
× argument: The input argument of `startSketchOn` requires a value
5656
with type `Solid` or a value with type `Plane` (`Solid | Plane`),
5757
but found a value with type `string`.
5858
╭─[6:5]

rust/kcl-lib/tests/kw_fn_too_few_args/execution_error.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
source: kcl-lib/src/simulation_tests.rs
33
description: Error from executing kw_fn_too_few_args.kcl
44
---
5-
KCL Semantic error
5+
KCL Argument error
66

7-
× semantic: This function requires a parameter y, but you haven't passed it
7+
× argument: This function requires a parameter y, but you haven't passed it
88
│ one.
99
╭─[1:14]
1010
1 │ ╭─▶ fn add(x, y) {
@@ -16,9 +16,9 @@ KCL Semantic error
1616
· ─────┬────
1717
· ╰── tests/kw_fn_too_few_args/input.kcl
1818
╰────
19-
╰─▶ KCL Semantic error
19+
╰─▶ KCL Argument error
2020

21-
× semantic: This function requires a parameter y, but you haven't
21+
× argument: This function requires a parameter y, but you haven't
2222
│ passed it one.
2323
╭─[1:14]
2424
1 │ ╭─▶ fn add(x, y) {

rust/kcl-lib/tests/kw_fn_unlabeled_but_has_label/execution_error.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
source: kcl-lib/src/simulation_tests.rs
33
description: Error from executing kw_fn_unlabeled_but_has_label.kcl
44
---
5-
KCL Semantic error
5+
KCL Argument error
66

7-
× semantic: The function does declare a parameter named 'x', but this
7+
× argument: The function does declare a parameter named 'x', but this
88
│ parameter doesn't use a label. Try removing the `x:`
99
╭─[1:12]
1010
1 │ ╭─▶ fn add(@x) {
@@ -16,9 +16,9 @@ KCL Semantic error
1616
· ─────┬────
1717
· ╰── tests/kw_fn_unlabeled_but_has_label/input.kcl
1818
╰────
19-
╰─▶ KCL Semantic error
19+
╰─▶ KCL Argument error
2020

21-
× semantic: The function does declare a parameter named 'x', but this
21+
× argument: The function does declare a parameter named 'x', but this
2222
parameter doesn't use a label. Try removing the `x:`
2323
╭─[1:12]
2424
1 │ ╭─▶ fn add(@x) {

rust/kcl-lib/tests/panic_repro_cube/execution_error.snap

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
source: kcl-lib/src/simulation_tests.rs
33
description: Error from executing panic_repro_cube.kcl
44
---
5-
KCL Semantic error
5+
KCL Argument error
66

7-
× semantic: The input argument of `getNextAdjacentEdge` requires a value
7+
× argument: The input argument of `getNextAdjacentEdge` requires a value
88
with type `TaggedEdge`, but found a unique ID (uuid) (with type `Edge`).
99
╭─[43:5]
1010
42// these double wrapped functions are the point of this test
@@ -14,9 +14,9 @@ KCL Semantic error
1414
· ╰── tests/panic_repro_cube/input.kcl
1515
44getNextAdjacentEdge(getNextAdjacentEdge(seg02))
1616
╰────
17-
╰─▶ KCL Semantic error
17+
╰─▶ KCL Argument error
1818

19-
× semantic: The input argument of `getNextAdjacentEdge` requires a
19+
× argument: The input argument of `getNextAdjacentEdge` requires a
2020
value with type `TaggedEdge`, but found a unique ID (uuid) (with
2121
type `Edge`).
2222
╭─[43:25]

src/lang/errors.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,34 @@ export class KCLSemanticError extends KCLError {
172172
}
173173
}
174174

175+
export class KCLArgumentError extends KCLError {
176+
constructor(
177+
msg: string,
178+
sourceRange: SourceRange,
179+
kclBacktrace: BacktraceItem[],
180+
nonFatal: CompilationError[],
181+
variables: VariableMap,
182+
operations: Operation[],
183+
artifactGraph: ArtifactGraph,
184+
filenames: { [x: number]: ModulePath | undefined },
185+
defaultPlanes: DefaultPlanes | null
186+
) {
187+
super(
188+
'argument',
189+
msg,
190+
sourceRange,
191+
kclBacktrace,
192+
nonFatal,
193+
variables,
194+
operations,
195+
artifactGraph,
196+
filenames,
197+
defaultPlanes
198+
)
199+
Object.setPrototypeOf(this, KCLArgumentError.prototype)
200+
}
201+
}
202+
175203
export class KCLTypeError extends KCLError {
176204
constructor(
177205
msg: string,

0 commit comments

Comments
 (0)