Skip to main content

TypeInternPool

Struct TypeInternPool 

pub struct TypeInternPool { /* private fields */ }
Expand description

Thread-safe intern pool for all composite types.

The pool is designed to be built during declaration gathering (sequential) and then queried during function body analysis (potentially parallel).

§Thread Safety

Uses RwLock for interior mutability:

  • Read lock for lookups (most common)
  • Write lock for insertions (only during declaration gathering)

§Usage

let pool = TypeInternPool::new();

// Register nominal types (structs/enums)
let (struct_type, is_new) = pool.register_struct(name_spur, struct_def);

// Intern structural types (arrays)
let array_type = pool.intern_array(element_type, 10);

// Look up type data
if let Some(data) = pool.try_get(some_type) {
    match data {
        TypeData::Struct(s) => println!("struct {}", s.def.name),
        TypeData::Enum(e) => println!("enum {}", e.def.name),
        TypeData::Array { element, len } => println!("array of {:?}; {}", element, len),
    }
}

Implementations§

§

impl TypeInternPool

pub fn clone_snapshot(&self) -> TypeInternPool

Clone the pool by snapshotting its canonical types and reconstructing the structural-dedup HashMaps. Used by ADR-0074 Phase 4’s AIR cache write to capture sema’s pool state without taking ownership of it. Behavior matches serde round-trip — both produce a pool whose intern_*(...) calls return the same InternedTypes as the original.

pub fn new() -> TypeInternPool

Create a new empty pool.

pub fn register_struct(&self, name: Spur, def: StructDef) -> (StructId, bool)

Register a new struct (nominal - no deduplication).

Returns the StructId (containing the pool index) and whether it was newly inserted. If a struct with this name already exists, returns the existing StructId.

pub fn reserve_struct_id(&self) -> StructId

Reserve a struct ID without registering the full definition yet.

This is used for anonymous structs where we need to know the ID before we can construct the name (which includes the ID). Call complete_struct_registration with the reserved ID to finish registration.

§Returns

Returns the reserved StructId. The caller MUST call complete_struct_registration with this ID before any other pool operations that might read this entry.

§Example
let struct_id = pool.reserve_struct_id();
let name = format!("__anon_struct_{}", struct_id.0);
let name_spur = interner.get_or_intern(&name);
let def = StructDef { name: name.clone(), ... };
pool.complete_struct_registration(struct_id, name_spur, def);

pub fn complete_struct_registration( &self, struct_id: StructId, name: Spur, def: StructDef, )

Complete the registration of a previously reserved struct ID.

This must be called after reserve_struct_id to fill in the actual struct data. The struct will be registered with the provided name for lookup purposes.

§Panics

Panics if:

  • The struct_id wasn’t created by reserve_struct_id
  • The slot at struct_id doesn’t contain a placeholder struct
  • A struct with the given name already exists

pub fn register_enum(&self, name: Spur, def: EnumDef) -> (EnumId, bool)

Register a new enum (nominal - no deduplication).

Returns the EnumId (containing the pool index) and whether it was newly inserted. If an enum with this name already exists, returns the existing EnumId.

pub fn intern_array(&self, element: InternedType, len: u64) -> InternedType

Intern an array type (structural - deduplicates).

Returns the canonical InternedType for arrays with this element type and length. If an identical array type already exists, returns the existing type.

pub fn intern_ptr_const(&self, pointee: InternedType) -> InternedType

Intern a ptr const type (structural - deduplicates).

Returns the canonical InternedType for pointers to this pointee type. If an identical pointer type already exists, returns the existing type.

pub fn intern_ptr_mut(&self, pointee: InternedType) -> InternedType

Intern a ptr mut type (structural - deduplicates).

Returns the canonical InternedType for mutable pointers to this pointee type. If an identical pointer type already exists, returns the existing type.

pub fn intern_ref(&self, referent: InternedType) -> InternedType

Intern a Ref(T) type (structural - deduplicates).

pub fn intern_mut_ref(&self, referent: InternedType) -> InternedType

Intern a MutRef(T) type (structural - deduplicates).

pub fn intern_slice(&self, element: InternedType) -> InternedType

Intern a Slice(T) type (structural - deduplicates).

pub fn intern_mut_slice(&self, element: InternedType) -> InternedType

Intern a MutSlice(T) type (structural - deduplicates).

pub fn intern_vec(&self, element: InternedType) -> InternedType

Intern a Vec(T) type (structural - deduplicates) (ADR-0066).

pub fn get_struct_by_name(&self, name: Spur) -> Option<InternedType>

Look up a struct by name.

pub fn get_enum_by_name(&self, name: Spur) -> Option<InternedType>

Look up an enum by name.

pub fn get_array(&self, element: InternedType, len: u64) -> Option<InternedType>

Look up an array type by element and length.

pub fn get(&self, ty: InternedType) -> Option<TypeData>

Get type data for a composite type.

Returns None for primitive types (use InternedType::is_primitive() first).

§Panics

Panics if the index is invalid.

pub fn is_struct(&self, ty: InternedType) -> bool

Check if this is a struct type.

pub fn is_enum(&self, ty: InternedType) -> bool

Check if this is an enum type.

pub fn is_array(&self, ty: InternedType) -> bool

Check if this is an array type.

pub fn get_struct_def(&self, ty: InternedType) -> Option<StructDef>

Get the struct definition if this is a struct type.

pub fn get_enum_def(&self, ty: InternedType) -> Option<EnumDef>

Get the enum definition if this is an enum type.

pub fn get_array_info(&self, ty: InternedType) -> Option<(InternedType, u64)>

Get array info (element type, length) if this is an array type.

pub fn struct_def(&self, struct_id: StructId) -> StructDef

Get a struct definition by StructId.

The StructId contains a pool index. This method looks up the struct in the pool and returns a clone of its definition.

§Panics

Panics if the StructId doesn’t correspond to a struct in the pool.

pub fn enum_def(&self, enum_id: EnumId) -> EnumDef

Get an enum definition by EnumId.

The EnumId contains a pool index. This method looks up the enum in the pool and returns a clone of its definition.

§Panics

Panics if the EnumId doesn’t correspond to an enum in the pool.

pub fn update_struct_def(&self, struct_id: StructId, new_def: StructDef)

Update a struct definition in the pool.

This is used during semantic analysis when struct fields are resolved after the struct is initially registered.

§Panics

Panics if the StructId doesn’t correspond to a struct in the pool.

pub fn update_enum_def(&self, enum_id: EnumId, new_def: EnumDef)

Update an enum definition in the pool.

This is used during semantic analysis when enum variants are resolved after the enum is initially registered.

§Panics

Panics if the EnumId doesn’t correspond to an enum in the pool.

pub fn struct_id_to_interned(&self, struct_id: StructId) -> InternedType

Convert a StructId to an InternedType.

Since StructId now contains a pool index, we just add the primitive offset.

pub fn enum_id_to_interned(&self, enum_id: EnumId) -> InternedType

Convert an EnumId to an InternedType.

Since EnumId now contains a pool index, we just add the primitive offset.

pub fn array_def(&self, array_id: ArrayTypeId) -> (Type, u64)

Get an array type definition by ArrayTypeId.

The ArrayTypeId contains a pool index. This method looks up the array in the pool and returns its element type and length as a tuple.

§Returns

Returns (element_type, length) where element_type is the array’s element type and length is the array’s fixed size.

§Panics

Panics if the ArrayTypeId doesn’t correspond to an array in the pool.

pub fn intern_array_from_type( &self, element_type: Type, len: u64, ) -> ArrayTypeId

Intern an array type from a Type element.

This is a helper method that converts the Type to InternedType and then interns the array.

§Panics

Panics if the element type contains a struct/enum that isn’t in the pool.

pub fn get_array_by_type( &self, element_type: Type, len: u64, ) -> Option<ArrayTypeId>

Look up an array type by Type element and length.

Returns None if no such array exists in the pool.

pub fn intern_ptr_const_from_type(&self, pointee_type: Type) -> PtrConstTypeId

Intern a ptr const type from a Type pointee.

§Panics

Panics if the pointee type contains a struct/enum that isn’t in the pool.

pub fn intern_ptr_mut_from_type(&self, pointee_type: Type) -> PtrMutTypeId

Intern a ptr mut type from a Type pointee.

§Panics

Panics if the pointee type contains a struct/enum that isn’t in the pool.

pub fn ptr_const_def(&self, ptr_id: PtrConstTypeId) -> Type

Get ptr const pointee type if this is a ptr const type.

pub fn ptr_mut_def(&self, ptr_id: PtrMutTypeId) -> Type

Get ptr mut pointee type if this is a ptr mut type.

pub fn intern_ref_from_type(&self, referent_type: Type) -> RefTypeId

Intern a Ref(T) type from a Type referent.

pub fn intern_mut_ref_from_type(&self, referent_type: Type) -> MutRefTypeId

Intern a MutRef(T) type from a Type referent.

pub fn ref_def(&self, ref_id: RefTypeId) -> Type

Get the referent type of a Ref(T).

pub fn mut_ref_def(&self, ref_id: MutRefTypeId) -> Type

Get the referent type of a MutRef(T).

pub fn intern_slice_from_type(&self, element_type: Type) -> SliceTypeId

Intern a Slice(T) type from a Type element.

pub fn intern_mut_slice_from_type(&self, element_type: Type) -> MutSliceTypeId

Intern a MutSlice(T) type from a Type element.

pub fn slice_def(&self, slice_id: SliceTypeId) -> Type

Get the element type of a Slice(T).

pub fn mut_slice_def(&self, slice_id: MutSliceTypeId) -> Type

Get the element type of a MutSlice(T).

pub fn intern_vec_from_type(&self, element_type: Type) -> VecTypeId

Intern a Vec(T) type from a Type element (ADR-0066).

pub fn vec_def(&self, vec_id: VecTypeId) -> Type

Get the element type of a Vec(T) (ADR-0066).

pub fn is_thread_safety_type(&self, ty: Type) -> ThreadSafety

ADR-0084: thread-safety classification for any type.

Returns one of Unsend < Send < Sync:

  • Built-in negative facts. Raw pointers (Ptr(T) / MutPtr(T)) are intrinsically Unsend regardless of T.
  • Built-in positive facts. Primitive integer / float / bool / char / unit / never types are intrinsically Sync.
  • Composites. Arrays, slices, vectors, references, and pointer-to-T chains take the classification of their element/referent. Struct / enum types read the thread_safety field on their definition (computed by validate_consistency as the structural minimum over members, then optionally overridden by a @mark(unsend) / @mark(checked_send) / @mark(checked_sync) directive).

Module / interface / comptime-only types fall through to Sync — they have no runtime presence so the classification doesn’t constrain anything.

pub fn is_type_linear(&self, ty: Type) -> bool

Check if a type is linear (must be explicitly consumed, can’t be implicitly dropped — ADR-0008).

Linearity propagates through compound types (ADR-0067):

  • Struct(S) is linear iff S was declared linear struct.
  • [T; N] is linear iff N > 0 and T is linear.
  • Vec(T) is linear iff T is linear.
  • Enum(E) is linear iff any variant payload is linear.
  • All other types are non-linear.

pub fn all_vec_ids(&self) -> Vec<VecTypeId>

Get all Vec(T) type IDs registered in the pool (ADR-0066).

pub fn array_id_to_interned(&self, array_id: ArrayTypeId) -> InternedType

Convert an ArrayTypeId to an InternedType.

Since ArrayTypeId now contains a pool index, we just add the primitive offset.

pub fn all_struct_ids(&self) -> Vec<StructId>

Get all struct IDs registered in the pool.

Returns a vector of all StructId values, useful for iterating over all structs (e.g., for drop glue synthesis).

pub fn all_enum_ids(&self) -> Vec<EnumId>

Get all enum IDs registered in the pool.

Returns a vector of all EnumId values, useful for iterating over all enums.

pub fn all_array_ids(&self) -> Vec<ArrayTypeId>

Get all array IDs registered in the pool.

Returns a vector of all ArrayTypeId values, useful for iterating over all arrays (e.g., for drop glue synthesis).

pub fn len(&self) -> usize

Get the number of composite types in the pool.

pub fn is_empty(&self) -> bool

Check if the pool is empty (no composite types).

pub fn stats(&self) -> TypeInternPoolStats

Get statistics about the pool contents.

pub fn type_to_interned(&self, ty: Type) -> Option<InternedType>

Convert an old-style Type to an InternedType.

This is a temporary helper for Phase 1 migration. It converts the existing Type enum to the new interned representation.

§Note

For struct/enum types, the corresponding type must already be registered in the pool. For array types, this returns an error since array interning requires the pool to already have the element type interned.

pub fn interned_to_type(&self, ty: InternedType) -> Option<Type>

Convert an InternedType back to the old-style Type.

This is a temporary helper for Phase 1 migration to verify correctness. Returns None for composite types since we need the old IDs.

pub fn abi_slot_count(&self, ty: Type) -> u32

Return the number of ABI slots that ty occupies when passed as a function argument.

  • Scalars (integers, bool, enum, pointer) → 1
  • Struct → sum of field slot counts (flattened)
  • Array → element slot count × length
  • Zero-sized types (unit, never, comptime-only, module) → 0

pub fn format_type_name(&self, ty: Type) -> String

Return the human-readable name of ty, suitable for error messages.

Examples: "i32", "bool", "MyStruct", "[i32; 4]", "Ptr(i32)". Pointer types are formatted in the ADR-0061 surface form (Ptr(T) / MutPtr(T)) regardless of which syntax the user wrote; the old ptr const T / ptr mut T form remains accepted by the parser during the migration but is not produced by diagnostics.

Trait Implementations§

§

impl Clone for TypeInternPool

§

fn clone(&self) -> TypeInternPool

Clone the pool by copying all type data into a new pool.

This is used when building SemaContext from Sema, as the context needs its own copy of the pool for thread-safe sharing.

1.0.0 · Source§

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

Performs copy-assignment from source. Read more
§

impl Debug for TypeInternPool

§

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

Formats the value using the given formatter. Read more
§

impl Default for TypeInternPool

§

fn default() -> TypeInternPool

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

impl<'de> Deserialize<'de> for TypeInternPool

§

fn deserialize<D>( de: D, ) -> Result<TypeInternPool, <D as Deserializer<'de>>::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
§

impl Serialize for TypeInternPool

§

fn serialize<S>( &self, ser: S, ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

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.

§

impl<T> Instrument for T

§

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

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

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
§

impl<'src, T> IntoMaybe<'src, T> for T
where T: 'src,

§

type Proj<U: 'src> = U

§

fn map_maybe<R>( self, _f: impl FnOnce(&'src T) -> &'src R, g: impl FnOnce(T) -> R, ) -> <T as IntoMaybe<'src, T>>::Proj<R>
where R: 'src,

§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

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

Initializes a with the given initializer. Read more
§

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

Dereferences the given pointer. Read more
§

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

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

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

impl<'p, T> Seq<'p, T> for T
where T: Clone,

§

type Item<'a> = &'a T where T: 'a

The item yielded by the iterator.
§

type Iter<'a> = Once<&'a T> where T: 'a

An iterator over the items within this container, by reference.
§

fn seq_iter(&self) -> <T as Seq<'p, T>>::Iter<'_>

Iterate over the elements of the container.
§

fn contains(&self, val: &T) -> bool
where T: PartialEq,

Check whether an item is contained within this sequence.
§

fn to_maybe_ref<'b>(item: <T as Seq<'p, T>>::Item<'b>) -> Maybe<T, &'p T>
where 'p: 'b,

Convert an item of the sequence into a [MaybeRef].
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.
§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

§

impl<T> OrderedSeq<'_, T> for T
where T: Clone,