Skip to main content

Span

Struct Span 

Source
#[repr(packed(4))]
pub struct Span(u64);
Expand description

A compressed span.

SpanData is 16 bytes, which is too big to stick everywhere. Span is only 8 bytes. A large majority of SpanData instances can be made to fit within those 8 bytes. Any SpanData whose fields don’t fit into a Span are stored in a separate interner table, and the Span will index into that table.

An earlier version of this code used only 4 bytes for Span, but that was slower because many fewer spans could be stored inline and the interner was used a lot more. That version of the code also predated the storage of parents.

Experiments with uncompressed spans yielded worse performance in most cases because memory usage and cache miss rates are significantly higher without compression.

There are four different span formats and each packs data into the 8 bytes in a different way. A variable-length prefix in the high bits identifies which format is being used. It is an invariant that we always use the first listed format whose requirements are satisfied. len is hi - lo.

  • Inline-context format (requires 15-bit length, 16-bit context, and no parent):

    [ prefix=0 | len:15 | ctxt:16 | lo:32 ]

  • Inline-parent format (requires 14-bit length, root context, and 15-bit parent):

    [ prefix=110 | len:14 | parent:15 | lo:32 ]

  • Inline-pair format (requires 24-bit lo, 7-bit length, 15-bit context, 16-bit parent):

    [ prefix=10 | len:7 | ctxt:15 | parent:16 | lo:24 ]

  • Interned format (all cases not covered above):

    [ prefix=111 | ctxt:29 | index:32 ]

Notes about this design.

  • This configuration was the best one found after many measurements of real-world crates, and replaced an earlier 8-byte design.

  • The size of lo depends on the size of the crate and its dependencies. Crates whose lo size exceeds 24-bits are extremely rare.

  • The most common numbers of bits needed for len are from 0 to 7, with a peak usually at 3 or 4, and then it drops off quickly from 8 onwards. Lengths larger than 14 bits are rare, but many crates will have a small number of such lengths (sometimes 20+ bits).

  • The number of bits needed for ctxt and parent values depend partly on the crate size and partly on the form of the code. For both fields, values needing more than 15 bits are very rare, and most crates won’t hit these limits.

  • The ctxt is stored inline in every format (Every ctxt must fit in 29 bits; if we ever hit that we’d have many gigabytes of contexts, and certainly would have OOM’d anyway.) This means reading the ctxt never requires checking the interner. This is good because the ctxt is often consulted by itself. It also means we don’t need to store the ctxt in the interner table, which we achieve by using SpanDataNoCtxt, which minimizes the number of unique values that need to be interned.

  • The use of repr(packed(4)) means Span has an alignment of 4 bytes, which keeps many types that contain spans (e.g. AST nodes) smaller. repr(packed(1)) isn’t worth it; it only shrinks a few types and performance is a tiny bit worse.

In order to reliably use parented spans in incremental compilation, accesses to lo and hi must introduce a dependency to the parent definition’s span. This is performed using the callback SPAN_TRACK to access the query engine.

Tuple Fields§

§0: u64

Implementations§

Source§

impl Span

Source

pub fn mark_with_reason( self, allow_internal_unstable: Option<Arc<[Symbol]>>, reason: DesugaringKind, edition: Edition, hcx: impl StableHashCtxt, ) -> Span

Reuses the span but adds information like the kind of the desugaring and features that are allowed inside this span.

Source§

impl Span

Source

pub fn new( lo: BytePos, hi: BytePos, ctxt: SyntaxContext, parent: Option<LocalDefId>, ) -> Self

Source

fn try_new_span_with_parent( lo: u32, len: u32, ctxt: u32, parent: LocalDefId, ) -> Option<Self>

Tries to create an InlineParent or InlinePair format span. Returns None if the fields won’t fit.

Source

pub fn data(self) -> SpanData

Source

pub fn data_untracked(self) -> SpanData

Internal function to translate between an encoded span and the expanded representation. This function must not be used outside the incremental engine.

Source

pub fn from_expansion(self) -> bool

Returns true if this span comes from any kind of macro, desugaring or inlining.

Source

pub fn is_dummy(self) -> bool

Returns true if this is a dummy span with lo=0, hi=0. Any context value is allowed, which means it’s not the same as an equality comparison with DUMMY_SP.

Source

pub fn map_ctxt(self, map: impl FnOnce(SyntaxContext) -> SyntaxContext) -> Span

Source

pub fn ctxt(self) -> SyntaxContext

This function is used as a fast path when decoding the full SpanData is not necessary. It’s a cut-down version of data_untracked and doesn’t require taking the interner lock.

Source

pub fn eq_ctxt(self, other: Span) -> bool

Source

pub fn with_parent(self, parent: Option<LocalDefId>) -> Span

Source

pub fn parent(self) -> Option<LocalDefId>

Source

pub(crate) fn to_raw_span(self) -> RawSpan

Source

pub fn from_raw_span(RawSpan: RawSpan) -> Span

Source§

impl Span

Source

pub fn lo(self) -> BytePos

Source

pub fn with_lo(self, lo: BytePos) -> Span

Source

pub fn hi(self) -> BytePos

Source

pub fn with_hi(self, hi: BytePos) -> Span

Source

pub fn with_ctxt(self, ctxt: SyntaxContext) -> Span

Source

pub fn lo_hi(self) -> (BytePos, BytePos)

When to use this:

  • Use it instead of == for span equality comparisons when either span could be generated code and you only care that they point to the same bytes of source text.
  • Use it (possibly via OrdSpan) for span ordering comparisons of any kind.
Source

pub fn is_visible(self, sm: &SourceMap) -> bool

Source

pub fn in_external_macro(self, sm: &SourceMap) -> bool

Returns whether this span originates in a foreign crate’s external macro.

This is used to test whether a lint should not even begin to figure out whether it should be reported on the current node.

Source

pub fn in_derive_expansion(self) -> bool

Returns true if span originates in a derive-macro’s expansion.

Source

pub fn is_from_async_await(self) -> bool

Return whether span is generated by async or await.

Source

pub fn can_be_used_for_suggestions(self) -> bool

Gate suggestions that would not be appropriate in a context the user didn’t write.

Source

pub fn with_root_ctxt(lo: BytePos, hi: BytePos) -> Span

Source

pub fn shrink_to_lo(self) -> Span

Returns a new span representing an empty span at the beginning of this span.

Source

pub fn shrink_to_hi(self) -> Span

Returns a new span representing an empty span at the end of this span.

Source

pub fn is_empty(self) -> bool

Returns true if hi == lo.

Source

pub fn substitute_dummy(self, other: Span) -> Span

Returns self if self is not the dummy span, and other otherwise.

Source

pub fn contains(self, other: Span) -> bool

Returns true if self fully encloses other.

Source

pub fn overlaps(self, other: Span) -> bool

Returns true if self touches other.

Source

pub fn overlaps_or_adjacent(self, other: Span) -> bool

Returns true if self touches or adjoins other.

Source

pub fn trim_start(self, other: Span) -> Option<Span>

Returns Some(span), where the start is trimmed by the end of other.

Source

pub fn trim_end(self, other: Span) -> Option<Span>

Returns Some(span), where the end is trimmed by the start of other.

Source

pub fn source_callsite(self) -> Span

Returns the source span – this is either the supplied span, or the span for the macro callsite that expanded to it.

Source

pub fn parent_callsite(self) -> Option<Span>

Returns the call-site span of the last macro expansion which produced this Span. (see ExpnData::call_site). Returns None if this is not an expansion.

Source

pub fn find_ancestor_inside(self, outer: Span) -> Option<Span>

Find the first ancestor span that’s contained within outer.

This method traverses the macro expansion ancestors until it finds the first span that’s contained within outer.

The span returned by this method may have a different SyntaxContext than outer. If you need to extend the span, use find_ancestor_inside_same_ctxt instead, because joining spans with different syntax contexts can create unexpected results.

This is used to find the span of the macro call when a parent expr span, i.e. outer, is known.

Source

pub fn find_ancestor_in_same_ctxt(self, other: Span) -> Option<Span>

Find the first ancestor span with the same SyntaxContext as other.

This method traverses the macro expansion ancestors until it finds a span that has the same SyntaxContext as other.

Like find_ancestor_inside_same_ctxt, but specifically for when spans might not overlap. Take care when using this, and prefer find_ancestor_inside or find_ancestor_inside_same_ctxt when you know that the spans are nested (modulo macro expansion).

Source

pub fn find_ancestor_inside_same_ctxt(self, outer: Span) -> Option<Span>

Find the first ancestor span that’s contained within outer and has the same SyntaxContext as outer.

This method traverses the macro expansion ancestors until it finds a span that is both contained within outer and has the same SyntaxContext as outer.

This method is the combination of find_ancestor_inside and find_ancestor_in_same_ctxt and should be preferred when extending the returned span. If you do not need to modify the span, use find_ancestor_inside instead.

Source

pub fn find_ancestor_not_from_extern_macro(self, sm: &SourceMap) -> Option<Span>

Find the first ancestor span that does not come from an external macro.

This method traverses the macro expansion ancestors until it finds a span that is either from user-written code or from a local macro (defined in the current crate).

External macros are those defined in dependencies or the standard library. This method is useful for reporting errors in user-controllable code and avoiding diagnostics inside external macros.

§See also
Source

pub fn find_ancestor_not_from_macro(self) -> Option<Span>

Find the first ancestor span that does not come from any macro expansion.

This method traverses the macro expansion ancestors until it finds a span that originates from user-written code rather than any macro-generated code.

This method is useful for reporting errors at the exact location users wrote code and providing suggestions at directly editable locations.

§See also
Source

pub fn edition(self) -> Edition

Edition of the crate from which this span came.

Source

pub fn is_rust_2015(self) -> bool

Is this edition 2015?

Source

pub fn at_least_rust_2018(self) -> bool

Are we allowed to use features from the Rust 2018 edition?

Source

pub fn at_least_rust_2021(self) -> bool

Are we allowed to use features from the Rust 2021 edition?

Source

pub fn at_least_rust_2024(self) -> bool

Are we allowed to use features from the Rust 2024 edition?

Source

pub fn source_callee(self) -> Option<ExpnData>

Returns the source callee.

Returns None if the supplied span has no expansion trace, else returns the ExpnData for the macro definition corresponding to the source callsite.

Source

pub fn allows_unstable(self, feature: Symbol) -> bool

Checks if a span is “internal” to a macro in which #[unstable] items can be used (that is, a macro marked with #[allow_internal_unstable]).

Source

pub fn is_desugaring(self, kind: DesugaringKind) -> bool

Checks if this span arises from a compiler desugaring of kind kind.

Source

pub fn desugaring_kind(self) -> Option<DesugaringKind>

Returns the compiler desugaring that created this span, or None if this span is not from a desugaring.

Source

pub fn allows_unsafe(self) -> bool

Checks if a span is “internal” to a macro in which unsafe can be used without triggering the unsafe_code lint. (that is, a macro marked with #[allow_internal_unsafe]).

Source

pub fn macro_backtrace(self) -> impl Iterator<Item = ExpnData>

Source

pub fn split_at(self, pos: u32) -> (Span, Span)

Splits a span into two composite spans around a certain position.

Source

pub(crate) fn try_metavars( a: SpanData, b: SpanData, a_orig: Span, b_orig: Span, ) -> (SpanData, SpanData)

Check if you can select metavar spans for the given spans to get matching contexts.

Source

pub(crate) fn prepare_to_combine( a_orig: Span, b_orig: Span, ) -> Result<(SpanData, SpanData, Option<LocalDefId>), Span>

Prepare two spans to a combine operation like to or between.

Source

pub fn with_neighbor(self, neighbor: Span) -> Span

This span, but in a larger context, may switch to the metavariable span if suitable.

Source

pub fn to(self, end: Span) -> Span

Returns a Span that would enclose both self and end.

Note that this can also be used to extend the span “backwards”: start.to(end) and end.to(start) return the same Span.

    ____             ___
    self lorem ipsum end
    ^^^^^^^^^^^^^^^^^^^^
Source

pub fn between(self, end: Span) -> Span

Returns a Span between the end of self to the beginning of end.

    ____             ___
    self lorem ipsum end
        ^^^^^^^^^^^^^
Source

pub fn until(self, end: Span) -> Span

Returns a Span from the beginning of self until the beginning of end.

    ____             ___
    self lorem ipsum end
    ^^^^^^^^^^^^^^^^^
Source

pub fn within_macro(self, within: Span, sm: &SourceMap) -> Option<Span>

Returns the Span within the syntax context of “within”. This is useful when “self” is an expansion from a macro variable, since this can be used for providing extra macro expansion context for certain errors.

macro_rules! m {
    ($ident:ident) => { ($ident,) }
}

m!(outer_ident);

If “self” is the span of the outer_ident, and “within” is the span of the ($ident,) expr, then this will return the span of the $ident macro variable.

Source

pub fn from_inner(self, inner: InnerSpan) -> Span

Source

pub fn with_def_site_ctxt(self, expn_id: ExpnId) -> Span

Equivalent of Span::def_site from the proc macro API, except that the location is taken from the self span.

Source

pub fn with_call_site_ctxt(self, expn_id: ExpnId) -> Span

Equivalent of Span::call_site from the proc macro API, except that the location is taken from the self span.

Source

pub fn with_mixed_site_ctxt(self, expn_id: ExpnId) -> Span

Equivalent of Span::mixed_site from the proc macro API, except that the location is taken from the self span.

Source

pub(crate) fn with_ctxt_from_mark( self, expn_id: ExpnId, transparency: Transparency, ) -> Span

Produces a span with the same location as self and context produced by a macro with the given ID and transparency, assuming that macro was defined directly and not produced by some other macro (which is the case for built-in and procedural macros).

Source

pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span

Source

pub fn remove_mark(&mut self) -> ExpnId

Source

pub fn adjust(&mut self, expn_id: ExpnId) -> Option<ExpnId>

Source

pub fn normalize_to_macros_2_0_and_adjust( &mut self, expn_id: ExpnId, ) -> Option<ExpnId>

Source

pub fn normalize_to_macros_2_0(self) -> Span

Source

pub fn normalize_to_macro_rules(self) -> Span

Trait Implementations§

Source§

impl !Ord for Span

Source§

impl !PartialOrd for Span

Source§

impl Clone for Span

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for Span

Source§

impl Debug for Span

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<D: SpanDecoder> Decodable<D> for Span

Source§

impl Default for Span

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<E: SpanEncoder> Encodable<E> for Span

Source§

fn encode(&self, s: &mut E)

Source§

impl Eq for Span

Source§

impl Hash for Span

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for Span

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StableHash for Span

Source§

fn stable_hash<Hcx: StableHashCtxt>( &self, hcx: &mut Hcx, hasher: &mut StableHasher, )

Source§

impl StructuralPartialEq for Span

Auto Trait Implementations§

§

impl DynSend for Span

§

impl DynSync for Span

§

impl Freeze for Span

§

impl RefUnwindSafe for Span

§

impl Send for Span

§

impl Sync for Span

§

impl Unpin for Span

§

impl UnsafeUnpin for Span

§

impl UnwindSafe for Span

Blanket Implementations§

§

impl<T> Aligned for T

§

const ALIGN: Alignment

Alignment of Self.
Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 8 bytes