Skip to main content

closed_trait_macros/
lib.rs

1//! Attribute macros for the [`closed-trait`](https://docs.rs/closed-trait) crate. Use them through
2//! that crate, which re-exports both and provides the items the generated code refers to.
3mod enumerate;
4mod implements;
5mod sealed;
6mod util;
7
8use proc_macro::TokenStream;
9
10/// Seals a trait so that only the listed types can implement it, and every listed type must
11/// implement it.
12///
13/// ```compile_fail
14/// # use closed_trait::sealed;
15/// #[sealed(Circle, Square)] // error: Square does not implement Shape
16/// trait Shape {}
17///
18/// struct Circle;
19/// impl Shape for Circle {}
20///
21/// struct Square;
22///
23/// impl Shape for i32 {} // error: i32 is not permitted
24/// # fn main() {}
25/// ```
26///
27/// # Entries
28///
29/// An entry is a type, written plainly or as a path, as in `#[sealed(Square, shapes::Circle)]`, and
30/// that is all of it where neither the trait nor the type is generic. Cases where one or both of
31/// them are generic are presented in the next sections.
32///
33/// ## A generic trait
34///
35/// A generic trait has to be told which of its instantiations the entry implements.
36/// `Entry: Trait<..>` says which:
37///
38/// ```
39/// # use closed_trait::sealed;
40/// struct Plain;
41///
42/// #[sealed(Plain: Store<i32>)]
43/// trait Store<T> {}
44///
45/// impl Store<i32> for Plain {}
46/// # fn main() {}
47/// ```
48///
49/// One instantiation can be enough, but the type may implement the trait at every one of them.
50/// `for<..>` declares a parameter for the entry to instantiate with:
51///
52/// ```
53/// # use closed_trait::sealed;
54/// struct Plain;
55///
56/// // every `Store<T>`, not just one
57/// #[sealed(for<T> Plain: Store<T>)]
58/// trait Store<T> {}
59///
60/// impl<T> Store<T> for Plain {}
61/// # fn main() {}
62/// ```
63///
64/// A parameter the binder declares can carry bounds:
65///
66/// ```
67/// # use closed_trait::sealed;
68/// # use std::fmt::Debug;
69/// struct Plain;
70///
71/// #[sealed(for<T: Debug> Plain: Store<T>)]
72/// trait Store<T> {}
73///
74/// impl<T: Debug> Store<T> for Plain {}
75/// # fn main() {}
76/// ```
77///
78/// The bounds are part of what is sealed: `Plain` is permitted `Store<T>` only where `T: Debug`, so
79/// an `impl<T> Store<T> for Plain` covering every `T` is refused.
80///
81/// Lifetimes, types and const parameters can be declared together, lifetimes first (as in
82/// `for<'a, T: Clone, const N: usize>`), and each is written exactly as it would be on an `impl`.
83///
84/// ## A generic type
85///
86/// The parameters a `for<..>` declares serve the type just as well, which is how a trait with no
87/// parameters of its own seals a generic type:
88///
89/// ```
90/// # use closed_trait::sealed;
91/// # struct Square;
92/// # impl Shape for Square {}
93/// # struct Circle;
94/// # impl Shape for Circle {}
95/// struct Ref<'a, T>(&'a T);
96///
97/// #[sealed(
98///     for<'a, T: Shape> Ref<'a, T>,
99///     Square,
100///     Circle,
101/// )]
102/// trait Shape {}
103///
104/// impl<'a, T: Shape> Shape for Ref<'a, T> {}
105/// # fn main() {}
106/// ```
107///
108/// ## A generic type under a generic trait
109///
110/// One binder covers both, and a name it declares may stand in the type and the instantiation
111/// alike.
112///
113/// ```
114/// # use closed_trait::sealed;
115/// struct Boxed<U>(U);
116///
117/// // every `Boxed<U>`, each at the matching `Store<U>`
118/// #[sealed(for<U> Boxed<U>: Store<U>)]
119/// trait Store<T> {}
120///
121/// impl<U> Store<U> for Boxed<U> {}
122/// # fn main() {}
123/// ```
124///
125/// The binder's names are its own, so where they go is what counts, not what they are called:
126/// `for<U, V> Pair<U, V>: Store<V, U>` seals `Pair<U, V>` at `Store<V, U>`, swapped. And the
127/// instantiation's arguments are ordinary types, so a parameter can sit inside a larger one rather
128/// than be the argument itself: `for<T> Keyed<T>: Store<Vec<T>>`.
129///
130/// ## `as Name`
131///
132/// Names the entry. Only [`enumerate`][macro@enumerate] reads it: a variant is otherwise named
133/// after the type it holds, and two entries whose names come out the same would be one variant
134/// twice, which is refused. `as Name` gives one of them a name of its own. This happens in two
135/// ways.
136///
137/// **Different types whose last segment matches.** Here the name settles which is which:
138///
139/// ```
140/// # use closed_trait::{enumerate, sealed};
141/// mod a { pub struct Foo; }
142/// mod b { pub struct Foo; }
143///
144/// #[enumerate]
145/// // without `as`, both would take the last segment `Foo`
146/// #[sealed(a::Foo as Left, b::Foo as Right)]
147/// trait Shape {}
148///
149/// impl Shape for a::Foo {}
150/// impl Shape for b::Foo {}
151///
152/// # fn main() {
153/// let _ = AnyShape::Left(a::Foo); // see enumerate
154/// # }
155/// ```
156///
157/// **The same type listed twice**, which is how one type reaches the enum at more than one
158/// instantiation. There the name is not a nicety but required, since both entries would otherwise
159/// be the `Plain` variant:
160///
161/// ```
162/// # use closed_trait::{enumerate, sealed};
163/// # use closed_trait::Enumerable;
164/// struct Plain;
165/// struct Boxed<T>(pub T);
166///
167/// #[enumerate]
168/// #[sealed(Plain: Store<i32>, Plain as PlainF64: Store<f64>, for<T> Boxed<T>: Store<T>)]
169/// trait Store<T> {}
170///
171/// impl Store<i32> for Plain {}
172/// impl Store<f64> for Plain {}
173/// impl<T> Store<T> for Boxed<T> {}
174///
175/// # fn main() {
176/// // the one type reaching two different enum instantiations
177/// assert!(matches!(Plain.into_enum(), AnyStore::<i32>::Plain(_)));
178/// assert!(matches!(Plain.into_enum(), AnyStore::<f64>::PlainF64(_)));
179/// # }
180/// ```
181///
182/// The name settles the *variant* only. The two entries must also pin different arguments, and
183/// some entry (`Boxed<T>` here) has to *mention* `T`. The enum is generic over the parameters its
184/// variants use, not over the trait's, since an enum may not declare one no variant uses. Drop
185/// `Boxed<T>` and nothing is left to be generic over: both entries become variants of one plain
186/// `AnyStore`, so `Plain` converts into it two ways and `into_enum` has two answers. `enumerate`
187/// refuses that. Keeping the enum generic is what puts the two entries in `AnyStore<i32>` and
188/// `AnyStore<f64>`, one `Plain` apiece.
189///
190/// ## All of it at once
191///
192/// A binder, the type, a name and the instantiation it implements, in that order:
193///
194/// ```
195/// # use closed_trait::sealed;
196/// struct Ref<'a, T>(&'a T);
197///
198/// #[sealed(
199///     for<'a, T> Ref<'a, T> as RefStore: Store<i32>
200/// )]
201/// trait Store<T> {}
202///
203/// impl<'a, T> Store<i32> for Ref<'a, T> {}
204/// # fn main() {}
205/// ```
206///
207/// # The list is checked in both directions
208///
209/// Every entry is checked, which is why a trait that declares type or const parameters needs them
210/// supplied for each of its entries, and the instantiation is what supplies them:
211/// `Plain: Store<i32>` pins them, `for<T> Boxed<T>: Store<T>` passes on what its binder declared.
212/// An entry without one is refused, since nothing could then tell whether it implements the trait
213/// at all. A trait declaring none asks nothing, which is why `#[sealed(Square, Circle)]` above
214/// needs no annotation.
215///
216/// A lifetime is never asked for, and not merely because inference usually copes. A type cannot
217/// implement the same trait at two different lifetimes: two such impls overlap, and coherence
218/// rejects them, so there is never more than one candidate to disambiguate. `#[sealed(Plain)]`
219/// under `trait Foo<'a>` is therefore accepted *and* checked: an entry implementing no `Foo` at all
220/// is still caught.
221///
222/// # The seal is as precise as the list
223///
224/// The marker carries the same type and const parameters the trait does, so `Plain: Store<i32>`
225/// permits `Plain` to implement `Store<i32>` and nothing else: an unlisted `impl Store<f64> for
226/// Plain` is rejected:
227///
228/// ```compile_fail
229/// # use closed_trait::sealed;
230/// struct Plain;
231///
232/// #[sealed(Plain: Store<i32>)]
233/// trait Store<T> {}
234///
235/// impl Store<i32> for Plain {}
236/// impl Store<f64> for Plain {} // error: not permitted to implement `Store` here
237/// # fn main() {}
238/// ```
239///
240/// An entry whose binder supplies them instead, like `for<T> Boxed<T>: Store<T>`, permits every
241/// instantiation, which is what the binder says. Lifetimes are not on the marker, for the reason
242/// above: they could never tell two entries apart.
243///
244/// # What the seal is worth
245///
246/// The marker trait is private to the module the attribute is written in, and carries a supertrait
247/// private one level deeper. Naming the marker is therefore not enough to satisfy it: the only
248/// place both can be implemented is inside the generated module, which nothing but this macro
249/// writes. Code sitting directly beside the sealed trait cannot opt a type in, which a single level
250/// of privacy would have allowed.
251///
252/// The cost is that permitted types must be nameable from that module, so they have to live at
253/// module level. **A type declared inside a function body cannot be sealed**, because no module
254/// nested in a function can refer to it.
255#[proc_macro_attribute]
256pub fn sealed(args: TokenStream, item: TokenStream) -> TokenStream {
257    sealed::process(args, item)
258}
259
260/// Generates enums holding the types a trait is sealed to and macros rules to work with these
261/// enums.
262///
263/// Reads its type list from the `#[sealed(..)]` attribute below it, so it must be written **above**;
264/// attribute macros run top down, and `#[sealed]` consumes itself when it expands.
265///
266/// ```
267/// # use closed_trait::{enumerate, sealed};
268/// // on a concrete type `into_enum` needs the trait in scope; a generic
269/// // `S: Shape` gets it from the supertrait bound
270/// use closed_trait::Enumerable;
271///
272/// struct Square;
273/// struct Circle;
274///
275/// #[enumerate]
276/// #[sealed(Square, Circle)]
277/// trait Shape {}
278///
279/// impl Shape for Square {}
280/// impl Shape for Circle {}
281///
282/// # fn main() {
283/// let shape: AnyShape = Square.into_enum();
284/// match shape {
285///     AnyShape::Square(_) => {},
286///     AnyShape::Circle(_) => {},
287/// # }
288/// }
289/// ```
290///
291/// # The three enums
292///
293/// All three are generated by default, each with one variant per entry named after the type's last
294/// path segment, and each taking the trait's visibility. A type not in upper camel case therefore
295/// gives a variant that is not either (`i32` yields an `i32` variant), so the enums carry
296/// `#[allow(non_camel_case_types)]`: the name came from a type, not from a choice the caller made.
297/// `as Name` is there for anyone who would rather write `I32`. Given the base `Shape` sealed
298/// trait:
299///
300/// | enum              | holds            | reached from                               |
301/// | ----------------- | ---------------- | ------------------------------------------ |
302/// | `AnyShape`        | `Square`         | `into_enum`, or `From`                     |
303/// | `AnyShapeRef<'a>` | `&'a Square`     | `as_enum_ref`, `From`, or `owned.as_ref()` |
304/// | `AnyShapeMut<'a>` | `&'a mut Square` | `as_enum_mut`, `From`, or `owned.as_mut()` |
305///
306/// Each brings a supertrait with it: `Enumerable<AnyShape>` and the higher-ranked `for<'a>
307/// EnumerableRef<'a, AnyShapeRef<'a>>` and its `Mut` counterpart, which is what makes the enums
308/// reachable from a generic `S: Shape` without naming them.
309///
310/// The borrowing pair is what `into_enum` cannot give you: taking `self`, it needs the value moved
311/// in, so a `&S` has no route to the owned enum at all. They are also cheaper to pass, being a
312/// pointer and a discriminant rather than as wide as the largest permitted type. The shared one
313/// derives `Clone` and `Copy`.
314///
315/// Conversions *between* the three (`as_ref` and `as_mut` on the owned enum, and `as_ref` on the
316/// unique one, which reborrows) come as inherent methods. `no_bridge` leaves them out.
317///
318/// # Options
319///
320/// Written bare, an option applies to all three enums. Written inside `owned(..)`, `ref(..)` or
321/// `mut(..)` it applies to that one, and a specific option beats a grouped one.
322///
323/// ## `name = ..`
324///
325/// Names the enums, which are `Any{Trait}`, `Any{Trait}Ref` and `Any{Trait}Mut` by default.
326///
327/// Grouped, it is a **base** that each kind extends, so `name = "Shapes"` gives `Shapes`,
328/// `ShapesRef` and `ShapesMut`. Specific, it is the name itself: `ref(name = "ShapeView")` gives
329/// exactly `ShapeView`.
330///
331/// ```
332/// # use closed_trait::{enumerate, sealed};
333/// # struct Square;
334///
335/// #[enumerate(name = "Shapes", ref(name = "ShapeView"))]
336/// #[sealed(Square)]
337/// trait Shape {}
338///
339/// impl Shape for Square {}
340///
341/// # fn main() {
342/// let mut owned: Shapes        = Shapes::Square(Square);
343/// let mutable:   ShapesMut<'_> = owned.as_mut();
344/// let reference: ShapeView<'_> = mutable.as_ref();
345/// # }
346/// ```
347///
348/// ## `no_bridge`
349///
350/// Prevents generating the conversion methods written *on* an enum. `owned(no_bridge)` drops
351/// `as_ref(&self)` and `as_mut(&mut self)`; `mut(no_bridge)` drops the reborrowing `as_ref(&self)`;
352/// a bare `no_bridge` drops all three. Nothing is written on the shared enum, so `ref(no_bridge)`
353/// is refused rather than silently doing nothing.
354///
355/// ## `attrs = ".."`
356///
357/// Attributes to put on a generated enum, verbatim: derives, `#[non_exhaustive]`, `#[repr(..)]`,
358/// anything. It is the one option that **must** be specific. What is valid differs between
359/// the three: the shared enum already derives `Copy`, and the unique one cannot derive `Clone` at
360/// all, so one spelling spread across them would be a trap. A bare `attrs` is an error saying so.
361///
362/// ```
363/// # use closed_trait::{enumerate, sealed};
364/// # #[derive(Clone, Debug, PartialEq)] pub struct Square;
365///
366/// #[enumerate(owned(attrs = "#[derive(Clone, Debug, PartialEq)] #[non_exhaustive]"))]
367/// #[sealed(Square)]
368/// trait Shape {}
369///
370/// # impl Shape for Square {}
371/// # fn main() {}
372/// ```
373///
374/// Documentation is the exception: the enum's docs are generated and identical for every sealed
375/// trait, so a `///` or `#[doc = ".."]` here is an error.
376///
377/// ## `crate = ".."`
378///
379/// Where the generated code should look for `Enumerable`. Defaults to `::closed_trait`, which is
380/// right whenever `closed-trait` is a direct dependency under its own name.
381///
382/// It is wrong in two cases, and both fail with `cannot find `closed_trait` in the crate root` even
383/// though nothing in the caller's source names it:
384///
385/// - the dependency was renamed, as in `st = { package = "closed-trait" }`;
386/// - the macros are reached through a re-export, so the caller does not depend
387///   on `closed-trait` at all.
388///
389/// Point it at whatever crate re-exports `Enumerable`:
390///
391/// ```
392/// # use closed_trait::{enumerate, sealed};
393/// # pub struct Square;
394/// #[enumerate(crate = "::closed_trait")]
395/// #[sealed(Square)]
396/// trait Shape {}
397///
398/// # impl Shape for Square {}
399/// # fn main() {}
400/// ```
401///
402/// ## `match_any`
403///
404/// Generates `match_any_{trait}!`, a macro that expands to a `match` over every variant. A `match`
405/// on the enum already tells the variants apart; what this adds is one body that runs against the
406/// *concrete* type, which a closure cannot express because Rust has no generic closures.
407///
408/// ```
409/// # use closed_trait::{enumerate, sealed};
410///
411/// struct Square { side: i32 }
412/// struct Circle { radius: i32 }
413///
414/// #[enumerate(match_any)]
415/// #[sealed(Square, Circle)]
416/// trait Shape { fn area(&self) -> i32; }
417///
418/// # impl Shape for Square { fn area(&self) -> i32 { self.side * self.side } }
419/// # impl Shape for Circle { fn area(&self) -> i32 { 3 * self.radius * self.radius } }
420///
421/// # fn main() {
422/// let shape = AnyShape::from(Square { side: 3 });
423/// let area = match_any_shape!(shape, s => s.area());
424/// assert_eq!(9, area);
425/// # }
426/// ```
427///
428/// The value may be given by `&`, by `&mut` or by value; match ergonomics make
429/// the binding follow it, so one macro covers all three. The binding has to be
430/// named by the caller.
431///
432/// It is a `match`, not a closure, and the difference is the point:
433///
434/// ```
435/// # use closed_trait::{enumerate, sealed};
436/// # pub struct Square { pub side: i32 }
437/// # pub struct Circle { pub radius: i32 }
438/// # #[enumerate(match_any)]
439/// # #[sealed(Square, Circle)]
440/// # pub trait Shape { fn area(&self) -> i32; }
441/// # impl Shape for Square { fn area(&self) -> i32 { self.side * self.side } }
442/// # impl Shape for Circle { fn area(&self) -> i32 { 3 * self.radius * self.radius } }
443/// fn first_greater(shapes: &[AnyShape], value: i32) -> Option<i32> {
444///     for shape in shapes {
445///         // `return` leaves `first_big`, which a method taking the body could
446///         // never do
447///         match_any_shape!(shape, s => if s.area() > value { return Some(s.area()) });
448///     }
449///     None
450/// }
451///
452/// # fn main() {}
453/// ```
454///
455/// The body may also move anything it owns, since only one arm ever runs, and it can be `async`.
456/// To handle some variants differently, match first and let the last arm fall through:
457///
458/// ```
459/// # use closed_trait::{enumerate, sealed};
460/// # pub struct Square { pub side: i32 }
461/// # pub struct Circle { pub radius: i32 }
462/// # #[enumerate(match_any)]
463/// # #[sealed(Square, Circle)]
464/// # pub trait Shape { fn area(&self) -> i32; }
465/// # impl Shape for Square { fn area(&self) -> i32 { self.side * self.side } }
466/// # impl Shape for Circle { fn area(&self) -> i32 { 3 * self.radius * self.radius } }
467/// # fn main() {
468/// # let shape = AnyShape::from(Square { side: 3 });
469/// let cost = match &shape {
470///     AnyShape::Square(_) => 0,
471///     other => match_any_shape!(other, s => s.area()),
472/// };
473/// # assert_eq!(cost, 0);
474/// # }
475/// ```
476///
477/// Two things follow from it being a macro. The enum and the trait must be in scope where it is
478/// called, because a `macro_rules!` body resolves paths at the call site. And the body is *copied*
479/// into every arm.
480///
481/// That copying is worth being deliberate about. It costs compile time in proportion to the number
482/// of variants, since the body is type-checked once per arm, and one mistake in it is reported once
483/// per arm too. Nesting one of these inside another squares the count.
484///
485/// The option takes an optional name, so `match_any("match_shape")` generates `match_shape!`
486/// instead. Whether the macro can leave the crate depends on the trait's visibility, and so does
487/// whether it can collide, see [Visibility](#visibility).
488///
489/// # Visibility
490///
491/// Everything generated takes the trait's own visibility: the three enums, the conversions between
492/// them, and the names the match macros are reached through. There is no option to change it: the
493/// enums appear in the trait's supertrait bounds, so anything narrower would put a private type in
494/// a public interface.
495///
496/// It decides one thing beyond reach, though. A `macro_rules!` cannot leave the crate that defines
497/// it without `#[macro_export]`, and that always plants it at the crate root. So a macro generated
498/// for a `pub` trait goes there under a hidden name and is aliased beside the enum, while one for
499/// any narrower trait simply stays where it was written:
500///
501/// | the trait is      | the macro is                               | usable from another crate | can collide |
502/// | ----------------- | ------------------------------------------ | ------------------------- | ----------- |
503/// | `pub`             | at the crate root, aliased beside the enum | yes                       | yes         |
504/// | anything narrower | where it was written                       | no                        | no          |
505///
506/// Colliding means two traits of the same name, in different modules, both asking for `match_any`:
507/// their hidden root names would be the same, and one of them needs `match_any("other_name")`.
508///
509/// # Generics
510///
511/// A generic trait's enum declares the parameters its variants are generic over, with their bounds,
512/// not those of the trait: an enum may not declare a parameter no variant uses. Where every entry
513/// pins its arguments, none is left to declare and the enum is plain:
514///
515/// ```
516/// # use closed_trait::{enumerate, sealed};
517///
518/// // every entry fixes its argument, so `AnyValue` is a plain enum
519/// #[enumerate]
520/// #[sealed(
521///     i32: Value<i32>,
522///     f64: Value<f64>
523/// )]
524/// trait Value<T> {}
525///
526/// impl Value<i32> for i32 {}
527/// impl Value<f64> for f64 {}
528///
529/// # fn main() {
530/// let _: AnyValue = AnyValue::i32(6);
531/// # }
532/// ```
533///
534/// ## `for<..>` entries
535///
536/// Parameters declared in a `for<..>` binder are the entry's own and never reach the enum. Each is
537/// passed to the trait as an argument, and the parameter it lands on, carrying the bounds the
538/// binder gave it, is what the enum declares:
539///
540/// ```
541/// # use closed_trait::{enumerate, sealed};
542/// # use closed_trait::Enumerable;
543/// struct Boxed<U>(U);
544///
545/// #[enumerate]
546/// #[sealed(for<U> Boxed<U>: Store<U>)] // here `U` is used in place of `T` declared by Store
547/// trait Store<T> {}
548///
549/// impl<V> Store<V> for Boxed<V> {}
550///
551/// # fn main() {
552/// let _: AnyStore<u8> = Boxed(1u8).into_enum();
553/// # }
554/// ```
555///
556/// A name never passed that way lands on no parameter, so the variant has nothing to be generic
557/// over and the entry is refused: under a trait declaring none at all, `for<U> Boxed<U>: Shape`
558/// leaves `U` free. `#[sealed]` accepts it, but the enum cannot.
559///
560/// ## Pinned entries and `match_any`
561///
562/// An entry *pins* its arguments when it names a concrete instantiation instead of the trait's
563/// parameters. Such an entry becomes a variant like any other, and the enum does not record which
564/// instantiation that variant belongs to.
565///
566/// `into_enum` and `From` exist only at the instantiations the entry named, so nothing ever builds
567/// a variant that does not belong. Pinning therefore works with `enumerate`.
568///
569/// ```
570/// # use closed_trait::{enumerate, sealed};
571/// # use closed_trait::Enumerable;
572/// struct Plain;
573///
574/// #[enumerate]
575/// #[sealed(Plain: Store<i32>)]
576/// pub trait Store<T> {}
577///
578/// impl Store<i32> for Plain {}
579///
580/// # fn main() {
581/// let _: AnyStore = Plain.into_enum();
582/// # }
583/// ```
584///
585/// What such an entry rules out is `match_any`. Nothing stops the trait from being *named* at an
586/// instantiation no permitted type implements, and that is precisely where a body may ask the macro
587/// to expand. This is what it would become there, written out by hand:
588///
589/// ```compile_fail
590/// # use closed_trait::{enumerate, sealed};
591/// #[enumerate]
592/// #[sealed(i32: Value<i32>)]
593/// trait Value<T> {}
594///
595/// impl Value<i32> for i32 {}
596///
597/// fn describe(value: impl Value<String>) {
598///     // what `match_any_value!(value.into_enum(), v => takes(v))` becomes
599///     match value.into_enum() {
600///         // error: the trait bound `i32: Value<String>` is not satisfied
601///         AnyValue::i32(v) => takes(v),
602///     }
603/// }
604///
605/// fn takes<V: Value<String>>(_: V) {}
606/// # fn main() {}
607/// ```
608///
609/// The enum is fine, and so is the signature: `Value<String>` is a legal bound, merely one that
610/// nothing satisfies. Drop the `match` and it compiles on its own:
611///
612/// ```
613/// # use closed_trait::{enumerate, sealed};
614/// # #[enumerate]
615/// # #[sealed(i32: Value<i32>)]
616/// # trait Value<T> {}
617/// # impl Value<i32> for i32 {}
618/// fn describe(_: impl Value<String>) {}
619/// # fn main() {}
620/// ```
621///
622/// What cannot hold is the `match_any`. `AnyValue::i32` hands back an `i32`, which is a `Value<i32>`
623/// and nothing else, so a body written against `Value<String>` cannot use it. Rather than generate
624/// that and let it fail inside the caller's code, `#[enumerate]` refuses it where the list is
625/// written.
626///
627/// A permitted type that is not `Sized` cannot be held in a variant. That one is rustc's to
628/// report rather than this macro's, since sizedness is not visible in the tokens.
629#[proc_macro_attribute]
630pub fn enumerate(args: TokenStream, item: TokenStream) -> TokenStream {
631    enumerate::process(args, item)
632}
633
634/// Generates a macro that instantiates the attributed function for a type, when that type satisfies
635/// the bounds on the function's first parameter.
636///
637/// The macro is named after the function, with a `try_` prefix: `describe` gets `try_describe!`,
638/// `parse` gets `try_parse!`. `name = ".."` gives it another name. It takes an expression, tests
639/// its type, and returns `Some` of an [`Fn`] for that instantiation or `None`. Nothing is moved and
640/// nothing runs until that `Fn` is called, which may happen more than once:
641///
642/// ```
643/// # use closed_trait::if_implements_fn;
644/// # use std::fmt::Display;
645/// #[if_implements_fn]
646/// fn into_i32_plus_one(v: impl Into<i32>) -> i32 {
647///     v.into() + 1
648/// }
649///
650/// # fn main() {
651/// let n = 7u8;
652/// match try_into_i32_plus_one!(n) {
653///     Some(f) => assert_eq!(f(n), 8),
654///     None => unreachable!("u8 implements Into<i32>"),
655/// }
656///
657/// let s = "hello";
658/// match try_into_i32_plus_one!(s) {
659///     Some(_) => unreachable!("&str does not implement Into<i32>"),
660///     None => {},
661/// }
662/// # }
663/// ```
664///
665/// # The annotated function
666///
667/// The first parameter is the one tested, and its type is written in one of two ways:
668///
669/// ```
670/// # use closed_trait::if_implements_fn;
671/// # use std::fmt::Debug;
672/// #[if_implements_fn]
673/// fn named<T: Debug>(v: &T) {
674///     println!("{v:?}");
675/// }
676///
677/// #[if_implements_fn]
678/// fn anonymous(v: &impl Debug) {
679///     println!("{v:?}");
680/// }
681/// # fn main() {}
682/// ```
683///
684/// Both test the same thing: the bounds written on that parameter (here `Debug`). Bounds on any
685/// other parameter are not tested.
686///
687/// Everything else the signature says is the compiler's to check rather than this macro's, so
688/// lifetimes, `where` clauses, further parameters and `async` all work as they do on any function.
689/// What is refused is:
690///
691/// - a method, since the macro sits beside the function and a `macro_rules!` cannot be defined in
692///   an `impl` or a `trait`;
693/// - a function with no parameters, there being nothing to test;
694/// - an `unsafe fn`, whose unsafety the safe call would hide;
695/// - an explicit ABI, which the ordinary call would belie;
696/// - anything that would not be a valid function without the attribute, which the compiler reports
697///   as it always would.
698///
699/// A `const fn` is accepted and keeps its constness, since it is emitted as written. The macro's
700/// own path is not const (what it hands back is an `Fn` called at run time), so the macro cannot be
701/// used in a const context.
702///
703/// The macro calls the function rather than carrying a copy of its body, which is what makes its
704/// paths resolve at the *call site*: the function itself, and the traits its bounds name, have to
705/// be in scope there.
706///
707/// # Type and const arguments
708///
709/// The parameters the function declares besides the first can be given after a `;`, in declaration
710/// order, or left to inference as they would be at any other call:
711///
712/// ```
713/// # use closed_trait::if_implements_fn;
714/// # use std::fmt::Debug;
715/// #[if_implements_fn]
716/// fn function<T, const N: usize>(_: impl Debug) {}
717///
718/// # fn main() {
719/// // `T` and `N` are named nowhere in the signature, so nothing can infer them.
720/// try_function!("a"; String, 7);
721/// # }
722/// ```
723///
724/// The list is handed to a turbofish as written, so `_` and const arguments work as they do there,
725/// `try_function!("a"; String, { 3 + 4 })` included.
726///
727/// # Options
728///
729/// Each is a `key = "value"` pair, written in any order, and written at most once unless said
730/// otherwise.
731///
732/// ## Visibility
733///
734/// `vis = ".."` gives the macro a visibility of its own, written as it would be on any item. Left
735/// out, it takes the function's, capped at the crate: a `pub` function gets a `pub(crate)` macro,
736/// and anything narrower keeps what it has. Written out, it may narrow the function's visibility
737/// but not widen it, since the expansion is a call to the function: a macro reaching further than
738/// the function it calls would fail only at the call site.
739///
740/// ```
741/// # use closed_trait::if_implements_fn;
742/// # use std::fmt::Debug;
743/// #[if_implements_fn(vis = "pub(self)")]
744/// pub fn print_debug<T: Debug>(v: &T) {
745///     println!("{v:?}");
746/// }
747/// # fn main() {}
748/// ```
749///
750/// **`vis = "pub"` is the one value refused: the macro does not leave the crate, however public the
751/// function is.** A `macro_rules!` leaves its crate only through `#[macro_export]`, and that plants
752/// its name in the crate *root* rather than in the module it was written in, while the expansion
753/// still calls the function by the name it was written under.
754///
755/// ```
756/// mod private {
757///     pub fn not_pub() {}
758/// }
759/// # fn main() {}
760/// ```
761///
762/// The `pub` on the function above is meaningless, since its enclosing module is private. Exporting
763/// its macro would make that reachable from any crate while `not_pub` stays unreachable outside its
764/// module. An attribute is handed the item alone and never its surroundings, so there is no way to
765/// detect this, and for that reason exporting is not allowed at all.
766///
767/// ## Naming
768///
769/// `name = ".."` is the macro's whole name, `try_` included, for a function whose macro reads badly
770/// under the prefix or whose name is already taken:
771///
772/// ```
773/// # use closed_trait::if_implements_fn;
774/// # use std::fmt::Debug;
775/// #[if_implements_fn(name = "debug_if_possible")]
776/// pub fn print_debug<T: Debug>(v: &T) {
777///     println!("{v:?}");
778/// }
779///
780/// # fn main() {
781/// assert!(debug_if_possible!(&1).is_some());
782/// # }
783/// ```
784///
785/// # In a generic function
786///
787/// The bounds are tested against what the expression's type is *known* to be where the macro is
788/// written. Inside a generic function that is whatever the function declares, and not what it is
789/// later called with:
790///
791/// ```
792/// # use closed_trait::if_implements_fn;
793/// # use std::fmt::Display;
794/// #[if_implements_fn]
795/// fn show(v: impl Display) -> String {
796///     format!("{v}")
797/// }
798///
799/// fn unbounded<T>(v: T) -> bool {
800///     try_show!(v).is_some()
801/// }
802///
803/// fn bounded<T: Display>(v: T) -> bool {
804///     try_show!(v).is_some()
805/// }
806///
807/// # fn main() {
808/// assert!(!unbounded(6u8)); // `u8` is `Display`, but `T` is not
809/// assert!(bounded(6u8));
810/// # }
811/// ```
812///
813/// `unbounded` answers `None` for every `T`, `u8` included: nothing there says `T: Display`, so the
814/// test cannot hold. Declaring the bound is what makes it hold, and once it is declared the call
815/// could be written directly. So this is for a call site that knows the type concretely.
816///
817/// # Rationale
818///
819/// On its own the macro is rarely useful, since whether the tested type implements the given bounds
820/// is decided statically: most of the time the whole mechanism folds into either the direct call,
821/// when they hold, or nothing when they do not.
822///
823/// What it really buys is a call that can be written safely where the first argument (the one whose
824/// type is tested) may not have the right type. That is especially useful inside a
825/// [`match_any`][macro@enumerate] invocation, where the expression assumes several distinct types.
826///
827/// It is what lets that call be written once, inside the arm:
828///
829/// ```
830/// # use closed_trait::{enumerate, if_implements_fn, sealed};
831/// # use closed_trait::Enumerable;
832/// # use std::fmt::Debug;
833/// # #[derive(Debug)]
834/// # struct ImplDebug;
835/// # struct NotDebug;
836/// #[enumerate(match_any)]
837/// #[sealed(ImplDebug, NotDebug)]
838/// trait MyTrait {}
839/// # impl MyTrait for ImplDebug {}
840/// # impl MyTrait for NotDebug {}
841///
842/// #[if_implements_fn]
843/// fn print_debug(e: impl Debug) {
844///     println!("{e:?}");
845/// }
846///
847/// # fn main() {
848/// let v = ImplDebug.into_enum();
849/// match_any_my_trait!(v, v => {
850///     if let Some(f) = try_print_debug!(v) {
851///         f(v);
852///     }
853/// });
854/// # }
855/// ```
856///
857/// Written by hand, the same call does not compile:
858///
859/// ```compile_fail
860/// # use closed_trait::{enumerate, if_implements_fn, sealed};
861/// # use closed_trait::Enumerable;
862/// # use std::fmt::Debug;
863/// # #[derive(Debug)]
864/// # struct ImplDebug;
865/// # struct NotDebug;
866/// # #[enumerate(match_any)]
867/// # #[sealed(ImplDebug, NotDebug)]
868/// # trait MyTrait {}
869/// # impl MyTrait for ImplDebug {}
870/// # impl MyTrait for NotDebug {}
871/// # fn print_debug(e: impl Debug) {
872/// #     println!("{e:?}");
873/// # }
874/// # fn main() {
875/// let v = ImplDebug.into_enum();
876/// match_any_my_trait!(v, v => {
877///     print_debug(v); // compile error: NotDebug does not implement the Debug trait
878/// });
879/// # }
880/// ```
881///
882/// That can be fixed by not calling `print_debug` on `NotDebug`, but only by writing the whole
883/// match out, which grows tedious once the enum has dozens of variants.
884#[proc_macro_attribute]
885pub fn if_implements_fn(args: TokenStream, item: TokenStream) -> TokenStream {
886    implements::process(args, item)
887}