logo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
//! [`Gat!`]: Gat
//! [#\[gat\]]: gat
#![cfg_attr(feature = "docs",
    cfg_attr(all(), doc = include_str!("../README.md")),
)]
#![doc(html_logo_url = "https://user-images.githubusercontent.com/9920355/170709986-aaa13f92-0faf-4b5d-89c9-6463b6b3d49b.png")]
#![deny(rustdoc::private_intra_doc_links)]

#![no_std]
#![forbid(unsafe_code)]

/// Entrypoint of the crate. **Enables (lifetime) GATs on the annotated `trait`
/// or `impl` block.**
///
/// ## Example(s)
///
/** -  ```rust
    # use ::core::convert::TryInto;
    # fn main() {}
    #[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:
///
/**     ```rust, compile_fail
     //! No HKTs or type families yet 😔
     # fn main() {}
     #[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 use`ing 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:
/**    ```rust
    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;
    ``` */
pub use ::nougat_proc_macros::gat;

/// Refer to a `<Type as Trait>::Assoc<…>` type.
/// Or express `Trait<Assoc<…> = …>` constraints.
///
/// Indeed, the GATs defined by <code>[#\[gat\]]</code>, when outside of a
/// <code>[#\[gat\]]</code>-annotated item (or a
/// <code>#\[[apply]\(Gat!\)\]</code>-annotated one), cannot be accessed through
/// the expected `<Type as Trait>::Assoc<…>` path directly.
///
/// [#\[gat\]]: gat
///
/// In order to work around that limitation, wrapping such paths inside
/// invocations to this very [`Gat!`] macro will avoid the issue:
///
/// ## Examples
///
/** ```rust
 # fn main() {}
 #[macro_use]
 extern crate nougat;

 #[gat]
 trait LendingIterator {
     type Item<'next>
     where
         Self : 'next,
     ;

     fn next(&mut self)
       -> Option<Self::Item<'_>>
     ;
 }

 fn first_item<I : LendingIterator> (
     iter: &'_ mut I,
 ) -> Option< Gat!(<I as LendingIterator>::Item<'_>) >
 {
     iter.next()
 }
``` */
///
/// But if you need to annotate a bunch of types like that within the same item
/// (_e.g._, function, (inline) module), you can, instead, directly
/// <code>#\[[apply]\([Gat!]\)\]</code> to that item to automagically get
/// `Gat!` applied to each and every such type occurrence:
///
/** ```rust
 # fn main() {}
 #[macro_use]
 extern crate nougat;

 #[gat]
 trait LendingIterator {
     type Item<'next>
     where
         Self : 'next,
     ;

     fn next(&mut self)
       -> Option<Self::Item<'_>>
     ;
 }

 #[apply(Gat!)]
 fn first_item<I : LendingIterator> (
     iter: &'_ mut I,
 ) -> Option< <I as LendingIterator>::Item<'_> >
 {
     iter.next()
 }
``` */
///
/// #### Tip: use type aliases!
///
/// Granted, the usage of [`Gat!`] may make some signature more heavyweight,
/// but the truth is that `<Type as Trait>::Assoc<…>`, _even without a `Gat!`
/// macro around it_, is already quite a mouthful.
///
/// And as with any "mouthful type", the trick is to factor out common patterns
/// with a (generic) type alias.
///
/// So it is heavily advisable that GAT-using library authors quickly get in the
/// habit of defining and using them:
///
/// ```rust
/// # #[cfg(any())] macro_rules! {
/// type Item<'lt, I /* : LendingIterator */> = Gat!(<I as LendingIterator>::Item<'lt>);
/// # }
/// ```
///
/**  - ```rust
    # fn main() {}
    #[macro_use]
    extern crate nougat;

    #[gat]
    trait LendingIterator {
        type Item<'next>
        where
            Self : 'next,
        ;

        fn next(&mut self) -> Option<Self::Item<'_>>;
    }

    type Item<'lt, I> = Gat!(<I as LendingIterator>::Item<'lt>);

    // Look ma, no macros!
    fn first_item<I: LendingIterator>(iter: &mut I) -> Option<Item<'_, I>> {
        iter.next()
    }
    ``` */
///
/// ## Remarks
///
/// Neither `Trait::Assoc<…>` nor `Type::Assoc<…>` paths will work, even when
/// the compiler would have enough information to figure out that we are talking
/// of `<Type as Trait>`, since macros, such as this one, don't have access to
/// that compiler resolution information, only to syntactical paths.
///
/// The only hard-coded exception to this rule is when inside a
/// <code>[#\[gat\]]</code> trait definition or implementation: there, not only
/// is `Gat!` automagically applied where applicable, the `Self::Assoc<…>` types
/// also become `<Self as Trait>::Assoc<…>`.
///
/// [#\[gat\]]: gat
pub use ::nougat_proc_macros::Gat;

/// Reëxport of [`::macro_rules_attribute::apply`](
/// https://docs.rs/macro_rules_attribute/0.1.*/macro_rules_attribute/attr.apply.html)
///
/// Intended to be used as <code>#\[apply([Gat!])\]</code> to try and apply
/// `Gat!` to each `<Type as Trait>::Assoc<…>` occurrence.
pub use ::macro_rules_attribute::apply;

#[cfg_attr(feature = "ui-tests",
    cfg_attr(all(), doc = include_str!("compile_fail_tests.md")),
)]
mod _compile_fail_tests {}