summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeedehai <18319900+Leedehai@users.noreply.github.com>2023-04-19 07:26:55 -0400
committerGitHub <noreply@github.com>2023-04-19 13:26:55 +0200
commitdc3017955a67e5509f6bc33cb9b4833806da4c22 (patch)
tree364304f23268107cb0443fc0037a86bd4136d9ef
parente4b09d417e9bfc2c0011299272f33c6861e96a6f (diff)
Give more specific error messages (#881)
-rw-r--r--src/eval/args.rs8
-rw-r--r--src/eval/scope.rs10
-rw-r--r--src/syntax/lexer.rs12
-rw-r--r--src/syntax/parser.rs24
-rw-r--r--tests/typ/compiler/array.typ2
-rw-r--r--tests/typ/compiler/block.typ10
-rw-r--r--tests/typ/compiler/call.typ2
-rw-r--r--tests/typ/compiler/closure.typ14
-rw-r--r--tests/typ/compiler/dict.typ4
-rw-r--r--tests/typ/compiler/include.typ2
-rw-r--r--tests/typ/compiler/methods.typ2
-rw-r--r--tests/typ/compiler/ops-invalid.typ8
-rw-r--r--tests/typ/compiler/ops.typ6
-rw-r--r--tests/typ/compiler/recursion.typ2
-rw-r--r--tests/typ/text/escape.typ2
-rw-r--r--tests/typ/text/font.typ2
-rw-r--r--tests/typ/visualize/shape-circle.typ2
-rw-r--r--tests/typ/visualize/shape-square.typ2
18 files changed, 66 insertions, 48 deletions
diff --git a/src/eval/args.rs b/src/eval/args.rs
index aadd7d54..8617bd93 100644
--- a/src/eval/args.rs
+++ b/src/eval/args.rs
@@ -158,7 +158,13 @@ impl Args {
/// argument.
pub fn finish(self) -> SourceResult<()> {
if let Some(arg) = self.items.first() {
- bail!(arg.span, "unexpected argument");
+ bail!(
+ arg.span,
+ match &arg.name {
+ Some(name) => eco_format!("unexpected argument: {}", name),
+ _ => eco_format!("unexpected argument"),
+ }
+ )
}
Ok(())
}
diff --git a/src/eval/scope.rs b/src/eval/scope.rs
index e241cac5..f2207188 100644
--- a/src/eval/scope.rs
+++ b/src/eval/scope.rs
@@ -2,7 +2,7 @@ use std::collections::BTreeMap;
use std::fmt::{self, Debug, Formatter};
use std::hash::Hash;
-use ecow::EcoString;
+use ecow::{eco_format, EcoString};
use super::{Library, Value};
use crate::diag::StrResult;
@@ -42,7 +42,7 @@ impl<'a> Scopes<'a> {
.chain(self.scopes.iter().rev())
.chain(self.base.map(|base| base.global.scope()))
.find_map(|scope| scope.get(var))
- .ok_or("unknown variable")?)
+ .ok_or(eco_format!("unknown variable: {}", var))?)
}
/// Try to access a variable immutably in math.
@@ -51,7 +51,7 @@ impl<'a> Scopes<'a> {
.chain(self.scopes.iter().rev())
.chain(self.base.map(|base| base.math.scope()))
.find_map(|scope| scope.get(var))
- .ok_or("unknown variable")?)
+ .ok_or(eco_format!("unknown variable: {}", var))?)
}
/// Try to access a variable mutably.
@@ -61,8 +61,8 @@ impl<'a> Scopes<'a> {
.find_map(|scope| scope.get_mut(var))
.ok_or_else(|| {
match self.base.and_then(|base| base.global.scope().get(var)) {
- Some(_) => "cannot mutate a constant",
- _ => "unknown variable",
+ Some(_) => eco_format!("cannot mutate a constant: {}", var),
+ _ => eco_format!("unknown variable: {}", var),
}
})?
}
diff --git a/src/syntax/lexer.rs b/src/syntax/lexer.rs
index 7961d4ca..dcd2509a 100644
--- a/src/syntax/lexer.rs
+++ b/src/syntax/lexer.rs
@@ -217,7 +217,7 @@ impl Lexer<'_> {
.and_then(std::char::from_u32)
.is_none()
{
- return self.error("invalid unicode escape sequence");
+ return self.error(eco_format!("invalid unicode codepoint: {}", hex));
}
return SyntaxKind::Escape;
@@ -585,10 +585,10 @@ impl Lexer<'_> {
SyntaxKind::Float
} else {
return self.error(match base {
- 2 => "invalid binary number",
- 8 => "invalid octal number",
- 16 => "invalid hexadecimal number",
- _ => "invalid number",
+ 2 => eco_format!("invalid binary number: 0b{}", number),
+ 8 => eco_format!("invalid octal number: 0o{}", number),
+ 16 => eco_format!("invalid hexadecimal number: 0x{}", number),
+ _ => eco_format!("invalid number: {}", number),
});
};
@@ -600,7 +600,7 @@ impl Lexer<'_> {
suffix,
"pt" | "mm" | "cm" | "in" | "deg" | "rad" | "em" | "fr" | "%"
) {
- return self.error("invalid number suffix");
+ return self.error(eco_format!("invalid number suffix: {}", suffix));
}
SyntaxKind::Numeric
diff --git a/src/syntax/parser.rs b/src/syntax/parser.rs
index e6807404..4bc25a30 100644
--- a/src/syntax/parser.rs
+++ b/src/syntax/parser.rs
@@ -1046,8 +1046,8 @@ fn validate_dict(p: &mut Parser, m: Marker) {
None => first.text().clone(),
};
- if !used.insert(key) {
- first.convert_to_error("duplicate key");
+ if !used.insert(key.clone()) {
+ first.convert_to_error(eco_format!("duplicate key: {}", key));
child.make_erroneous();
}
}
@@ -1073,13 +1073,19 @@ fn validate_params(p: &mut Parser, m: Marker) {
match child.kind() {
SyntaxKind::Ident => {
if !used.insert(child.text().clone()) {
- child.convert_to_error("duplicate parameter");
+ child.convert_to_error(eco_format!(
+ "duplicate parameter: {}",
+ child.text()
+ ));
}
}
SyntaxKind::Named => {
let Some(within) = child.children_mut().first_mut() else { return };
if !used.insert(within.text().clone()) {
- within.convert_to_error("duplicate parameter");
+ within.convert_to_error(eco_format!(
+ "duplicate parameter: {}",
+ within.text()
+ ));
child.make_erroneous();
}
}
@@ -1101,7 +1107,10 @@ fn validate_params(p: &mut Parser, m: Marker) {
continue;
}
if !used.insert(within.text().clone()) {
- within.convert_to_error("duplicate parameter");
+ within.convert_to_error(eco_format!(
+ "duplicate parameter: {}",
+ within.text()
+ ));
child.make_erroneous();
}
}
@@ -1122,7 +1131,10 @@ fn validate_args(p: &mut Parser, m: Marker) {
if child.kind() == SyntaxKind::Named {
let Some(within) = child.children_mut().first_mut() else { return };
if !used.insert(within.text().clone()) {
- within.convert_to_error("duplicate argument");
+ within.convert_to_error(eco_format!(
+ "duplicate argument: {}",
+ within.text()
+ ));
child.make_erroneous();
}
}
diff --git a/tests/typ/compiler/array.typ b/tests/typ/compiler/array.typ
index 97b5da52..c9e85ed7 100644
--- a/tests/typ/compiler/array.typ
+++ b/tests/typ/compiler/array.typ
@@ -224,7 +224,7 @@
// Error: 4-6 unexpected end of block comment
#(1*/2)
-// Error: 6-8 invalid number suffix
+// Error: 6-8 invalid number suffix: u
#(1, 1u 2)
// Error: 3-4 unexpected comma
diff --git a/tests/typ/compiler/block.typ b/tests/typ/compiler/block.typ
index bb23c0fe..81c719da 100644
--- a/tests/typ/compiler/block.typ
+++ b/tests/typ/compiler/block.typ
@@ -61,7 +61,7 @@
// Block directly in markup also creates a scope.
#{ let x = 1 }
-// Error: 7-8 unknown variable
+// Error: 7-8 unknown variable: x
#test(x, 1)
---
@@ -73,7 +73,7 @@
#test(a, 1)
-// Error: 3-4 unknown variable
+// Error: 3-4 unknown variable: b
#{b}
---
@@ -83,7 +83,7 @@
test(b, 1)
}}
-// Error: 2-3 unknown variable
+// Error: 2-3 unknown variable: b
#b
---
@@ -106,13 +106,13 @@
// Content blocks also create a scope.
#[#let x = 1]
-// Error: 2-3 unknown variable
+// Error: 2-3 unknown variable: x
#x
---
// Multiple unseparated expressions in one line.
-// Error: 2-4 invalid number suffix
+// Error: 2-4 invalid number suffix: u
#1u
// Should output `1`.
diff --git a/tests/typ/compiler/call.typ b/tests/typ/compiler/call.typ
index f78dec20..04eb2906 100644
--- a/tests/typ/compiler/call.typ
+++ b/tests/typ/compiler/call.typ
@@ -44,7 +44,7 @@
}
---
-// Error: 26-30 duplicate argument
+// Error: 26-30 duplicate argument: font
#set text(font: "Arial", font: "Helvetica")
---
diff --git a/tests/typ/compiler/closure.typ b/tests/typ/compiler/closure.typ
index a1e51d56..915de850 100644
--- a/tests/typ/compiler/closure.typ
+++ b/tests/typ/compiler/closure.typ
@@ -106,7 +106,7 @@
---
// Don't leak environment.
#{
- // Error: 16-17 unknown variable
+ // Error: 16-17 unknown variable: x
let func() = x
let x = "hi"
func()
@@ -141,22 +141,22 @@
test(greet("Typst"), "Hey, Typst!")
test(greet("Typst", birthday: true), "Happy Birthday, Typst!")
- // Error: 23-35 unexpected argument
+ // Error: 23-35 unexpected argument: whatever
test(greet("Typst", whatever: 10))
}
---
-// Error: 11-12 duplicate parameter
+// Error: 11-12 duplicate parameter: x
#let f(x, x) = none
---
-// Error: 14-15 duplicate parameter
-// Error: 23-24 duplicate parameter
-// Error: 35-36 duplicate parameter
+// Error: 14-15 duplicate parameter: a
+// Error: 23-24 duplicate parameter: b
+// Error: 35-36 duplicate parameter: b
#let f(a, b, a: none, b: none, c, b) = none
---
-// Error: 13-14 duplicate parameter
+// Error: 13-14 duplicate parameter: a
#let f(a, ..a) = none
---
diff --git a/tests/typ/compiler/dict.typ b/tests/typ/compiler/dict.typ
index fb0a59a3..6c982ed4 100644
--- a/tests/typ/compiler/dict.typ
+++ b/tests/typ/compiler/dict.typ
@@ -56,11 +56,11 @@
#test(dict, (a: 3, b: 1))
---
-// Error: 24-29 duplicate key
+// Error: 24-29 duplicate key: first
#(first: 1, second: 2, first: 3)
---
-// Error: 17-20 duplicate key
+// Error: 17-20 duplicate key: a
#(a: 1, "b": 2, "a": 3)
---
diff --git a/tests/typ/compiler/include.typ b/tests/typ/compiler/include.typ
index fa2e84c0..586e869b 100644
--- a/tests/typ/compiler/include.typ
+++ b/tests/typ/compiler/include.typ
@@ -24,7 +24,7 @@
#include "modules/chap1.typ"
// The variables of the file should not appear in this scope.
-// Error: 2-6 unknown variable
+// Error: 2-6 unknown variable: name
#name
---
diff --git a/tests/typ/compiler/methods.typ b/tests/typ/compiler/methods.typ
index 86faefbc..afcb024f 100644
--- a/tests/typ/compiler/methods.typ
+++ b/tests/typ/compiler/methods.typ
@@ -42,5 +42,5 @@
#(numbers.sorted() = 1)
---
-// Error: 2-5 cannot mutate a constant
+// Error: 2-5 cannot mutate a constant: box
#box.push(1)
diff --git a/tests/typ/compiler/ops-invalid.typ b/tests/typ/compiler/ops-invalid.typ
index 8ccbb8b7..3ab62929 100644
--- a/tests/typ/compiler/ops-invalid.typ
+++ b/tests/typ/compiler/ops-invalid.typ
@@ -97,7 +97,7 @@
}
---
-// Error: 4-5 unknown variable
+// Error: 4-5 unknown variable: x
#((x) = "")
---
@@ -110,15 +110,15 @@
#(not x = "a")
---
-// Error: 7-8 unknown variable
+// Error: 7-8 unknown variable: x
#(1 + x += 3)
---
-// Error: 3-4 unknown variable
+// Error: 3-4 unknown variable: z
#(z = 1)
---
-// Error: 3-7 cannot mutate a constant
+// Error: 3-7 cannot mutate a constant: rect
#(rect = "hi")
---
diff --git a/tests/typ/compiler/ops.typ b/tests/typ/compiler/ops.typ
index 1a9a2169..a6c64cbd 100644
--- a/tests/typ/compiler/ops.typ
+++ b/tests/typ/compiler/ops.typ
@@ -116,11 +116,11 @@
#test(0xA + 0xa, 0x14)
---
-// Error: 2-7 invalid binary number
+// Error: 2-7 invalid binary number: 0b123
#0b123
---
-// Error: 2-8 invalid hexadecimal number
+// Error: 2-8 invalid hexadecimal number: 0x123z
#0x123z
---
@@ -201,7 +201,7 @@
#(x += "thing") #test(x, "something")
---
-// Error: 3-6 cannot mutate a constant
+// Error: 3-6 cannot mutate a constant: box
#(box = 1)
---
diff --git a/tests/typ/compiler/recursion.typ b/tests/typ/compiler/recursion.typ
index ae214631..1bd53178 100644
--- a/tests/typ/compiler/recursion.typ
+++ b/tests/typ/compiler/recursion.typ
@@ -15,7 +15,7 @@
---
// Test with unnamed function.
-// Error: 17-18 unknown variable
+// Error: 17-18 unknown variable: f
#let f = (n) => f(n - 1)
#f(10)
diff --git a/tests/typ/text/escape.typ b/tests/typ/text/escape.typ
index 95a8a027..e7ec9023 100644
--- a/tests/typ/text/escape.typ
+++ b/tests/typ/text/escape.typ
@@ -27,7 +27,7 @@ let f() , ; : | + - /= == 12 "string"
---
// Unicode codepoint does not exist.
-// Error: 1-11 invalid unicode escape sequence
+// Error: 1-11 invalid unicode codepoint: FFFFFF
\u{FFFFFF}
---
diff --git a/tests/typ/text/font.typ b/tests/typ/text/font.typ
index 9844d066..07d00d14 100644
--- a/tests/typ/text/font.typ
+++ b/tests/typ/text/font.typ
@@ -56,5 +56,5 @@ Emoji: 🐪, 🌋, 🏞
#set text(size: 10pt, 12pt)
---
-// Error: 11-31 unexpected argument
+// Error: 11-31 unexpected argument: something
#set text(something: "invalid")
diff --git a/tests/typ/visualize/shape-circle.typ b/tests/typ/visualize/shape-circle.typ
index cde4b112..34238d9a 100644
--- a/tests/typ/visualize/shape-circle.typ
+++ b/tests/typ/visualize/shape-circle.typ
@@ -54,5 +54,5 @@ Expanded by height.
---
// Radius wins over width and height.
-// Error: 23-34 unexpected argument
+// Error: 23-34 unexpected argument: width
#circle(radius: 10pt, width: 50pt, height: 100pt, fill: eastern)
diff --git a/tests/typ/visualize/shape-square.typ b/tests/typ/visualize/shape-square.typ
index cb6552e4..a321dc4a 100644
--- a/tests/typ/visualize/shape-square.typ
+++ b/tests/typ/visualize/shape-square.typ
@@ -35,5 +35,5 @@
---
// Size wins over width and height.
-// Error: 09-20 unexpected argument
+// Error: 09-20 unexpected argument: width
#square(width: 10cm, height: 20cm, size: 1cm, fill: rgb("eb5278"))