logo

Attribute Macro nougat::gat

source · []
#[gat]
Expand description

Entrypoint of the crate. Enables (lifetime) GATs on the annotated trait or impl block.

Example(s)

  • #[macro_use]
    extern crate nougat;
    
    #[gat]
    trait LendingIterator {
        type Item<'next>
        where
            Self : 'next,
        ;
    
        fn next(&mut self) -> Option<Self::Item<'_>>;
    }
    
    struct WindowsMut<Slice, const SIZE: usize> {
        slice: Slice,
        start: usize,
    }
    
    #[gat]
    impl<Item, const SIZE: usize> LendingIterator for WindowsMut<&mut [Item], SIZE> {
        type Item<'next>
        where
            Self : 'next,
        =
            &'next mut [Item; SIZE]
        ;
    
        fn next(&mut self) -> Option<&mut [Item; SIZE]> {
            let to_yield =
                self.slice
                    .get_mut(self.start ..)?
                    .get_mut(.. SIZE)?
                    .try_into()
                    .expect("slice has the right SIZE")
            ;
            self.start += 1;
            Some(to_yield)
        }
    }

Remarks

  • There is no need to use Gat! when inside a #[gat]-annotated item (since #[gat] will take care of automagically resolving the <Type as Trait>::Assoc<…> paths, as well as the Self::Assoc<…> ones), except when inside a macro! { … } invocation.

  • Only lifetime GATs are supported, so no type-GATs:

    //! No HKTs or type families yet 😔
    #[macro_use]
    extern crate nougat;
    
    #[gat]
    trait Collection {
        type Of<T>;
    }
    
    enum Vec_ {}
    
    #[gat]
    impl Collection for Vec_ {
        type Of<T> = Vec<T>;
    }
  • ⚠️ When use or pub useing a #[gat]-annotated trait, make sure to annotate such use “statement” with #[gat(AssocItem)].

    ⚠️ Otherwise it won’t be possible to implement that trait through the new path ⚠️

    For instance:

    extern crate nougat as nou;
    
    mod example {
        #[nou::gat]
        pub trait LendingIterator {
            type Item<'next>;
            // …
        }
    }
    
    // ⚠️ DO NOT FORGET TO ADD THIS ⚠️
    #[nou::gat(Item)] // 👈
    pub use example::LendingIterator;