pub struct Spanned<T> {
pub value: T,
pub span: Span,
pub file_id: u16,
}Expand description
A value with an associated source location (span and file).
PartialEq / Eq / Hash are implemented manually to delegate to
the inner value only — two Spanned<T> values are considered equal
when their Ts are equal, regardless of where they came from in
source. This matches the principle that “what” a value is should
not depend on where it lives. Consumers that genuinely need
location-sensitive equality compare .span and .file_id
explicitly.
Note: the rkyv-archived form (ArchivedSpanned<T>, present under the
rkyv feature) does not automatically receive PartialEq /
Eq. The host doesn’t compare archived values today; if a future
code path needs to, add rkyv(compare = (PartialEq)) to the derive
attribute below or hand-roll a manual impl on the archived type.
§#[non_exhaustive] policy
Deliberately NOT #[non_exhaustive], for the same reason as
Span: it is constructed via struct literal in hundreds of
call sites and the field set is intentionally minimal and stable.
Add fields cautiously; if a new field is genuinely needed, prefer
a sibling/wrapper type over modifying this one in place.
Fields§
§value: TThe value.
span: SpanThe source span (byte offsets within the file).
file_id: u16The source file ID (index into SourceMap).
Uses u16 to minimize struct size (max 65,535 files).
Implementations§
Source§impl<T> Spanned<T>
impl<T> Spanned<T>
Sourcepub const fn new(value: T, span: Span) -> Spanned<T>
pub const fn new(value: T, span: Span) -> Spanned<T>
Create a new spanned value with file_id defaulting to 0.
Use with_file_id to set the correct file ID after creation.
Sourcepub const fn synthesized(value: T) -> Spanned<T>
pub const fn synthesized(value: T) -> Spanned<T>
Wrap a value that was programmatically synthesized (no source
representation). Uses Span::ZERO and SYNTHESIZED_FILE_ID
so downstream consumers can detect “no source” without sentinel
checks on the inner value’s fields.
Used by plugin-synthesized AST nodes, test fixtures, CLI commands that build directives in-memory, and any other producer that does not parse from source bytes.
Sourcepub fn with_file_id(self, file_id: usize) -> Spanned<T>
pub fn with_file_id(self, file_id: usize) -> Spanned<T>
Set the file ID for this spanned value.
Accepts usize for API convenience but stores as u16 internally.
§Panics
Debug builds will panic if file_id exceeds u16::MAX (65,535).
Sourcepub fn map<U, F>(self, f: F) -> Spanned<U>where
F: FnOnce(T) -> U,
pub fn map<U, F>(self, f: F) -> Spanned<U>where
F: FnOnce(T) -> U,
Map the inner value, preserving span and file_id.
Sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Unwrap the spanned value, discarding the span and file_id.
Trait Implementations§
Source§impl<T> Archive for Spanned<T>
impl<T> Archive for Spanned<T>
Source§type Archived = ArchivedSpanned<T>
type Archived = ArchivedSpanned<T>
Source§type Resolver = SpannedResolver<T>
type Resolver = SpannedResolver<T>
Source§fn resolve(
&self,
resolver: <Spanned<T> as Archive>::Resolver,
out: Place<<Spanned<T> as Archive>::Archived>,
)
fn resolve( &self, resolver: <Spanned<T> as Archive>::Resolver, out: Place<<Spanned<T> as Archive>::Archived>, )
Source§const COPY_OPTIMIZATION: CopyOptimization<Self> = _
const COPY_OPTIMIZATION: CopyOptimization<Self> = _
serialize. Read moreSource§impl<T> Deref for Spanned<T>
Spanned<T> is a transparent wrapper that adds source location to a
value. Following the convention used by other transparent wrappers in
the standard library (Box<T>, Rc<T>, Cow<'_, T>, MutexGuard<T>),
it implements Deref so callers can read inner fields and call inner
methods without spelling .value everywhere. Consumers that genuinely
need to inspect the source location reach for .span, .file_id, or
.value (for ownership) explicitly.
impl<T> Deref for Spanned<T>
Spanned<T> is a transparent wrapper that adds source location to a
value. Following the convention used by other transparent wrappers in
the standard library (Box<T>, Rc<T>, Cow<'_, T>, MutexGuard<T>),
it implements Deref so callers can read inner fields and call inner
methods without spelling .value everywhere. Consumers that genuinely
need to inspect the source location reach for .span, .file_id, or
.value (for ownership) explicitly.
Source§impl<'de, T> Deserialize<'de> for Spanned<T>where
T: Deserialize<'de>,
impl<'de, T> Deserialize<'de> for Spanned<T>where
T: Deserialize<'de>,
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<Spanned<T>, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Spanned<T>, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl<T> Eq for Spanned<T>where
T: Eq,
Source§impl<T> PartialEq for Spanned<T>where
T: PartialEq,
impl<T> PartialEq for Spanned<T>where
T: PartialEq,
Source§impl<T> Serialize for Spanned<T>where
T: Serialize,
impl<T> Serialize for Spanned<T>where
T: Serialize,
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Source§impl<T> ShiftSpans for Spanned<T>where
T: ShiftSpans,
impl<T> ShiftSpans for Spanned<T>where
T: ShiftSpans,
Auto Trait Implementations§
impl<T> Freeze for Spanned<T>where
T: Freeze,
impl<T> RefUnwindSafe for Spanned<T>where
T: RefUnwindSafe,
impl<T> Send for Spanned<T>where
T: Send,
impl<T> Sync for Spanned<T>where
T: Sync,
impl<T> Unpin for Spanned<T>where
T: Unpin,
impl<T> UnsafeUnpin for Spanned<T>where
T: UnsafeUnpin,
impl<T> UnwindSafe for Spanned<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
Source§type ArchivedMetadata = ()
type ArchivedMetadata = ()
Source§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
Source§impl<T> ArchiveUnsized for Twhere
T: Archive,
impl<T> ArchiveUnsized for Twhere
T: Archive,
Source§type Archived = <T as Archive>::Archived
type Archived = <T as Archive>::Archived
Archive, it may be
unsized. Read moreSource§fn archived_metadata(
&self,
) -> <<T as ArchiveUnsized>::Archived as ArchivePointee>::ArchivedMetadata
fn archived_metadata( &self, ) -> <<T as ArchiveUnsized>::Archived as ArchivePointee>::ArchivedMetadata
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CryptoRng for T
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> LayoutRaw for T
impl<T> LayoutRaw for T
Source§fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
fn layout_raw(_: <T as Pointee>::Metadata) -> Result<Layout, LayoutError>
Source§impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
impl<T, N1, N2> Niching<NichedOption<T, N1>> for N2
Source§unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
unsafe fn is_niched(niched: *const NichedOption<T, N1>) -> bool
Source§fn resolve_niched(out: Place<NichedOption<T, N1>>)
fn resolve_niched(out: Place<NichedOption<T, N1>>)
out indicating that a T is niched.Source§impl<T, S> SerializeUnsized<S> for T
impl<T, S> SerializeUnsized<S> for T
Source§impl<T> Source for T
impl<T> Source for T
Source§type Slice<'a> = <<T as Deref>::Target as Source>::Slice<'a>
where
T: 'a
type Slice<'a> = <<T as Deref>::Target as Source>::Slice<'a> where T: 'a
Source can be sliced into.Source§fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>where
Chunk: Chunk<'a>,
fn read<'a, Chunk>(&'a self, offset: usize) -> Option<Chunk>where
Chunk: Chunk<'a>,
None when reading
out of bounds would occur. Read moreSource§fn slice(&self, range: Range<usize>) -> Option<<T as Source>::Slice<'_>>
fn slice(&self, range: Range<usize>) -> Option<<T as Source>::Slice<'_>>
slice::get(range). Read moreSource§unsafe fn slice_unchecked(
&self,
range: Range<usize>,
) -> <T as Source>::Slice<'_>
unsafe fn slice_unchecked( &self, range: Range<usize>, ) -> <T as Source>::Slice<'_>
slice::get_unchecked(range). Read moreSource§fn is_boundary(&self, index: usize) -> bool
fn is_boundary(&self, index: usize) -> bool
impl<R> TryCryptoRng for R
Source§impl<R> TryRngCore for R
impl<R> TryRngCore for R
Source§type Error = Infallible
type Error = Infallible
Source§fn try_next_u32(&mut self) -> Result<u32, <R as TryRngCore>::Error>
fn try_next_u32(&mut self) -> Result<u32, <R as TryRngCore>::Error>
u32.Source§fn try_next_u64(&mut self) -> Result<u64, <R as TryRngCore>::Error>
fn try_next_u64(&mut self) -> Result<u64, <R as TryRngCore>::Error>
u64.Source§fn try_fill_bytes(
&mut self,
dst: &mut [u8],
) -> Result<(), <R as TryRngCore>::Error>
fn try_fill_bytes( &mut self, dst: &mut [u8], ) -> Result<(), <R as TryRngCore>::Error>
dest entirely with random data.Source§fn unwrap_mut(&mut self) -> UnwrapMut<'_, Self>
fn unwrap_mut(&mut self) -> UnwrapMut<'_, Self>
UnwrapMut wrapper.