Skip to main content

Origin

Struct Origin 

Source
pub struct Origin<S> {
    pub location: Rc<SourceLocation>,
    /* private fields */
}
Expand description

The syntax a node was built from, plus where that syntax came from.

§Why the two travel together

syn tokens normally carry spans, so in principle the syntax alone could answer “where was this written”. Not here: the proc-macro serializes each marked item as a string into JSONL, and build.rs re-parses it, so every span in spell() points into an anonymous buffer. [SourceLocation::from_span] captures file, line and column at macro-expansion time — while real rustc spans still exist — precisely because they cannot survive that trip.

§Why the location is shared

One captured record is one item, so there is exactly one location per item and none of its own for any component. An item and everything inside it — parameters, fields, variants, types, extents — therefore point at the same [SourceLocation], which is both the honest answer and the cheap one: a struct with twenty fields keeps one location, not twenty copies of a path.

Rc rather than Arc: this holds syn values, which are !Send, so the model can never cross a thread boundary and an atomic refcount would only cost. TypeKey made the same call for the same reason.

§The rule about origins

A reference carries a name; the declaration carries the origin.

location.crate_name here is the crate whose source this node was written in — the use site. It is never part of a referenced item’s identity: TypeId is a name alone, because #[prebindgen] names live in one flat namespace. ConstId is not an exception — the crate it records is the const’s declaring crate, obtained by lookup, and that is exactly what lets an array extent refuse a const from another source.

§The syntax is sealed

You may output the source. You may not read it.

spell hands out tokens and nothing else, which is all generated Rust ever needed. The node is reachable only through one crate-internal accessor, and the field itself is pub(super) — so the model still reads it freely, while everything outside is limited to the spelling.

It was a public field returning a syn node to anyone who asked. Outside this crate, captured syntax is reachable only through Emit, and the compiler enforces it.

Fields§

§location: Rc<SourceLocation>

The captured item this node belongs to, shared with every sibling.

Implementations§

Source§

impl<S> Origin<S>

Source

pub fn new(syntax: S, location: Rc<SourceLocation>) -> Origin<S>

Source

pub fn crate_name(&self) -> Option<&str>

The crate this node’s source was written in.

The use site, not the declaring crate of anything it names.

Source

pub fn with<T>(&self, syntax: T) -> Origin<T>

The same location over different syntax — for building a component’s origin from the item’s.

Source§

impl Origin<Type>

Source

pub fn key(&self) -> TypeKey

This type’s identity as a table key — the same answer TypeRef::key gives for a reading.

Here because a declaration is an Origin<syn::Type>: the type a build script wrote, carried with a placeless location. Asking it for its identity is not reaching for the node, and it should not have to be spelled as one — every TypeKey::from_type(decl.as_syn()) was a keying operation wearing an escape’s clothes.

Source§

impl<S> Origin<S>
where S: ToTokens,

Source

pub fn spell(&self) -> TokenStream

The node’s tokens, for generated Rust to spell.

The only output route, and deliberately not ToTokens. Implementing that trait would make quote!(#node) work — and hand every consumer to_token_stream().to_string() with it, which is a classifier’s input in a spelling’s clothing. A TokenStream interpolates just as well one let earlier, and the string, if a site really wants one, is now a two-call pattern that says so.

It does not make a token string impossiblespell().to_string() reaches one, and the ledger still lists that as open. What it makes is visible: .to_token_stream().to_string() was indistinguishable from the same call on a type an adapter built itself.

pub, not pub(crate): the registry pipeline’s own tests (now in the separate prebindgen-registry crate) call this on a captured element’s origin — see TypeRef’s doc for why this seal is now a convention rather than a compiler check.

Source§

impl Origin<Type>

Source

pub fn declared_spelling(&self) -> TokenStream

A declared type’s tokens.

Public where Origin::spell is sealed, and the difference is what S is. An Origin<syn::ItemFn>’s tokens re-parse to the captured item, so handing them out is the item door under another name — that one is Emit’s to open. An Origin<syn::Type> in an adapter’s declaration holds a type the build script wrote, which was never captured syntax and which #280 leaves the model no way to have a reading for.

Still a token route, and still one C3 has to account for when TypeRef::spell moves onto Emit: a declaration is an identity (key()), and the two sites that spell one do it to splice #target into generated Rust.

Trait Implementations§

Source§

impl<S> Clone for Origin<S>
where S: Clone,

Source§

fn clone(&self) -> Origin<S>

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<S> Debug for Origin<S>
where S: Debug,

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<S> !Send for Origin<S>

§

impl<S> !Sync for Origin<S>

§

impl<S> Freeze for Origin<S>
where S: Freeze,

§

impl<S> RefUnwindSafe for Origin<S>
where S: RefUnwindSafe,

§

impl<S> Unpin for Origin<S>
where S: Unpin,

§

impl<S> UnsafeUnpin for Origin<S>
where S: UnsafeUnpin,

§

impl<S> UnwindSafe for Origin<S>
where S: UnwindSafe,

Blanket Implementations§

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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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> 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 = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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.