perf: reduce size of LoadError

This commit is contained in:
Tobias Schmitz 2025-05-20 14:26:05 +02:00
parent 1c4eea8353
commit fc9697fd46
No known key found for this signature in database
4 changed files with 32 additions and 22 deletions

View File

@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
use std::str::Utf8Error; use std::str::Utf8Error;
use std::string::FromUtf8Error; use std::string::FromUtf8Error;
use az::SaturatingAs;
use comemo::Tracked; use comemo::Tracked;
use ecow::{eco_vec, EcoVec}; use ecow::{eco_vec, EcoVec};
use typst_syntax::package::{PackageSpec, PackageVersion}; use typst_syntax::package::{PackageSpec, PackageVersion};
@ -680,11 +681,11 @@ impl Loaded {
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub enum ReportPos { pub enum ReportPos {
/// Contains the range, and the 0-based line/column. /// Contains a range, and a line/column pair.
Full(std::ops::Range<usize>, LineCol), Full(std::ops::Range<u32>, LineCol),
/// Contains the range. /// Contains a range.
Range(std::ops::Range<usize>), Range(std::ops::Range<u32>),
/// Contains the 0-based line/column. /// Contains a line/column pair.
LineCol(LineCol), LineCol(LineCol),
#[default] #[default]
None, None,
@ -692,7 +693,7 @@ pub enum ReportPos {
impl From<std::ops::Range<usize>> for ReportPos { impl From<std::ops::Range<usize>> for ReportPos {
fn from(value: std::ops::Range<usize>) -> Self { fn from(value: std::ops::Range<usize>) -> Self {
Self::Range(value) Self::Range(value.start.saturating_as()..value.end.saturating_as())
} }
} }
@ -703,12 +704,18 @@ impl From<LineCol> for ReportPos {
} }
impl ReportPos { impl ReportPos {
pub fn full(range: std::ops::Range<usize>, pair: LineCol) -> Self {
let range = range.start.saturating_as()..range.end.saturating_as();
Self::Full(range, pair)
}
fn range(&self, lines: &Lines<String>) -> Option<std::ops::Range<usize>> { fn range(&self, lines: &Lines<String>) -> Option<std::ops::Range<usize>> {
match self { match self {
ReportPos::Full(range, _) => Some(range.clone()), ReportPos::Full(range, _) => Some(range.start as usize..range.end as usize),
ReportPos::Range(range) => Some(range.clone()), ReportPos::Range(range) => Some(range.start as usize..range.end as usize),
&ReportPos::LineCol(pair) => { &ReportPos::LineCol(pair) => {
let i = lines.line_column_to_byte(pair.line, pair.col)?; let i =
lines.line_column_to_byte(pair.line as usize, pair.col as usize)?;
Some(i..i) Some(i..i)
} }
ReportPos::None => None, ReportPos::None => None,
@ -719,7 +726,7 @@ impl ReportPos {
match self { match self {
&ReportPos::Full(_, pair) => Some(pair), &ReportPos::Full(_, pair) => Some(pair),
ReportPos::Range(range) => { ReportPos::Range(range) => {
let (line, col) = lines.byte_to_line_column(range.start)?; let (line, col) = lines.byte_to_line_column(range.start as usize)?;
Some(LineCol::zero_based(line, col)) Some(LineCol::zero_based(line, col))
} }
&ReportPos::LineCol(pair) => Some(pair), &ReportPos::LineCol(pair) => Some(pair),
@ -732,7 +739,9 @@ impl ReportPos {
fn try_line_col(&self, bytes: &[u8]) -> Option<LineCol> { fn try_line_col(&self, bytes: &[u8]) -> Option<LineCol> {
match self { match self {
&ReportPos::Full(_, pair) => Some(pair), &ReportPos::Full(_, pair) => Some(pair),
ReportPos::Range(range) => LineCol::try_from_byte_pos(range.start, bytes), ReportPos::Range(range) => {
LineCol::try_from_byte_pos(range.start as usize, bytes)
}
&ReportPos::LineCol(pair) => Some(pair), &ReportPos::LineCol(pair) => Some(pair),
ReportPos::None => None, ReportPos::None => None,
} }
@ -743,23 +752,23 @@ impl ReportPos {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct LineCol { pub struct LineCol {
/// The 0-based line. /// The 0-based line.
line: usize, line: u32,
/// The 0-based column. /// The 0-based column.
col: usize, col: u32,
} }
impl LineCol { impl LineCol {
/// Constructs the line/column pair from 0-based indices. /// Constructs the line/column pair from 0-based indices.
pub fn zero_based(line: usize, col: usize) -> Self { pub fn zero_based(line: usize, col: usize) -> Self {
Self { line, col } Self {
line: line.saturating_as(),
col: col.saturating_as(),
}
} }
/// Constructs the line/column pair from 1-based numbers. /// Constructs the line/column pair from 1-based numbers.
pub fn one_based(line: usize, col: usize) -> Self { pub fn one_based(line: usize, col: usize) -> Self {
Self { Self::zero_based(line.saturating_sub(1), col.saturating_sub(1))
line: line.saturating_sub(1),
col: col.saturating_sub(1),
}
} }
/// Try to compute a line/column pair from possibly invalid utf-8 data. /// Try to compute a line/column pair from possibly invalid utf-8 data.

View File

@ -1,3 +1,4 @@
use az::SaturatingAs;
use ecow::EcoVec; use ecow::EcoVec;
use typst_syntax::Spanned; use typst_syntax::Spanned;
@ -171,8 +172,8 @@ fn format_csv_error(
let msg = "failed to parse CSV"; let msg = "failed to parse CSV";
let pos = (err.kind().position()) let pos = (err.kind().position())
.map(|pos| { .map(|pos| {
let start = pos.byte() as usize; let start = pos.byte().saturating_as();
ReportPos::Range(start..start) ReportPos::from(start..start)
}) })
.unwrap_or(LineCol::one_based(line, 1).into()); .unwrap_or(LineCol::one_based(line, 1).into());
match err.kind() { match err.kind() {

View File

@ -85,7 +85,7 @@ pub fn format_yaml_error(
.map(|loc| { .map(|loc| {
let line_col = LineCol::one_based(loc.line(), loc.column()); let line_col = LineCol::one_based(loc.line(), loc.column());
let range = loc.index()..loc.index(); let range = loc.index()..loc.index();
ReportPos::Full(range, line_col) ReportPos::full(range, line_col)
}) })
.unwrap_or_default(); .unwrap_or_default();
data.err_in_text(pos, "failed to parse YAML", error) data.err_in_text(pos, "failed to parse YAML", error)

View File

@ -580,7 +580,7 @@ fn syntax_error_pos(error: &ParseSyntaxError) -> ReportPos {
match error { match error {
ParseSyntaxError::InvalidYaml(scan_error) => { ParseSyntaxError::InvalidYaml(scan_error) => {
let m = scan_error.marker(); let m = scan_error.marker();
ReportPos::Full( ReportPos::full(
m.index()..m.index(), m.index()..m.index(),
LineCol::one_based(m.line(), m.col() + 1), LineCol::one_based(m.line(), m.col() + 1),
) )