diff options
| author | Laurenz <laurmaedje@gmail.com> | 2024-02-21 15:11:35 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-21 14:11:35 +0000 |
| commit | 56ecd6c806ab32a7cca5289500504e398198d283 (patch) | |
| tree | 1b6fd1b34922d2877a714398beedb20f3e6cd317 /crates | |
| parent | 23756f9e8b0e3bf5b3e1126f681024575cca4529 (diff) | |
Wider callsite span (#3466)
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/typst/src/eval/access.rs | 2 | ||||
| -rw-r--r-- | crates/typst/src/eval/call.rs | 12 | ||||
| -rw-r--r-- | crates/typst/src/eval/rules.rs | 2 | ||||
| -rw-r--r-- | crates/typst/src/foundations/args.rs | 15 | ||||
| -rw-r--r-- | crates/typst/src/foundations/calc.rs | 22 |
5 files changed, 34 insertions, 19 deletions
diff --git a/crates/typst/src/eval/access.rs b/crates/typst/src/eval/access.rs index e3bf2bf0..6b6dff15 100644 --- a/crates/typst/src/eval/access.rs +++ b/crates/typst/src/eval/access.rs @@ -56,7 +56,7 @@ impl Access for ast::FuncCall<'_> { if is_accessor_method(&method) { let span = self.span(); let world = vm.world(); - let args = self.args().eval(vm)?; + let args = self.args().eval(vm)?.spanned(span); let value = access.target().access(vm)?; let result = call_method_access(value, &method, args, span); let point = || Tracepoint::Call(Some(method.get().clone())); diff --git a/crates/typst/src/eval/call.rs b/crates/typst/src/eval/call.rs index 26626b1e..3f7224d8 100644 --- a/crates/typst/src/eval/call.rs +++ b/crates/typst/src/eval/call.rs @@ -12,7 +12,7 @@ use crate::introspection::{Introspector, Locator}; use crate::math::{Accent, AccentElem, LrElem}; use crate::symbols::Symbol; use crate::syntax::ast::{self, AstNode}; -use crate::syntax::{Spanned, SyntaxNode}; +use crate::syntax::{Span, Spanned, SyntaxNode}; use crate::text::TextElem; use crate::util::LazyHash; use crate::World; @@ -40,7 +40,7 @@ impl Eval for ast::FuncCall<'_> { let field_span = field.span(); let target = if is_mutating_method(&field) { - let mut args = args.eval(vm)?; + let mut args = args.eval(vm)?.spanned(span); let target = target.access(vm)?; // Only arrays and dictionaries have mutable methods. @@ -59,7 +59,7 @@ impl Eval for ast::FuncCall<'_> { access.target().eval(vm)? }; - let mut args = args.eval(vm)?; + let mut args = args.eval(vm)?.spanned(span); // Handle plugins. if let Value::Plugin(plugin) = &target { @@ -126,7 +126,7 @@ impl Eval for ast::FuncCall<'_> { bail!(error); } } else { - (callee.eval(vm)?, args.eval(vm)?) + (callee.eval(vm)?, args.eval(vm)?.spanned(span)) }; // Handle math special cases for non-functions: @@ -222,7 +222,9 @@ impl Eval for ast::Args<'_> { } } - Ok(Args { span: self.span(), items }) + // We do *not* use the `self.span()` here because we want the callsite + // span to be one level higher (the whole function call). + Ok(Args { span: Span::detached(), items }) } } diff --git a/crates/typst/src/eval/rules.rs b/crates/typst/src/eval/rules.rs index e34fe5cd..f5d7da17 100644 --- a/crates/typst/src/eval/rules.rs +++ b/crates/typst/src/eval/rules.rs @@ -23,7 +23,7 @@ impl Eval for ast::SetRule<'_> { }) }) .at(target.span())?; - let args = self.args().eval(vm)?; + let args = self.args().eval(vm)?.spanned(self.span()); Ok(target.set(&mut vm.engine, args)?.spanned(self.span())) } } diff --git a/crates/typst/src/foundations/args.rs b/crates/typst/src/foundations/args.rs index 54811437..4624ae02 100644 --- a/crates/typst/src/foundations/args.rs +++ b/crates/typst/src/foundations/args.rs @@ -42,7 +42,8 @@ use crate::syntax::{Span, Spanned}; #[derive(Clone, Hash)] #[allow(clippy::derived_hash_with_manual_eq)] pub struct Args { - /// The span of the whole argument list. + /// The callsite span for the function. This is not the span of the argument + /// list itself, but of the whole function call. pub span: Span, /// The positional and named arguments. pub items: EcoVec<Arg>, @@ -62,6 +63,14 @@ impl Args { Self { span, items } } + /// Attach a span to these arguments if they don't already have one. + pub fn spanned(mut self, span: Span) -> Self { + if self.span.is_detached() { + self.span = span; + } + self + } + /// Returns the number of remaining positional arguments. pub fn remaining(&self) -> usize { self.items.iter().filter(|slot| slot.name.is_none()).count() @@ -345,8 +354,8 @@ pub trait IntoArgs { } impl IntoArgs for Args { - fn into_args(self, _: Span) -> Args { - self + fn into_args(self, fallback: Span) -> Args { + self.spanned(fallback) } } diff --git a/crates/typst/src/foundations/calc.rs b/crates/typst/src/foundations/calc.rs index c65102ce..eb0b59dd 100644 --- a/crates/typst/src/foundations/calc.rs +++ b/crates/typst/src/foundations/calc.rs @@ -114,11 +114,9 @@ pub fn pow( }; let result = match (base, exponent.v) { - (Num::Int(a), Num::Int(b)) if b >= 0 => a - .checked_pow(b as u32) - .map(Num::Int) - .ok_or("the result is too large") - .at(span)?, + (Num::Int(a), Num::Int(b)) if b >= 0 => { + a.checked_pow(b as u32).map(Num::Int).ok_or_else(too_large).at(span)? + } (a, b) => Num::Float(if a.float() == std::f64::consts::E { b.float().exp() } else if a.float() == 2.0 { @@ -469,7 +467,7 @@ pub fn fact( /// The number whose factorial to calculate. Must be non-negative. number: u64, ) -> StrResult<i64> { - Ok(fact_impl(1, number).ok_or("the result is too large")?) + Ok(fact_impl(1, number).ok_or_else(too_large)?) } /// Calculates a permutation. @@ -493,7 +491,7 @@ pub fn perm( return Ok(0); } - Ok(fact_impl(base - numbers + 1, base).ok_or("the result is too large")?) + Ok(fact_impl(base - numbers + 1, base).ok_or_else(too_large)?) } /// Calculates the product of a range of numbers. Used to calculate @@ -528,7 +526,7 @@ pub fn binom( /// The lower coefficient. Must be non-negative. k: u64, ) -> StrResult<i64> { - Ok(binom_impl(n, k).ok_or("the result is too large")?) + Ok(binom_impl(n, k).ok_or_else(too_large)?) } /// Calculates a binomial coefficient, with `n` the upper coefficient and `k` @@ -594,7 +592,7 @@ pub fn lcm( Ok(a.checked_div(gcd(a, b)) .and_then(|gcd| gcd.checked_mul(b)) .map(|v| v.abs()) - .ok_or("the return value is too large")?) + .ok_or_else(too_large)?) } /// Rounds a number down to the nearest integer. @@ -974,3 +972,9 @@ cast! { v: f64 => Self::Float(v), v: Angle => Self::Angle(v), } + +/// The error message when the result is too large to be represented. +#[cold] +fn too_large() -> &'static str { + "the result is too large" +} |
