summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMalo <57839069+MDLC01@users.noreply.github.com>2024-06-16 11:35:18 +0200
committerGitHub <noreply@github.com>2024-06-16 09:35:18 +0000
commit34550220aee087271769fb9e5d94d1faebe243c1 (patch)
treeec2b737f906d8d1e1429471bfadf54fb18fc02bf
parentf25308d1ebd6554d35d512584ca4c3034f230240 (diff)
Add hints to array destructuring error messages (#4400)
-rw-r--r--crates/typst/src/eval/binding.rs27
-rw-r--r--tests/suite/scripting/destructuring.typ13
2 files changed, 37 insertions, 3 deletions
diff --git a/crates/typst/src/eval/binding.rs b/crates/typst/src/eval/binding.rs
index 8a2d91ee..4201faed 100644
--- a/crates/typst/src/eval/binding.rs
+++ b/crates/typst/src/eval/binding.rs
@@ -96,7 +96,10 @@ where
match p {
ast::DestructuringItem::Pattern(pattern) => {
let Ok(v) = value.at(i as i64, None) else {
- bail!(pattern.span(), "not enough elements to destructure");
+ bail!(
+ pattern.span(), "not enough elements to destructure";
+ hint: "the provided array has a length of {len}",
+ );
};
destructure_impl(vm, pattern, v, f)?;
i += 1;
@@ -105,7 +108,10 @@ where
let sink_size = (1 + len).checked_sub(destruct.items().count());
let sink = sink_size.and_then(|s| value.as_slice().get(i..i + s));
let (Some(sink_size), Some(sink)) = (sink_size, sink) else {
- bail!(spread.span(), "not enough elements to destructure");
+ bail!(
+ spread.span(), "not enough elements to destructure";
+ hint: "the provided array has a length of {len}",
+ );
};
if let Some(expr) = spread.sink_expr() {
f(vm, expr, Value::Array(sink.into()))?;
@@ -119,7 +125,22 @@ where
}
if i < len {
- bail!(destruct.span(), "too many elements to destructure");
+ if i == 0 {
+ bail!(
+ destruct.span(), "too many elements to destructure";
+ hint: "the provided array has a length of {len}, but the pattern expects an empty array",
+ )
+ } else if i == 1 {
+ bail!(
+ destruct.span(), "too many elements to destructure";
+ hint: "the provided array has a length of {len}, but the pattern expects a single element",
+ );
+ } else {
+ bail!(
+ destruct.span(), "too many elements to destructure";
+ hint: "the provided array has a length of {len}, but the pattern expects {i} elements",
+ );
+ }
}
Ok(())
diff --git a/tests/suite/scripting/destructuring.typ b/tests/suite/scripting/destructuring.typ
index 0a3c1c54..9d28c195 100644
--- a/tests/suite/scripting/destructuring.typ
+++ b/tests/suite/scripting/destructuring.typ
@@ -119,12 +119,22 @@
// Error: 7-14 expected pattern, found function call
#let (a.at(0),) = (1,)
+--- destructuring-let-empty-array ---
+#let () = ()
+
+--- destructuring-let-empty-array-too-many-elements ---
+// Error: 6-8 too many elements to destructure
+// Hint: 6-8 the provided array has a length of 2, but the pattern expects an empty array
+#let () = (1, 2)
+
--- destructuring-let-array-too-few-elements ---
// Error: 13-14 not enough elements to destructure
+// Hint: 13-14 the provided array has a length of 2
#let (a, b, c) = (1, 2)
--- destructuring-let-array-too-few-elements-with-sink ---
// Error: 7-10 not enough elements to destructure
+// Hint: 7-10 the provided array has a length of 2
#let (..a, b, c, d) = (1, 2)
--- destructuring-let-array-bool-invalid ---
@@ -183,6 +193,7 @@
--- destructuring-let-array-trailing-placeholders ---
// Trailing placeholders.
// Error: 10-11 not enough elements to destructure
+// Hint: 10-11 the provided array has a length of 1
#let (a, _, _, _, _) = (1,)
#test(a, 1)
@@ -350,8 +361,10 @@
--- issue-3275-destructuring-loop-over-2d-array-1 ---
// Error: 10-11 not enough elements to destructure
+// Hint: 10-11 the provided array has a length of 1
#for (x, y) in ((1,), (2,)) {}
--- issue-3275-destructuring-loop-over-2d-array-2 ---
// Error: 6-12 too many elements to destructure
+// Hint: 6-12 the provided array has a length of 3, but the pattern expects 2 elements
#for (x, y) in ((1,2,3), (4,5,6)) {}