miden_debug_types/
span.rs

1use core::{
2    borrow::Borrow,
3    fmt,
4    hash::{Hash, Hasher},
5    ops::{Bound, Deref, DerefMut, Index, Range, RangeBounds},
6};
7
8use miden_crypto::utils::{
9    ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable,
10};
11#[cfg(feature = "serde")]
12use serde::{Deserialize, Serialize};
13
14use super::{ByteIndex, ByteOffset, SourceId};
15
16/// This trait should be implemented for any type that has an associated [SourceSpan].
17pub trait Spanned {
18    fn span(&self) -> SourceSpan;
19}
20
21impl Spanned for SourceSpan {
22    #[inline(always)]
23    fn span(&self) -> SourceSpan {
24        *self
25    }
26}
27
28impl<T: ?Sized + Spanned> Spanned for alloc::boxed::Box<T> {
29    fn span(&self) -> SourceSpan {
30        (**self).span()
31    }
32}
33
34impl<T: ?Sized + Spanned> Spanned for alloc::rc::Rc<T> {
35    fn span(&self) -> SourceSpan {
36        (**self).span()
37    }
38}
39
40impl<T: ?Sized + Spanned> Spanned for alloc::sync::Arc<T> {
41    fn span(&self) -> SourceSpan {
42        (**self).span()
43    }
44}
45
46// SPAN
47// ================================================================================================
48
49/// This type is used to wrap any `T` with a [SourceSpan], and is typically used when it is not
50/// convenient to add a [SourceSpan] to the type - most commonly because we don't control the type.
51pub struct Span<T> {
52    span: SourceSpan,
53    spanned: T,
54}
55
56#[cfg(feature = "serde")]
57impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Span<T> {
58    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59    where
60        D: serde::Deserializer<'de>,
61    {
62        let spanned = T::deserialize(deserializer)?;
63        Ok(Self { span: SourceSpan::UNKNOWN, spanned })
64    }
65}
66
67#[cfg(feature = "serde")]
68impl<T: serde::Serialize> serde::Serialize for Span<T> {
69    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70    where
71        S: serde::Serializer,
72    {
73        T::serialize(&self.spanned, serializer)
74    }
75}
76
77impl<T> Spanned for Span<T> {
78    fn span(&self) -> SourceSpan {
79        self.span
80    }
81}
82
83impl<T: Copy> Copy for Span<T> {}
84
85impl<T: Clone> Clone for Span<T> {
86    fn clone(&self) -> Self {
87        Self {
88            span: self.span,
89            spanned: self.spanned.clone(),
90        }
91    }
92}
93
94impl<T: Default> Default for Span<T> {
95    fn default() -> Self {
96        Self {
97            span: SourceSpan::UNKNOWN,
98            spanned: T::default(),
99        }
100    }
101}
102
103impl<T> Span<T> {
104    /// Creates a span for `spanned` with `span`.
105    #[inline]
106    pub fn new(span: impl Into<SourceSpan>, spanned: T) -> Self {
107        Self { span: span.into(), spanned }
108    }
109
110    /// Creates a span for `spanned` representing a single location, `offset`.
111    #[inline]
112    pub fn at(source_id: SourceId, offset: usize, spanned: T) -> Self {
113        let offset = u32::try_from(offset).expect("invalid source offset: too large");
114        Self {
115            span: SourceSpan::at(source_id, offset),
116            spanned,
117        }
118    }
119
120    /// Creates a [Span] from a value with an unknown/default location.
121    pub fn unknown(spanned: T) -> Self {
122        Self { span: Default::default(), spanned }
123    }
124
125    /// Consume this [Span] and get a new one with `span` as the underlying source span
126    #[inline]
127    pub fn with_span(mut self, span: SourceSpan) -> Self {
128        self.span = span;
129        self
130    }
131
132    /// Gets the associated [SourceSpan] for this spanned item.
133    #[inline(always)]
134    pub const fn span(&self) -> SourceSpan {
135        self.span
136    }
137
138    /// Gets a reference to the spanned item.
139    #[inline(always)]
140    pub const fn inner(&self) -> &T {
141        &self.spanned
142    }
143
144    /// Applies a transformation to the spanned value while retaining the same [SourceSpan].
145    #[inline]
146    pub fn map<U, F>(self, mut f: F) -> Span<U>
147    where
148        F: FnMut(T) -> U,
149    {
150        Span {
151            span: self.span,
152            spanned: f(self.spanned),
153        }
154    }
155
156    /// Like [`Option<T>::as_deref`], this constructs a [`Span<U>`] wrapping the result of
157    /// dereferencing the inner value of type `T` as a value of type `U`.
158    pub fn as_deref<U>(&self) -> Span<&U>
159    where
160        U: ?Sized,
161        T: Deref<Target = U>,
162    {
163        Span {
164            span: self.span,
165            spanned: self.spanned.deref(),
166        }
167    }
168
169    /// Gets a new [Span] that borrows the inner value.
170    pub fn as_ref(&self) -> Span<&T> {
171        Span { span: self.span, spanned: &self.spanned }
172    }
173
174    /// Manually set the source id for the span of this item
175    ///
176    /// See also [SourceSpan::set_source_id].
177    pub fn set_source_id(&mut self, id: SourceId) {
178        self.span.set_source_id(id);
179    }
180
181    /// Shifts the span right by `count` units
182    #[inline]
183    pub fn shift(&mut self, count: ByteOffset) {
184        self.span.start += count;
185        self.span.end += count;
186    }
187
188    /// Extends the end of the span by `count` units.
189    #[inline]
190    pub fn extend(&mut self, count: ByteOffset) {
191        self.span.end += count;
192    }
193
194    /// Consumes this span, returning the component parts, i.e. the [SourceSpan] and value of type
195    /// `T`.
196    #[inline]
197    pub fn into_parts(self) -> (SourceSpan, T) {
198        (self.span, self.spanned)
199    }
200
201    /// Unwraps the spanned value of type `T`.
202    #[inline]
203    pub fn into_inner(self) -> T {
204        self.spanned
205    }
206}
207
208impl<T> Borrow<T> for Span<T> {
209    fn borrow(&self) -> &T {
210        &self.spanned
211    }
212}
213
214impl<T: Borrow<str>> Borrow<str> for Span<T> {
215    fn borrow(&self) -> &str {
216        self.spanned.borrow()
217    }
218}
219
220impl<U, T: Borrow<[U]>> Borrow<[U]> for Span<T> {
221    fn borrow(&self) -> &[U] {
222        self.spanned.borrow()
223    }
224}
225
226impl<T> Deref for Span<T> {
227    type Target = T;
228
229    #[inline(always)]
230    fn deref(&self) -> &Self::Target {
231        &self.spanned
232    }
233}
234
235impl<T> DerefMut for Span<T> {
236    #[inline(always)]
237    fn deref_mut(&mut self) -> &mut Self::Target {
238        &mut self.spanned
239    }
240}
241
242impl<T: ?Sized, U: AsRef<T>> AsRef<T> for Span<U> {
243    fn as_ref(&self) -> &T {
244        self.spanned.as_ref()
245    }
246}
247
248impl<T: ?Sized, U: AsMut<T>> AsMut<T> for Span<U> {
249    fn as_mut(&mut self) -> &mut T {
250        self.spanned.as_mut()
251    }
252}
253
254impl<T: fmt::Debug> fmt::Debug for Span<T> {
255    #[inline]
256    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
257        fmt::Debug::fmt(&self.spanned, f)
258    }
259}
260
261impl<T: fmt::Display> fmt::Display for Span<T> {
262    #[inline]
263    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
264        fmt::Display::fmt(&self.spanned, f)
265    }
266}
267
268impl<T: miden_formatting::prettier::PrettyPrint> miden_formatting::prettier::PrettyPrint
269    for Span<T>
270{
271    fn render(&self) -> miden_formatting::prettier::Document {
272        self.spanned.render()
273    }
274}
275
276impl<T: Eq> Eq for Span<T> {}
277
278impl<T: PartialEq> PartialEq for Span<T> {
279    #[inline]
280    fn eq(&self, other: &Self) -> bool {
281        self.spanned.eq(&other.spanned)
282    }
283}
284
285impl<T: PartialEq> PartialEq<T> for Span<T> {
286    #[inline]
287    fn eq(&self, other: &T) -> bool {
288        self.spanned.eq(other)
289    }
290}
291
292impl<T: Ord> Ord for Span<T> {
293    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
294        self.spanned.cmp(&other.spanned)
295    }
296}
297
298impl<T: PartialOrd> PartialOrd for Span<T> {
299    #[inline]
300    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
301        self.spanned.partial_cmp(&other.spanned)
302    }
303}
304
305impl<T: Hash> Hash for Span<T> {
306    fn hash<H: Hasher>(&self, state: &mut H) {
307        self.spanned.hash(state);
308    }
309}
310
311impl<T: Serializable> Span<T> {
312    pub fn write_into_with_options<W: ByteWriter>(&self, target: &mut W, debug: bool) {
313        if debug {
314            self.span.write_into(target);
315        }
316        self.spanned.write_into(target);
317    }
318}
319
320impl<T: Serializable> Serializable for Span<T> {
321    fn write_into<W: ByteWriter>(&self, target: &mut W) {
322        self.span.write_into(target);
323        self.spanned.write_into(target);
324    }
325}
326
327impl<T: Deserializable> Span<T> {
328    pub fn read_from_with_options<R: ByteReader>(
329        source: &mut R,
330        debug: bool,
331    ) -> Result<Self, DeserializationError> {
332        let span = if debug {
333            SourceSpan::read_from(source)?
334        } else {
335            SourceSpan::default()
336        };
337        let spanned = T::read_from(source)?;
338        Ok(Self { span, spanned })
339    }
340}
341
342impl<T: Deserializable> Deserializable for Span<T> {
343    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
344        let span = SourceSpan::read_from(source)?;
345        let spanned = T::read_from(source)?;
346        Ok(Self { span, spanned })
347    }
348}
349
350// SOURCE SPAN
351// ================================================================================================
352
353/// This represents a span of bytes in a Miden Assembly source file.
354///
355/// It is compact, using only 8 bytes to represent the full span. This does, however, come at the
356/// tradeoff of only supporting source files of up to 2^32 bytes.
357///
358/// This type is produced by the lexer and carried through parsing. It can be converted into a
359/// line/column range as well, if needed.
360///
361/// This representation is more convenient to produce, and allows showing source spans in error
362/// messages, whereas line/column information is useful at a glance in debug output, it is harder
363/// to produce nice errors with it compared to this representation.
364#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
365#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
366pub struct SourceSpan {
367    #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "SourceId::is_unknown"))]
368    source_id: SourceId,
369    start: ByteIndex,
370    end: ByteIndex,
371}
372
373#[derive(Debug, thiserror::Error)]
374#[error("invalid byte index range: maximum supported byte index is 2^32")]
375pub struct InvalidByteIndexRange;
376
377impl SourceSpan {
378    /// A sentinel [SourceSpan] that indicates the span is unknown/invalid
379    pub const UNKNOWN: Self = Self {
380        source_id: SourceId::UNKNOWN,
381        start: ByteIndex::new(0),
382        end: ByteIndex::new(0),
383    };
384
385    /// Creates a new [SourceSpan] from the given range.
386    pub fn new<B>(source_id: SourceId, range: Range<B>) -> Self
387    where
388        B: Into<ByteIndex>,
389    {
390        Self {
391            source_id,
392            start: range.start.into(),
393            end: range.end.into(),
394        }
395    }
396
397    /// Creates a new [SourceSpan] for a specific offset.
398    pub fn at(source_id: SourceId, offset: impl Into<ByteIndex>) -> Self {
399        let offset = offset.into();
400        Self { source_id, start: offset, end: offset }
401    }
402
403    /// Try to create a new [SourceSpan] from the given range with `usize` bounds.
404    pub fn try_from_range(
405        source_id: SourceId,
406        range: Range<usize>,
407    ) -> Result<Self, InvalidByteIndexRange> {
408        const MAX: usize = u32::MAX as usize;
409        if range.start > MAX || range.end > MAX {
410            return Err(InvalidByteIndexRange);
411        }
412
413        Ok(SourceSpan {
414            source_id,
415            start: ByteIndex::from(range.start as u32),
416            end: ByteIndex::from(range.end as u32),
417        })
418    }
419
420    /// Returns `true` if this [SourceSpan] represents the unknown span
421    pub const fn is_unknown(&self) -> bool {
422        self.source_id.is_unknown()
423    }
424
425    /// Get the [SourceId] associated with this source span
426    #[inline(always)]
427    pub fn source_id(&self) -> SourceId {
428        self.source_id
429    }
430
431    /// Manually set the [SourceId] associated with this source span
432    ///
433    /// This is useful in cases where the range of the span is known, but the source id itself
434    /// is not available yet, due to scope or some other limitation. In such cases you might wish
435    /// to visit parsed objects once the source id is available, and update all of their spans
436    /// accordingly.
437    pub fn set_source_id(&mut self, id: SourceId) {
438        self.source_id = id;
439    }
440
441    /// Gets the offset in bytes corresponding to the start of this span (inclusive).
442    #[inline(always)]
443    pub fn start(&self) -> ByteIndex {
444        self.start
445    }
446
447    /// Gets the offset in bytes corresponding to the end of this span (exclusive).
448    #[inline(always)]
449    pub fn end(&self) -> ByteIndex {
450        self.end
451    }
452
453    /// Gets the length of this span in bytes.
454    #[inline(always)]
455    pub fn len(&self) -> usize {
456        self.end.to_usize() - self.start.to_usize()
457    }
458
459    /// Returns true if this span is empty.
460    pub fn is_empty(&self) -> bool {
461        self.len() == 0
462    }
463
464    /// Converts this span into a [`Range<u32>`].
465    #[inline]
466    pub fn into_range(self) -> Range<u32> {
467        self.start.to_u32()..self.end.to_u32()
468    }
469
470    /// Converts this span into a [`Range<usize>`].
471    #[inline]
472    pub fn into_slice_index(self) -> Range<usize> {
473        self.start.to_usize()..self.end.to_usize()
474    }
475}
476
477impl From<SourceSpan> for miette::SourceSpan {
478    fn from(span: SourceSpan) -> Self {
479        Self::new(miette::SourceOffset::from(span.start().to_usize()), span.len())
480    }
481}
482
483impl Serializable for SourceSpan {
484    fn write_into<W: ByteWriter>(&self, target: &mut W) {
485        target.write_u32(self.source_id.to_u32());
486        target.write_u32(self.start.into());
487        target.write_u32(self.end.into())
488    }
489}
490
491impl Deserializable for SourceSpan {
492    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
493        let source_id = SourceId::new_unchecked(source.read_u32()?);
494        let start = ByteIndex::from(source.read_u32()?);
495        let end = ByteIndex::from(source.read_u32()?);
496        Ok(Self { source_id, start, end })
497    }
498}
499
500impl From<SourceSpan> for Range<u32> {
501    #[inline(always)]
502    fn from(span: SourceSpan) -> Self {
503        span.into_range()
504    }
505}
506
507impl From<SourceSpan> for Range<usize> {
508    #[inline(always)]
509    fn from(span: SourceSpan) -> Self {
510        span.into_slice_index()
511    }
512}
513
514impl From<Range<u32>> for SourceSpan {
515    #[inline]
516    fn from(range: Range<u32>) -> Self {
517        Self::new(SourceId::UNKNOWN, range)
518    }
519}
520
521impl From<Range<ByteIndex>> for SourceSpan {
522    #[inline]
523    fn from(range: Range<ByteIndex>) -> Self {
524        Self {
525            source_id: SourceId::UNKNOWN,
526            start: range.start,
527            end: range.end,
528        }
529    }
530}
531
532impl Index<SourceSpan> for [u8] {
533    type Output = [u8];
534
535    #[inline]
536    fn index(&self, index: SourceSpan) -> &Self::Output {
537        &self[index.start().to_usize()..index.end().to_usize()]
538    }
539}
540
541impl RangeBounds<ByteIndex> for SourceSpan {
542    #[inline(always)]
543    fn start_bound(&self) -> Bound<&ByteIndex> {
544        Bound::Included(&self.start)
545    }
546
547    #[inline(always)]
548    fn end_bound(&self) -> Bound<&ByteIndex> {
549        Bound::Excluded(&self.end)
550    }
551}