summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/typst/src/eval/ops.rs18
-rw-r--r--crates/typst/src/eval/ty.rs8
-rw-r--r--tests/typ/compiler/type-compatibility.typ10
3 files changed, 36 insertions, 0 deletions
diff --git a/crates/typst/src/eval/ops.rs b/crates/typst/src/eval/ops.rs
index e44c3a41..23a32416 100644
--- a/crates/typst/src/eval/ops.rs
+++ b/crates/typst/src/eval/ops.rs
@@ -34,6 +34,11 @@ pub fn join(lhs: Value, rhs: Value) -> StrResult<Value> {
(Symbol(a), Content(b)) => Content(item!(text)(a.get().into()) + b),
(Array(a), Array(b)) => Array(a + b),
(Dict(a), Dict(b)) => Dict(a + b),
+
+ // Type compatibility.
+ (Type(a), Str(b)) => Str(format_str!("{a}{b}")),
+ (Str(a), Type(b)) => Str(format_str!("{a}{b}")),
+
(a, b) => mismatch!("cannot join {} with {}", a, b),
})
}
@@ -119,6 +124,10 @@ pub fn add(lhs: Value, rhs: Value) -> StrResult<Value> {
(Datetime(a), Duration(b)) => Datetime(a + b),
(Duration(a), Datetime(b)) => Datetime(b + a),
+ // Type compatibility.
+ (Type(a), Str(b)) => Str(format_str!("{a}{b}")),
+ (Str(a), Type(b)) => Str(format_str!("{a}{b}")),
+
(Dyn(a), Dyn(b)) => {
// Alignments can be summed.
if let (Some(&a), Some(&b)) = (a.downcast::<Align>(), b.downcast::<Align>()) {
@@ -380,6 +389,10 @@ pub fn equal(lhs: &Value, rhs: &Value) -> bool {
(&Relative(a), &Length(b)) => a.abs == b && a.rel.is_zero(),
(&Relative(a), &Ratio(b)) => a.rel == b && a.abs.is_zero(),
+ // Type compatibility.
+ (Type(a), Str(b)) => a.compat_name() == b.as_str(),
+ (Str(a), Type(b)) => a.as_str() == b.compat_name(),
+
_ => false,
}
}
@@ -449,6 +462,11 @@ pub fn contains(lhs: &Value, rhs: &Value) -> Option<bool> {
(Dyn(a), Str(b)) => a.downcast::<Regex>().map(|regex| regex.is_match(b)),
(Str(a), Dict(b)) => Some(b.contains(a)),
(a, Array(b)) => Some(b.contains(a.clone())),
+
+ // Type compatibility.
+ (Type(a), Str(b)) => Some(b.as_str().contains(a.compat_name())),
+ (Type(a), Dict(b)) => Some(b.contains(a.compat_name())),
+
_ => Option::None,
}
}
diff --git a/crates/typst/src/eval/ty.rs b/crates/typst/src/eval/ty.rs
index f7832672..da3c91aa 100644
--- a/crates/typst/src/eval/ty.rs
+++ b/crates/typst/src/eval/ty.rs
@@ -80,6 +80,14 @@ impl Type {
}
}
+// Type compatibility.
+impl Type {
+ /// The type's backwards-compatible name.
+ pub fn compat_name(&self) -> &str {
+ self.long_name()
+ }
+}
+
#[scope]
impl Type {
/// Determines a value's type.
diff --git a/tests/typ/compiler/type-compatibility.typ b/tests/typ/compiler/type-compatibility.typ
new file mode 100644
index 00000000..664981f4
--- /dev/null
+++ b/tests/typ/compiler/type-compatibility.typ
@@ -0,0 +1,10 @@
+// Test compatibility between types and strings.
+// Ref: false
+
+---
+#test(type(10), int)
+#test(type(10), "integer")
+#test("is " + type(10), "is integer")
+#test(int in ("integer", "string"), true)
+#test(int in "integers or strings", true)
+#test(str in "integers or strings", true)