starlark 0.14.0

An implementation of the Starlark language in Rust.
Documentation
/*
 * Copyright 2019 The Starlark in Rust Authors.
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/// Marker trait indicating a frozen type has been registered for vtable lookup.
///
/// This trait is automatically implemented by the registration macros:
/// - `register_avalue_simple_frozen!`
/// - `register_special_avalue_frozen!`
/// - Auto-registration from `#[starlark_value]` (which uses `register_avalue_simple_frozen!`)
///
/// # Safety
///
/// This trait must only be implemented via registration macros,
/// which ensure the type is properly registered in the vtable registry.
/// Manual implementations may break deserialization.
pub unsafe trait VtableRegistered {}

/// Register a frozen value type for deserialization. But without impl VtableRegistered.
#[doc(hidden)]
#[macro_export]
macro_rules! register_simple_vtable_entry {
    ($type:ty) => {
        #[allow(unexpected_cfgs)]
        const _: () = {
            #[cfg(feature = "pagable")]
            $crate::__derive_refs::inventory::submit! {
                $crate::__derive_refs::VTableRegistryEntry {
                    deser_type_id: $crate::__derive_refs::DeserTypeId::of::<$type>(),
                    vtable: $crate::__derive_refs::AValueVTable::new::<
                        $crate::__derive_refs::AValueSimple<$type>
                    >(),
                }
            }
        };
    };
}

/// Register a frozen value type for deserialization.
///
/// Invoke this macro once for each frozen `AValueSimple` Starlark value type
/// that needs to be deserializable. In most cases, the `#[starlark_value]` macro
/// handles registration automatically. Use this macro only when auto-registration
/// doesn't apply.
///
/// Without registration, attempting to deserialize a heap containing that type
/// will fail.
///
/// # Example
///
/// ```ignore
/// register_avalue_simple_frozen!(FrozenDict);
/// ```
#[macro_export]
macro_rules! register_avalue_simple_frozen {
    ($type:ty) => {
        $crate::register_simple_vtable_entry!($type);

        // SAFETY: This impl is generated by the registration macro which
        // ensures the vtable is properly registered above.
        unsafe impl $crate::__derive_refs::VtableRegistered for $type {}

        $crate::register_ty_starlark_value!($type);
    };
}

/// Macro to register a vtable for a special type with a custom AValue implementation.
///
/// This macro is for special types (like `StarlarkStr`, `FrozenTuple`, `ListGen<FrozenListData>`)
/// that use custom AValue implementations instead of `AValueSimple<T>`.
macro_rules! register_special_avalue_frozen {
    ($starlark_value:ty, $avalue:ty) => {
        #[allow(unexpected_cfgs)]
        const _: () = {
            #[cfg(feature = "pagable")]
            inventory::submit! {
                $crate::pagable::vtable_registry::VTableRegistryEntry {
                    deser_type_id: $crate::__derive_refs::DeserTypeId::of::<$starlark_value>(),
                    vtable: $crate::values::layout::vtable::AValueVTable::new::<$avalue>(),
                }
            }
        };
    };
}

pub(crate) use register_special_avalue_frozen;

/// Register a `TypeMatcher` for vtable lookup. Always emits the AValue
/// vtable for `TypeCompiledImplAsStarlarkValue<T>`; for generic wrappers,
/// additionally delegates to [`pagable::register_typetag!`] for the
/// per-instantiation typetag registration.
///
/// Forms:
/// - `register_type_matcher!(Matcher)` — non-generic (e.g. `IsStr`).
/// - `register_type_matcher!(Wrapper<A, B, ...>)` — generic, any arity.
#[macro_export]
macro_rules! register_type_matcher {
    ($wrapper:ident < $($arg:ty),+ $(,)? >) => {
        $crate::register_simple_vtable_entry!(
            $crate::values::typing::TypeCompiledImplAsStarlarkValue<$wrapper<$($arg),+>>
        );
        pagable::register_typetag!($wrapper<$($arg),+> as dyn $crate::__derive_refs::TypeMatcherDyn);
    };
    ($matcher:ty) => {
        // Note: We use register_simple_vtable_entry! instead of register_avalue_simple_frozen!
        // because TypeCompiledImplAsStarlarkValue<T> has a blanket impl of VtableRegistered
        // for T: TypeMatcherRegistered, which would conflict with the impl
        // generated by register_avalue_simple_frozen!.
        $crate::register_simple_vtable_entry!(
            $crate::values::typing::TypeCompiledImplAsStarlarkValue<
                $matcher,
            >
        );
    };
}