Skip to main content

patch_prolog_shared/
span.rs

1//! Source spans — byte ranges into a source file, for diagnostics and
2//! (later) runtime error provenance.
3//!
4//! Value types only. A `Span` is **never** embedded in a `Term` variant, so
5//! `Term`'s `PartialEq`/identity is unaffected — spans annotate the AST from
6//! the outside (`Spanned<T>`), they don't change what a term *is*.
7//!
8//! Line/column is deliberately not stored here: it is a presentation concern
9//! resolved from the source text at format time (see `plg_frontend`'s
10//! `SourceMap`). Byte offsets are the stable representation.
11
12/// Identifies a source file. Single-buffer today (always `0`); multi-file
13/// mapping arrives with `plgc build`'s concatenated inputs.
14pub type FileId = u32;
15
16/// A byte range `[lo, hi)` into a source file.
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
18pub struct Span {
19    pub file: FileId,
20    pub lo: u32,
21    pub hi: u32,
22}
23
24impl Span {
25    pub fn new(file: FileId, lo: u32, hi: u32) -> Self {
26        Self { file, lo, hi }
27    }
28
29    /// A zero-width span at `offset` — for point diagnostics like
30    /// unexpected-end-of-input where there is no lexeme to underline.
31    pub fn point(file: FileId, offset: u32) -> Self {
32        Self {
33            file,
34            lo: offset,
35            hi: offset,
36        }
37    }
38}
39
40/// A value annotated with its source span — carries spans alongside the AST
41/// without putting one inside `Term` itself.
42///
43/// Consumers: the parser's spanned body conjuncts (`Spanned<Term>`, codegen
44/// path) and the compiler's lowered goal IR (`type LGoal = Spanned<LGoalKind>`,
45/// SPANS.md Layer 3), where every goal carries its source span so raising
46/// call sites get `site_id` provenance with no per-variant plumbing. The
47/// undefined-call lint still uses the parser's flat `CallSite` occurrences.
48#[derive(Debug, Clone, PartialEq)]
49pub struct Spanned<T> {
50    pub node: T,
51    pub span: Span,
52}
53
54impl<T> Spanned<T> {
55    pub fn new(node: T, span: Span) -> Self {
56        Self { node, span }
57    }
58}