summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/eval/call.rs26
-rw-r--r--tests/typ/compiler/dict.typ1
-rw-r--r--tests/typ/compiler/methods.typ6
3 files changed, 27 insertions, 6 deletions
diff --git a/crates/typst/src/eval/call.rs b/crates/typst/src/eval/call.rs
index 9e4a128f..a4b05777 100644
--- a/crates/typst/src/eval/call.rs
+++ b/crates/typst/src/eval/call.rs
@@ -1,5 +1,5 @@
use comemo::{Prehashed, Tracked, TrackedMut};
-use ecow::EcoVec;
+use ecow::{eco_format, EcoVec};
use crate::diag::{bail, error, At, HintedStrResult, SourceResult, Trace, Tracepoint};
use crate::engine::Engine;
@@ -99,13 +99,27 @@ impl Eval for ast::FuncCall<'_> {
field.as_str()
);
- if let Value::Dict(dict) = target {
- if matches!(dict.get(&field), Ok(Value::Func(_))) {
- error.hint(
- "to call the function stored in the dictionary, \
+ let mut field_hint = || {
+ if target.field(&field).is_ok() {
+ error.hint(eco_format!(
+ "did you mean to access the field `{}`?",
+ field.as_str()
+ ));
+ }
+ };
+
+ match target {
+ Value::Dict(ref dict) => {
+ if matches!(dict.get(&field), Ok(Value::Func(_))) {
+ error.hint(
+ "to call the function stored in the dictionary, \
surround the field access with parentheses",
- );
+ );
+ } else {
+ field_hint();
+ }
}
+ _ => field_hint(),
}
bail!(error);
diff --git a/tests/typ/compiler/dict.typ b/tests/typ/compiler/dict.typ
index 138aa7d4..e66d8099 100644
--- a/tests/typ/compiler/dict.typ
+++ b/tests/typ/compiler/dict.typ
@@ -119,6 +119,7 @@
)
// Error: 8-15 type dictionary has no method `nonfunc`
+ // Hint: 8-15 did you mean to access the field `nonfunc`?
dict.nonfunc()
}
diff --git a/tests/typ/compiler/methods.typ b/tests/typ/compiler/methods.typ
index 692f9ab3..f3ec4434 100644
--- a/tests/typ/compiler/methods.typ
+++ b/tests/typ/compiler/methods.typ
@@ -36,6 +36,12 @@
#numbers.fun()
---
+// Error: 2:4-2:10 type content has no method `stroke`
+// Hint: 2:4-2:10 did you mean to access the field `stroke`?
+#let l = line(stroke: red)
+#l.stroke()
+
+---
// Error: 2:2-2:43 cannot mutate a temporary value
#let numbers = (1, 2, 3)
#numbers.map(v => v / 2).sorted().map(str).remove(4)