supply 0.1.0

Provider API for arbitrary number of lifetimes.
Documentation
//! Tests of the tag module's API.
//!
//! The tag module is all type level constructs so the tests in
//! this module may look very strange.

/*
use std::{
    cell::UnsafeCell,
    marker::{PhantomData, PhantomPinned},
    panic::{RefUnwindSafe, UnwindSafe},
};

use supply::{lt_list::LtTagOf, tag::*, Lt1, LtList};

#[allow(unused)]
struct NoAuto<'a>(
    PhantomData<(*const u8, PhantomPinned, &'a mut u8, UnsafeCell<u8>)>,
    str,
);

// Tagged
const _: () = {
    #[allow(unused)]
    struct Test<'a>(NoAuto<'a>);

    impl<'a> Tagged for Test<'a> {
        type Tag = Static<Test<'static>>;

        type LifetimesTag = LtTagOf<Lt1<'static>>;
    }

    fn with_t<T: ?Sized + Tagged>() {
        // Tag always implements Sized and 'static.
        fn assert_assoc<T: ?Sized + 'static>() {}
        assert_assoc::<T::Tag>();
    }
};

// TagOf
const _: () = {
    #[allow(unused)]
    struct Test<'a>(NoAuto<'a>);

    impl<'a> Tagged for Test<'a> {
        type Tag = Static<Test<'static>>;

        type LifetimesTag = LtTagOf<Lt1<'static>>;
    }

    fn with_t<T: ?Sized + Tagged>() {
        // Check that TagOf always gives the associated type.
        fn assert_ty<T: ?Sized + Tagged<Tag = U>, U: ?Sized>() {}
        assert_ty::<T, TagOf<T>>();
    }
};

// MaybeSizedTag
const _: () = {
    #[allow(unused)]
    struct Test(PhantomData<NoAuto<'static>>);

    impl<'a, L: LtList> MaybeSizedTag<Lt1<'a, L>> for Test {
        type Reified = NoAuto<'a>;
    }

    impl Tagged for Test {
        type Tag = Test;
    }

    // Check that the super traits are correct.
    trait AssertSuper<L>: 'static {}
    #[allow(clippy::needless_maybe_sized)]
    impl<L: LtList, T: ?Sized + MaybeSizedTag<L>> AssertSuper<L> for T {}

    // Check that Reified is ?Sized.
    fn with_t<T: MaybeSizedTag<L>, L: LtList>() {
        {
            trait AmbiguousIfImpl<A> {
                fn some_item() {}
            }

            impl<T: ?Sized> AmbiguousIfImpl<()> for T {}

            {
                struct Invalid;
                impl<T: Sized> AmbiguousIfImpl<Invalid> for T {}
            }

            let _ = <T::Reified as AmbiguousIfImpl<_>>::some_item;
        }
    }
};

// Tag
const _: () = {
    #[allow(unused)]
    struct Test(PhantomData<NoAuto<'static>>);

    impl<'a, L: LtList> MaybeSizedTag<Lt1<'a, L>> for Test {
        type Reified = PhantomData<NoAuto<'a>>;
    }

    impl Tagged for Test {
        type Tag = Test;
    }

    // Check that implementing MaybeSizedTag automatically gives Tag.
    fn with_l<L: LtList>() {
        fn assert_tag<'a, T: Tag<Lt1<'a, L>>, L: LtList>() {}
        assert_tag::<Test, L>()
    }

    // Check that SizedReified and Reified are Sized.
    fn with_t<T: Tag<L>, L: LtList>() {
        fn assert_sized<T: Tag<L> + MaybeSizedTag<L, Reified = T::SizedReified>, L: LtList>()
        where
            T::Reified: Sized,
            T::SizedReified: Sized,
        {
        }
        assert_sized::<T, L>();
    }
};

// Static<T>
const _: () = {
    fn _with_t<T: ?Sized>() {
        // Static always implements all the auto traits.
        fn assert_auto<T: Send + Sync + Unpin + RefUnwindSafe + UnwindSafe + Sized>() {}
        assert_auto::<Static<T>>();
    }

    fn _with_static_t<T: ?Sized + 'static, L: LtList>() {
        // Static's tag is always itself.
        fn assert_tagged<T: Tagged<Tag = T>>() {}
        assert_tagged::<Static<T>>();

        // Static's reified type is always it's generic.
        fn assert_tag<T, L: LtList, U: ?Sized>()
        where
            T: MaybeSizedTag<L, Reified = U>,
        {
        }
        assert_tag::<Static<T>, L, T>();
    }
};

// AddLt<T>
const _: () = {
    fn _with_t<T: ?Sized>() {
        // AddLt always implements all the auto traits.
        fn assert_auto<T: Send + Sync + Unpin + RefUnwindSafe + UnwindSafe + Sized>() {}
        assert_auto::<AddLt<T>>();
    }

    fn _with_tagged_t<T: ?Sized + Tagged>() {
        // AddLt's tag is itself with the generic swapped for the tagged one.
        fn assert_tagged<T: Tagged<Tag = U>, U>() {}
        assert_tagged::<AddLt<T>, AddLt<T::Tag>>();
    }

    #[allow(clippy::extra_unused_lifetimes)]
    fn _with_tag<'a, T: MaybeSizedTag<L>, L: LtList>() {
        // AddLt's reified type is always the same as it's generic's.
        // It also adds a lifetime to L.
        fn assert_tag<T, L: LtList, U: ?Sized>()
        where
            T: MaybeSizedTag<L, Reified = U>,
        {
        }
        assert_tag::<AddLt<T>, Lt1<'a, L>, T::Reified>();
    }
};

// Ref<T>
const _: () = {
    fn _with_t<T: ?Sized>() {
        // Ref always implements all the auto traits.
        fn assert_auto<T: Send + Sync + Unpin + RefUnwindSafe + UnwindSafe + Sized>() {}
        assert_auto::<Ref<T>>();
    }

    fn _with_tagged_t<T: ?Sized + Tagged>() {
        // Ref's tag is itself with the generic swapped for the tagged one.
        fn assert_tagged<T: Tagged<Tag = U>, U>() {}
        assert_tagged::<Ref<T>, Ref<T::Tag>>();
    }

    fn _with_tag<'a, T: MaybeSizedTag<L>, L: LtList<Head = Lt1<'a>>>()
    where
        T::Reified: 'a,
    {
        // Refs's reified type is always a borrow with the first lifetime.
        fn assert_tag<'a, T, L: LtList<Head = Lt1<'a>>, U: ?Sized + 'a>()
        where
            T: MaybeSizedTag<L, Reified = &'a U>,
        {
        }
        assert_tag::<Ref<T>, L, T::Reified>();
    }
};

// StaticRef<T>
const _: () = {
    fn _with_t<T: ?Sized>() {
        // StaticRef always implements all the auto traits.
        fn assert_auto<T: Send + Sync + Unpin + RefUnwindSafe + UnwindSafe + Sized>() {}
        assert_auto::<StaticRef<T>>();
    }

    fn _with_tagged_t<T: ?Sized + Tagged>() {
        // StaticRef's tag is itself with the generic swapped for the tagged one.
        fn assert_tagged<T: Tagged<Tag = U>, U>() {}
        assert_tagged::<StaticRef<T>, StaticRef<T::Tag>>();
    }

    fn _with_tag<T: MaybeSizedTag<L>, L: LtList>()
    where
        T::Reified: 'static,
    {
        // StaticRef's reified type is always a borrow with the static lifetime.
        fn assert_tag<T, L: LtList, U: ?Sized + 'static>()
        where
            T: MaybeSizedTag<L, Reified = &'static U>,
        {
        }
        assert_tag::<StaticRef<T>, L, T::Reified>();
    }
};

// Mut<T>
const _: () = {
    fn _with_t<T: ?Sized>() {
        // Mut always implements all the auto traits.
        fn assert_auto<T: Send + Sync + Unpin + RefUnwindSafe + UnwindSafe + Sized>() {}
        assert_auto::<Mut<T>>();
    }

    fn _with_tagged_t<T: ?Sized + Tagged>() {
        // Mut's tag is itself with the generic swapped for the tagged one.
        fn assert_tagged<T: Tagged<Tag = U>, U>() {}
        assert_tagged::<Mut<T>, Mut<T::Tag>>();
    }

    fn _with_tag<'a, T: MaybeSizedTag<L>, L: LtList<Head = Lt1<'a>>>()
    where
        T::Reified: 'a,
    {
        // Mut's reified type is always a borrow with the first lifetime.
        fn assert_tag<'a, T, L: LtList<Head = Lt1<'a>>, U: ?Sized + 'a>()
        where
            T: MaybeSizedTag<L, Reified = &'a mut U>,
        {
        }
        assert_tag::<Mut<T>, L, T::Reified>();
    }
};

// Check that NoAuto doesn't implement any of the auto traits.
const _: () = {
    trait AmbiguousIfImpl<A> {
        fn some_item() {}
    }

    impl<T: ?Sized> AmbiguousIfImpl<()> for T {}

    {
        struct Invalid;
        impl<T: ?Sized + RefUnwindSafe> AmbiguousIfImpl<Invalid> for T {}
    }

    {
        struct Invalid;
        impl<T: ?Sized + Send> AmbiguousIfImpl<Invalid> for T {}
    }

    {
        struct Invalid;
        impl<T: ?Sized + Sync> AmbiguousIfImpl<Invalid> for T {}
    }

    {
        struct Invalid;
        impl<T: ?Sized + Unpin> AmbiguousIfImpl<Invalid> for T {}
    }

    {
        struct Invalid;
        impl<T: ?Sized + UnwindSafe> AmbiguousIfImpl<Invalid> for T {}
    }

    {
        struct Invalid;
        impl<T: Sized> AmbiguousIfImpl<Invalid> for T {}
    }

    let _ = <NoAuto as AmbiguousIfImpl<_>>::some_item;
};
*/