Skip to main content

fp_macros/
lib.rs

1#![warn(missing_docs)]
2#![allow(clippy::tabs_in_doc_comments)]
3
4//! Procedural macros for the [`fp-library`](https://docs.rs/fp-library/latest/fp_library/) crate.
5//!
6//! This crate provides macros for generating and working with Higher-Kinded Type (HKT) traits.
7
8pub(crate) mod a_do; // Applicative do-notation
9pub(crate) mod analysis; // Type and trait analysis
10pub(crate) mod codegen; // Code generation (includes re-exports)
11pub(crate) mod core; // Core infrastructure (config, error, result)
12pub(crate) mod documentation; // Documentation generation macros
13pub(crate) mod hkt; // Higher-Kinded Type macros
14pub(crate) mod hm; // Hindley-Milner type conversion
15pub(crate) mod m_do; // Monadic do-notation
16pub(crate) mod resolution; // Type resolution
17pub(crate) mod support; // Support utilities (attributes, syntax, validation, errors)
18
19#[cfg(test)]
20#[expect(
21	clippy::unwrap_used,
22	clippy::indexing_slicing,
23	reason = "Tests use panicking operations for brevity and clarity"
24)]
25mod property_tests;
26
27use {
28	crate::core::ToCompileError,
29	a_do::a_do_worker,
30	codegen::{
31		FunctionFormatter,
32		ReExportInput,
33		TraitFormatter,
34		generate_re_exports_worker,
35	},
36	documentation::{
37		document_examples_worker,
38		document_module_worker,
39		document_parameters_worker,
40		document_returns_worker,
41		document_signature_worker,
42		document_type_parameters_worker,
43		include_documentation_worker,
44	},
45	hkt::{
46		ApplyInput,
47		AssociatedTypes,
48		ImplKindInput,
49		apply_worker,
50		generate_inferable_brand_name,
51		generate_name,
52		impl_kind_worker,
53		kind_attr_worker,
54		trait_kind_worker,
55	},
56	m_do::{
57		DoInput,
58		m_do_worker,
59	},
60	proc_macro::TokenStream,
61	quote::quote,
62	syn::parse_macro_input,
63};
64
65/// Generates the name of a `Kind` trait based on its signature.
66///
67/// This macro takes a list of associated type definitions, similar to a trait definition.
68///
69/// ### Syntax
70///
71/// ```ignore
72/// Kind!(
73///     type AssocName<Params>: Bounds;
74///     // ...
75/// )
76/// ```
77///
78/// * `Associated Types`: A list of associated type definitions (e.g., `type Of<T>;`) that define the signature of the Kind.
79///
80/// ### Generates
81///
82/// The name of the generated `Kind` trait (e.g., `Kind_0123456789abcdef`).
83/// The name is deterministic and based on a hash of the signature.
84///
85/// ### Examples
86///
87/// ```ignore
88/// // Invocation
89/// let name = Kind!(type Of<T>;);
90///
91/// // Expanded code
92/// let name = Kind_...; // e.g., Kind_a1b2c3d4e5f67890
93/// ```
94///
95/// ```ignore
96/// // Invocation
97/// let name = Kind!(type Of<'a, T: Display>: Debug;);
98///
99/// // Expanded code
100/// let name = Kind_...; // Unique hash based on signature
101/// ```
102///
103/// ```ignore
104/// // Invocation
105/// let name = Kind!(
106///     type Of<T>;
107///     type SendOf<T>: Send;
108/// );
109///
110/// // Expanded code
111/// let name = Kind_...; // Unique hash based on signature
112/// ```
113///
114/// ### Limitations
115///
116/// Due to Rust syntax restrictions, this macro cannot be used directly in positions where a
117/// concrete path is expected by the parser, such as:
118/// * Supertrait bounds: `trait MyTrait: Kind!(...) {}` (Invalid)
119/// * Type aliases: `type MyKind = Kind!(...);` (Invalid)
120/// * Trait aliases: `trait MyKind = Kind!(...);` (Invalid)
121///
122/// For supertrait bounds, use the [`kind`] attribute macro instead:
123/// ```ignore
124/// #[kind(type Of<'a, A: 'a>: 'a;)]
125/// pub trait Functor { ... }
126/// ```
127///
128/// For other positions, you must use the generated name directly (e.g., `Kind_...`).
129#[proc_macro]
130#[expect(non_snake_case, reason = "Matches the PascalCase type-level concept it represents")]
131pub fn Kind(input: TokenStream) -> TokenStream {
132	let input = parse_macro_input!(input as AssociatedTypes);
133	let name = match generate_name(&input) {
134		Ok(name) => name,
135		Err(e) => return e.to_compile_error().into(),
136	};
137	quote!(#name).into()
138}
139
140/// Defines a new `Kind` trait and its corresponding `InferableBrand` trait.
141///
142/// This macro generates a trait definition for a Higher-Kinded Type signature,
143/// along with a `InferableBrand` trait that enables closure-directed brand inference
144/// in dispatch functions (see [`crate::dispatch`](https://docs.rs/fp-library/latest/fp_library/dispatch/)).
145///
146/// ### Syntax
147///
148/// ```ignore
149/// trait_kind!(
150///     type AssocName<Params>: Bounds;
151///     // ...
152/// )
153/// ```
154///
155/// * `Associated Types`: A list of associated type definitions (e.g., `type Of<T>;`) that define the signature of the Kind.
156///
157/// ### Generates
158///
159/// Two public trait definitions with unique names derived from the signature:
160///
161/// 1. `Kind_{hash}`: The HKT trait with the specified associated types.
162/// 2. `InferableBrand_{hash}`: A reverse-mapping trait for closure-directed brand inference.
163///    Both share the same content hash.
164///
165/// ### Examples
166///
167/// ```ignore
168/// // Invocation
169/// trait_kind!(type Of<T>;);
170///
171/// // Expanded code
172/// pub trait Kind_a1b2... {
173///     type Of<T>;
174/// }
175/// pub trait InferableBrand_a1b2...<A> {
176///     type Marker;
177/// }
178/// ```
179///
180/// ```ignore
181/// // Invocation
182/// trait_kind!(type Of<'a, T: Display>: Debug;);
183///
184/// // Expanded code
185/// pub trait Kind_cdef... {
186///     type Of<'a, T: Display>: Debug;
187/// }
188/// pub trait InferableBrand_cdef...<'a, Brand, A: Display> {
189///     type Marker;
190/// }
191/// ```
192#[proc_macro]
193pub fn trait_kind(input: TokenStream) -> TokenStream {
194	let input = parse_macro_input!(input as AssociatedTypes);
195	match trait_kind_worker(input) {
196		Ok(tokens) => tokens.into(),
197		Err(e) => e.to_compile_error().into(),
198	}
199}
200
201/// Implements a `Kind` trait and its `InferableBrand` trait for a brand.
202///
203/// This macro simplifies the implementation of a generated `Kind` trait for a specific
204/// brand type, and also generates the `InferableBrand` impl that enables closure-directed brand
205/// inference in dispatch functions. It infers the correct `Kind` trait to implement based
206/// on the signature of the associated types provided in the block.
207///
208/// The signature (names, parameters, and bounds) of the associated types must match
209/// the definition used in [`trait_kind!`] or [`Kind!`] to ensure the correct trait is implemented.
210///
211/// ### Syntax
212///
213/// ```ignore
214/// impl_kind! {
215///     // Optional impl generics
216///     impl<Generics> for BrandType
217///     // Optional where clause
218///     where Bounds
219///     {
220///         type AssocName<Params> = ConcreteType;
221///         // ... more associated types
222///     }
223/// }
224/// ```
225///
226/// * `Generics`: Optional generic parameters for the implementation.
227/// * `BrandType`: The brand type to implement the Kind for.
228/// * `Bounds`: Optional where clause bounds.
229/// * `Associated Types`: The associated type assignments (e.g., `type Of<A> = Option<A>;`).
230///
231/// ### Generates
232///
233/// 1. An implementation of the appropriate `Kind_{hash}` trait for the brand.
234/// 2. A `InferableBrand_{hash}` impl for the target type with `type Marker = Val`,
235///    enabling closure-directed brand inference for both single-brand and
236///    multi-brand types.
237///
238/// The `InferableBrand` impl is generated for ALL brands (including multi-brand types).
239/// Projection types and multiple-associated-type definitions do suppress it.
240///
241/// ### Attributes
242///
243/// Inside the `impl_kind!` block, you can use these attributes:
244///
245/// * `#[multi_brand]`: Marks this brand as sharing its target type with other
246///   brands. Does NOT suppress `InferableBrand` impl generation.
247/// * `#[document_default]`: Marks this associated type as the default for resolving bare `Self` in
248///   the generated documentation for this brand within the module.
249///
250/// ### Examples
251///
252/// ```ignore
253/// // Invocation
254/// impl_kind! {
255///     for OptionBrand {
256///         #[document_default]
257///         type Of<A> = Option<A>;
258///     }
259/// }
260///
261/// // Expanded code (Kind impl + InferableBrand impl)
262/// impl Kind_a1b2... for OptionBrand {
263///     type Of<A> = Option<A>;
264/// }
265/// impl<A> InferableBrand_a1b2...<OptionBrand, A> for Option<A> {
266///     type Marker = Val;
267/// }
268/// ```
269///
270/// ```ignore
271/// // Invocation with impl generics
272/// impl_kind! {
273///     impl<E> for ResultBrand<E> {
274///         type Of<A> = Result<A, E>;
275///     }
276/// }
277///
278/// // Expanded code
279/// impl<E> Kind_... for ResultBrand<E> {
280///     type Of<A> = Result<A, E>;
281/// }
282/// impl<A, E> InferableBrand_...<ResultBrand<E>, A> for Result<A, E> {
283///     type Marker = Val;
284/// }
285/// ```
286///
287/// ```ignore
288/// // Multi-brand type: InferableBrand still generated
289/// impl_kind! {
290///     #[multi_brand]
291///     impl<E> for ResultErrAppliedBrand<E> {
292///         type Of<'a, A: 'a>: 'a = Result<A, E>;
293///     }
294/// }
295///
296/// // Expanded code (Kind impl + InferableBrand impl)
297/// impl<E> Kind_... for ResultErrAppliedBrand<E> {
298///     type Of<'a, A: 'a>: 'a = Result<A, E>;
299/// }
300/// impl<'a, A: 'a, E> InferableBrand_...<'a, ResultErrAppliedBrand<E>, A>
301///     for Result<A, E>
302/// {
303///     type Marker = Val;
304/// }
305/// ```
306///
307/// ```ignore
308/// // Multiple associated types: InferableBrand skipped automatically
309/// impl_kind! {
310///     impl<E> for MyBrand<E> where E: Clone {
311///         type Of<A> = MyType<A, E>;
312///         type SendOf<A> = MySendType<A, E>;
313///     }
314/// }
315///
316/// // Expanded code (only Kind impl)
317/// impl<E> Kind_... for MyBrand<E> where E: Clone {
318///     type Of<A> = MyType<A, E>;
319///     type SendOf<A> = MySendType<A, E>;
320/// }
321/// ```
322#[proc_macro]
323pub fn impl_kind(input: TokenStream) -> TokenStream {
324	let input = parse_macro_input!(input as ImplKindInput);
325	match impl_kind_worker(input) {
326		Ok(tokens) => tokens.into(),
327		Err(e) => e.to_compile_error().into(),
328	}
329}
330
331/// Applies a brand to type arguments.
332///
333/// This macro projects a brand type to its concrete type using the appropriate
334/// `Kind` trait. It uses a syntax that mimics a fully qualified path, where the
335/// `Kind` trait is specified by its signature.
336///
337/// ### Syntax
338///
339/// ```ignore
340/// Apply!(<Brand as Kind!( KindSignature )>::AssocType<Args>)
341/// ```
342///
343/// * `Brand`: The brand type (e.g., `OptionBrand`).
344/// * `KindSignature`: A list of associated type definitions defining the `Kind` trait schema.
345/// * `AssocType`: The associated type to project (e.g., `Of`).
346/// * `Args`: The concrete arguments to apply.
347///
348/// ### Generates
349///
350/// The concrete type resulting from applying the brand to the arguments.
351///
352/// ### Examples
353///
354/// ```ignore
355/// // Invocation
356/// // Applies MyBrand to lifetime 'static and type String.
357/// type Concrete = Apply!(<MyBrand as Kind!( type Of<'a, T>; )>::Of<'static, String>);
358///
359/// // Expanded code
360/// type Concrete = <MyBrand as Kind_...>::Of<'static, String>;
361/// ```
362///
363/// ```ignore
364/// // Invocation
365/// // Applies MyBrand to a generic type T with bounds.
366/// type Concrete = Apply!(<MyBrand as Kind!( type Of<T: Clone>; )>::Of<T>);
367///
368/// // Expanded code
369/// type Concrete = <MyBrand as Kind_...>::Of<T>;
370/// ```
371///
372/// ```ignore
373/// // Invocation
374/// // Complex example with lifetimes, types, and output bounds.
375/// type Concrete = Apply!(<MyBrand as Kind!( type Of<'a, T: Clone + Debug>: Display; )>::Of<'a, T>);
376///
377/// // Expanded code
378/// type Concrete = <MyBrand as Kind_...>::Of<'a, T>;
379/// ```
380///
381/// ```ignore
382/// // Invocation
383/// // Use a custom associated type for projection.
384/// type Concrete = Apply!(<MyBrand as Kind!( type Of<T>; type SendOf<T>; )>::SendOf<T>);
385///
386/// // Expanded code
387/// type Concrete = <MyBrand as Kind_...>::SendOf<T>;
388/// ```
389#[proc_macro]
390#[expect(non_snake_case, reason = "Matches the PascalCase type-level concept it represents")]
391pub fn Apply(input: TokenStream) -> TokenStream {
392	let input = parse_macro_input!(input as ApplyInput);
393	match apply_worker(input) {
394		Ok(tokens) => tokens.into(),
395		Err(e) => e.to_compile_error().into(),
396	}
397}
398
399/// Adds a `Kind` supertrait bound to a trait definition.
400///
401/// This attribute macro parses a Kind signature and adds the corresponding
402/// `Kind_` trait as a supertrait bound, avoiding the need to reference
403/// hash-based trait names directly.
404///
405/// ### Syntax
406///
407/// ```ignore
408/// #[kind(type AssocName<Params>: Bounds;)]
409/// pub trait MyTrait {
410///     // ...
411/// }
412/// ```
413///
414/// ### Examples
415///
416/// ```ignore
417/// // Invocation
418/// #[kind(type Of<'a, A: 'a>: 'a;)]
419/// pub trait Functor {
420///     fn map<'a, A: 'a, B: 'a>(
421///         f: impl Fn(A) -> B + 'a,
422///         fa: Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, A>),
423///     ) -> Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, B>);
424/// }
425///
426/// // Expanded code
427/// pub trait Functor: Kind_cdc7cd43dac7585f {
428///     // body unchanged
429/// }
430/// ```
431///
432/// ```ignore
433/// // Works with existing supertraits
434/// #[kind(type Of<'a, A: 'a>: 'a;)]
435/// pub trait Monad: Applicative {
436///     // Kind_ bound is appended: Monad: Applicative + Kind_...
437/// }
438/// ```
439#[proc_macro_attribute]
440pub fn kind(
441	attr: TokenStream,
442	item: TokenStream,
443) -> TokenStream {
444	let attr = parse_macro_input!(attr as AssociatedTypes);
445	let item = parse_macro_input!(item as syn::ItemTrait);
446	match kind_attr_worker(attr, item) {
447		Ok(tokens) => tokens.into(),
448		Err(e) => e.to_compile_error().into(),
449	}
450}
451
452/// Generates re-exports for all public free functions in a directory.
453///
454/// This macro scans the specified directory for Rust files, parses them to find public free functions,
455/// and generates `pub use` statements for them. It supports aliasing to resolve name conflicts
456/// and exclusions to suppress specific functions from being re-exported.
457///
458/// ### Syntax
459///
460/// ```ignore
461/// generate_function_re_exports!("path/to/directory", {
462///     "module::name": aliased_name,
463///     ...
464/// }, exclude {
465///     "module::name",
466///     ...
467/// })
468/// ```
469///
470/// * `path/to/directory`: The path to the directory containing the modules, relative to the crate root.
471/// * `aliases` (optional): A map of function names to their desired aliases. Keys can be
472///   qualified (`"module::function"`) or unqualified (`"function"`). When aliased, the function
473///   is exported under the alias name only.
474/// * `exclude` (optional): A set of function names to suppress entirely. Keys use the same
475///   qualified/unqualified format as aliases. Excluded functions are not re-exported at all,
476///   but remain available in their original modules.
477///
478/// ### Generates
479///
480/// `pub use` statements for each public function found in the directory, except those
481/// listed in the `exclude` block.
482///
483/// ### Examples
484///
485/// ```ignore
486/// generate_function_re_exports!("src/classes", {
487///     "category::identity": category_identity,
488///     "filterable::filter": filterable_filter,
489/// }, exclude {
490///     "ref_filterable::ref_filter",
491///     "ref_filterable::ref_filter_map",
492/// });
493///
494/// // Expanded: re-exports all public functions except ref_filter and ref_filter_map.
495/// // category::identity is exported as category_identity.
496/// // filterable::filter is exported as filterable_filter.
497/// ```
498#[proc_macro]
499pub fn generate_function_re_exports(input: TokenStream) -> TokenStream {
500	let input = parse_macro_input!(input as ReExportInput);
501	generate_re_exports_worker(&input, &FunctionFormatter).into()
502}
503
504/// Generates re-exports for all public traits in a directory.
505///
506/// This macro scans the specified directory for Rust files, parses them to find public traits,
507/// and generates `pub use` statements for them. Supports the same aliasing and exclusion
508/// syntax as [`generate_function_re_exports!`].
509///
510/// ### Syntax
511///
512/// ```ignore
513/// generate_trait_re_exports!("path/to/directory", {
514///     "module::TraitName": AliasedName,
515///     ...
516/// }, exclude {
517///     "module::TraitName",
518///     ...
519/// })
520/// ```
521///
522/// * `path/to/directory`: The path to the directory containing the modules, relative to the crate root.
523/// * `aliases` (optional): A map of trait names to their desired aliases.
524/// * `exclude` (optional): A set of trait names to suppress from re-export.
525///
526/// ### Generates
527///
528/// `pub use` statements for each public trait found in the directory, except those
529/// listed in the `exclude` block.
530///
531/// ### Examples
532///
533/// ```ignore
534/// generate_trait_re_exports!("src/classes", {});
535///
536/// // Expanded code
537/// pub use src::classes::functor::Functor;
538/// pub use src::classes::monad::Monad;
539/// // ... other re-exports
540/// ```
541#[proc_macro]
542pub fn generate_trait_re_exports(input: TokenStream) -> TokenStream {
543	let input = parse_macro_input!(input as ReExportInput);
544	generate_re_exports_worker(&input, &TraitFormatter).into()
545}
546
547/// Generates a Hindley-Milner style type signature for a function.
548///
549/// This macro analyzes the function signature and generates a documentation comment
550/// containing the corresponding Hindley-Milner type signature.
551///
552/// When used within a module annotated with [`#[document_module]`](macro@document_module),
553/// it automatically resolves `Self` and associated types based on the module's projection map.
554///
555/// ### Syntax
556///
557/// ```ignore
558/// // Auto-generate from the function signature
559/// #[document_signature]
560/// pub fn function_name<Generics>(params) -> ReturnType { ... }
561///
562/// // Manual override with an explicit signature string
563/// #[document_signature("forall A B. (A -> B) -> A -> B")]
564/// pub fn function_name<Generics>(params) -> ReturnType { ... }
565/// ```
566///
567/// When a string argument is provided, it is emitted directly as the
568/// signature without any analysis. This is useful for functions whose
569/// signatures cannot be inferred automatically.
570///
571/// When applying this macro to a method inside a trait, you can provide the trait name
572/// as an argument to correctly generate the `Trait self` constraint.
573///
574/// ### Generates
575///
576/// A documentation comment with the generated signature, prepended to the function definition.
577///
578/// ### Examples
579///
580/// ```ignore
581/// // Invocation
582/// #[document_signature]
583/// pub fn map<F: Functor, A, B>(f: impl Fn(A) -> B, fa: F::Of<A>) -> F::Of<B> { ... }
584///
585/// // Expanded code
586/// /// ### Type Signature
587/// /// `forall f a b. Functor f => (a -> b, f a) -> f b`
588/// pub fn map<F: Functor, A, B>(f: impl Fn(A) -> B, fa: F::Of<A>) -> F::Of<B> { ... }
589/// ```
590///
591/// ```ignore
592/// // Invocation
593/// #[document_signature]
594/// pub fn foo(x: impl Iterator<Item = String>) -> i32 { ... }
595///
596/// // Expanded code
597/// /// ### Type Signature
598/// /// `iterator -> i32`
599/// pub fn foo(x: impl Iterator<Item = String>) -> i32 { ... }
600/// ```
601///
602/// ```ignore
603/// // Invocation
604/// trait Functor {
605///     #[document_signature]
606///     fn map<A, B>(f: impl Fn(A) -> B, fa: Self::Of<A>) -> Self::Of<B>;
607/// }
608///
609/// // Expanded code
610/// trait Functor {
611///     /// ### Type Signature
612///     /// `forall self a b. Functor self => (a -> b, self a) -> self b`
613///     fn map<A, B>(f: impl Fn(A) -> B, fa: Self::Of<A>) -> Self::Of<B>;
614/// }
615/// ```
616///
617/// Manual override:
618///
619/// ```ignore
620/// // Invocation
621/// #[document_signature("forall F A B. Contravariant F => (B -> A, F A) -> F B")]
622/// pub fn contramap<FA, A, B>(f: impl Fn(B) -> A, fa: FA) -> FA::Of<B> { ... }
623///
624/// // Expanded code
625/// /// ### Type Signature
626/// /// `forall F A B. Contravariant F => (B -> A, F A) -> F B`
627/// pub fn contramap<FA, A, B>(f: impl Fn(B) -> A, fa: FA) -> FA::Of<B> { ... }
628/// ```
629///
630/// ### Dispatch-aware generation
631///
632/// When used inside a module annotated with
633/// [`#[document_module]`](macro@document_module), this macro benefits
634/// from dispatch trait analysis. If the function references a dispatch
635/// trait (via `impl *Dispatch<...>` or a where-clause bound), the
636/// macro builds a synthetic signature that replaces dispatch machinery
637/// with semantic equivalents (branded types, closure arrows, type
638/// class constraints). This produces cleaner signatures like
639/// `forall Brand A B. Functor Brand => (A -> B, Brand A) -> Brand B`
640/// instead of the raw Rust signature with `InferableBrand` and `Kind_*` bounds.
641///
642/// ### Configuration
643///
644/// This macro can be configured via `Cargo.toml` under `[package.metadata.document_signature]`.
645///
646/// * `brand_mappings`: A map of brand struct names to their display names in the signature.
647/// * `apply_macro_aliases`: A list of macro names that should be treated as `Apply!`.
648/// * `ignored_traits`: A list of traits to ignore in the signature constraints.
649///
650/// Example:
651/// ```toml
652/// [package.metadata.document_signature]
653/// brand_mappings = { "OptionBrand" = "Option", "VecBrand" = "Vec" }
654/// apply_macro_aliases = ["MyApply"]
655/// ignored_traits = ["Clone", "Debug"]
656/// ```
657#[proc_macro_attribute]
658pub fn document_signature(
659	attr: TokenStream,
660	item: TokenStream,
661) -> TokenStream {
662	match document_signature_worker(attr.into(), item.into()) {
663		Ok(tokens) => tokens.into(),
664		Err(e) => e.to_compile_error().into(),
665	}
666}
667
668/// Generates documentation for type parameters.
669///
670/// This macro analyzes the item's signature (function, struct, enum, impl block, etc.)
671/// and generates a documentation comment list based on the provided descriptions.
672///
673/// When used within a module annotated with [`#[document_module]`](macro@document_module),
674/// it benefits from automatic `Self` resolution and is applied as part of the module-level
675/// documentation pass.
676///
677/// ### Syntax
678///
679/// ```ignore
680/// #[document_type_parameters(
681///     "Description for first parameter",
682///     ("OverriddenName", "Description for second parameter"),
683///     ...
684/// )]
685/// pub fn function_name<Generics>(params) -> ReturnType { ... }
686/// ```
687///
688/// It can also be used on other items like `impl` blocks:
689///
690/// ```ignore
691/// #[document_type_parameters("Description for T")]
692/// impl<T> MyType<T> { ... }
693/// ```
694///
695/// * `Descriptions`: A comma-separated list. Each entry can be either a string literal
696///   or a tuple of two string literals `(Name, Description)`.
697///
698/// ### Generates
699///
700/// A list of documentation comments, one for each generic parameter, prepended to the
701/// function definition.
702///
703/// ### Examples
704///
705/// ```ignore
706/// // Invocation
707/// #[document_type_parameters(
708///     "The type of the elements.",
709///     ("E", "The error type.")
710/// )]
711/// pub fn map<T, ERR>(...) { ... }
712///
713/// // Expanded code
714/// /// ### Type Parameters
715/// /// * `T`: The type of the elements.
716/// /// * `E`: The error type.
717/// pub fn map<T, ERR>(...) { ... }
718/// ```
719///
720/// ### Constraints
721///
722/// * The number of arguments must exactly match the number of generic parameters
723///   (including lifetimes, types, and const generics) in the function signature.
724#[proc_macro_attribute]
725pub fn document_type_parameters(
726	attr: TokenStream,
727	item: TokenStream,
728) -> TokenStream {
729	match document_type_parameters_worker(attr.into(), item.into()) {
730		Ok(tokens) => tokens.into(),
731		Err(e) => e.to_compile_error().into(),
732	}
733}
734
735/// Generates documentation for a function's parameters.
736///
737/// This macro analyzes the function signature and generates a documentation comment
738/// list based on the provided descriptions. It also handles curried return types.
739///
740/// It can also be used on `impl` blocks to provide a common description for the receiver (`self`)
741/// parameter of methods within the block.
742///
743/// ### Syntax
744///
745/// For functions:
746/// ```ignore
747/// #[document_parameters(
748///     "Description for first parameter",
749///     ("overridden_name", "Description for second parameter"),
750///     ...
751/// )]
752/// pub fn function_name(params) -> impl Fn(...) { ... }
753/// ```
754///
755/// For `impl` blocks:
756/// ```ignore
757/// #[document_parameters("Description for receiver")]
758/// impl MyType {
759///     #[document_parameters]
760///     pub fn method_with_receiver(&self) { ... }
761///
762///     #[document_parameters("Description for arg")]
763///     pub fn method_with_args(&self, arg: i32) { ... }
764/// }
765/// ```
766///
767/// * `Descriptions`: A comma-separated list. Each entry can be either a string literal
768///   or a tuple of two string literals `(Name, Description)`.
769/// * For `impl` blocks: Exactly one string literal describing the receiver parameter.
770///
771/// ### Generates
772///
773/// A list of documentation comments, one for each parameter, prepended to the
774/// function definition.
775///
776/// ### Examples
777///
778/// ```ignore
779/// // Invocation
780/// #[document_parameters(
781///     "The first input value.",
782///     ("y", "The second input value.")
783/// )]
784/// pub fn foo(x: i32) -> impl Fn(i32) -> i32 { ... }
785///
786/// // Expanded code
787/// /// ### Parameters
788/// /// * `x`: The first input value.
789/// /// * `y`: The second input value.
790/// pub fn foo(x: i32) -> impl Fn(i32) -> i32 { ... }
791/// ```
792///
793/// ```ignore
794/// // Invocation on impl block
795/// #[document_parameters("The list instance")]
796/// impl<A> MyList<A> {
797///     #[document_parameters("The element to push")]
798///     pub fn push(&mut self, item: A) { ... }
799/// }
800///
801/// // Expanded code
802/// impl<A> MyList<A> {
803///     /// ### Parameters
804///     /// * `&mut self`: The list instance
805///     /// * `item`: The element to push
806///     pub fn push(&mut self, item: A) { ... }
807/// }
808/// ```
809///
810/// ### Constraints
811///
812/// * The number of arguments must exactly match the number of function parameters
813///   (excluding `self` but including parameters from curried return types).
814///
815/// ### Configuration
816///
817/// This macro can be configured via `Cargo.toml` under `[package.metadata.document_signature]`.
818///
819/// * `apply_macro_aliases`: A list of macro names that should be treated as `Apply!` for curried parameter extraction.
820///
821/// Example:
822/// ```toml
823/// [package.metadata.document_signature]
824/// apply_macro_aliases = ["MyApply"]
825/// ```
826#[proc_macro_attribute]
827pub fn document_parameters(
828	attr: TokenStream,
829	item: TokenStream,
830) -> TokenStream {
831	match document_parameters_worker(attr.into(), item.into()) {
832		Ok(tokens) => tokens.into(),
833		Err(e) => e.to_compile_error().into(),
834	}
835}
836
837/// Generates documentation for the return value of a function.
838///
839/// This macro adds a "Returns" section to the function's documentation.
840///
841/// ### Syntax
842///
843/// ```ignore
844/// #[document_returns("Description of the return value.")]
845/// pub fn foo() -> i32 { ... }
846/// ```
847///
848/// ### Generates
849///
850/// A documentation comment describing the return value.
851///
852/// ### Examples
853///
854/// ```ignore
855/// // Invocation
856/// #[document_returns("The sum of x and y.")]
857/// pub fn add(x: i32, y: i32) -> i32 { ... }
858///
859/// // Expanded code
860/// /// ### Returns
861/// /// The sum of x and y.
862/// pub fn add(x: i32, y: i32) -> i32 { ... }
863/// ```
864#[proc_macro_attribute]
865pub fn document_returns(
866	attr: TokenStream,
867	item: TokenStream,
868) -> TokenStream {
869	match document_returns_worker(attr.into(), item.into()) {
870		Ok(tokens) => tokens.into(),
871		Err(e) => e.to_compile_error().into(),
872	}
873}
874
875/// Inserts a `### Examples` heading and validates doc comment code blocks.
876///
877/// This attribute macro expands in-place to a `### Examples` heading. Example
878/// code is written as regular doc comments using fenced code blocks after the
879/// attribute. Every Rust code block must contain at least one assertion macro
880/// invocation (e.g., `assert_eq!`, `assert!`).
881///
882/// ### Syntax
883///
884/// ```ignore
885/// #[document_examples]
886/// ///
887/// /// ```
888/// /// let result = add(1, 2);
889/// /// assert_eq!(result, 3);
890/// /// ```
891/// pub fn add(x: i32, y: i32) -> i32 { ... }
892/// ```
893///
894/// ### Generates
895///
896/// A `### Examples` heading is inserted at the attribute's position. The code
897/// blocks in the doc comments are validated but not modified.
898///
899/// ### Examples
900///
901/// ```ignore
902/// // Invocation
903/// #[document_examples]
904/// ///
905/// /// ```
906/// /// let x = my_fn(1, 2);
907/// /// assert_eq!(x, 3);
908/// /// ```
909/// pub fn my_fn(a: i32, b: i32) -> i32 { a + b }
910///
911/// // Expanded code
912/// /// ### Examples
913/// ///
914/// /// ```
915/// /// let x = my_fn(1, 2);
916/// /// assert_eq!(x, 3);
917/// /// ```
918/// pub fn my_fn(a: i32, b: i32) -> i32 { a + b }
919/// ```
920///
921/// ### Errors
922///
923/// * Arguments are provided to the attribute.
924/// * No Rust code block is found in the doc comments.
925/// * A Rust code block does not contain an assertion macro invocation.
926/// * The attribute is applied more than once to the same function.
927#[proc_macro_attribute]
928pub fn document_examples(
929	attr: TokenStream,
930	item: TokenStream,
931) -> TokenStream {
932	match document_examples_worker(attr.into(), item.into()) {
933		Ok(tokens) => tokens.into(),
934		Err(e) => e.to_compile_error().into(),
935	}
936}
937
938/// Orchestrates documentation generation for an entire module.
939///
940/// This macro provides a centralized way to handle documentation for Higher-Kinded Type (HKT)
941/// implementations. It performs a two-pass analysis of the module:
942///
943/// 1. **Context Extraction**: It scans for `impl_kind!` invocations and standard `impl` blocks
944///    to build a comprehensive mapping of associated types (a "projection map").
945/// 2. **Documentation Generation**: It processes all methods annotated with [`#[document_signature]`](macro@document_signature)
946///    or [`#[document_type_parameters]`](macro@document_type_parameters), resolving `Self` and associated types
947///    using the collected context.
948/// 3. **Validation** (Optional): Checks that impl blocks and methods have appropriate documentation
949///    attributes and emits compile-time warnings for missing documentation.
950///
951/// ### Syntax
952///
953/// Due to inner macro attributes being unstable, use the following wrapper pattern:
954///
955/// ```ignore
956/// #[fp_macros::document_module]
957/// mod inner {
958///     // ... module content ...
959/// }
960/// pub use inner::*;
961/// ```
962///
963/// To disable validation warnings:
964///
965/// ```ignore
966/// #[fp_macros::document_module(no_validation)]
967/// mod inner {
968///     // ... module content ...
969/// }
970/// pub use inner::*;
971/// ```
972///
973/// ### Generates
974///
975/// In-place replacement of [`#[document_signature]`](macro@document_signature) and
976/// [`#[document_type_parameters]`](macro@document_type_parameters) attributes with generated documentation
977/// comments. It also resolves `Self` and `Self::AssocType` references to their concrete
978/// types based on the module's projection map.
979///
980/// ### Attributes
981///
982/// The macro supports several documentation-specific attributes for configuration:
983///
984/// * `#[document_default]`: (Used inside `impl` or `impl_kind!`) Marks an associated type as the
985///   default to use when resolving bare `Self` references.
986/// * `#[document_use = "AssocName"]`: (Used on `impl` or `fn`) Explicitly specifies which
987///   associated type definition to use for resolution within that scope.
988///
989/// ### Validation
990///
991/// By default, `document_module` validates that impl blocks and methods have appropriate
992/// documentation attributes and emits compile-time warnings for missing documentation.
993///
994/// To disable validation, use `#[document_module(no_validation)]`.
995///
996/// #### Validation Rules
997///
998/// An impl block or trait definition should have:
999/// * `#[document_type_parameters]` if it has type parameters
1000/// * `#[document_parameters]` if it contains methods with receiver parameters (self, &self, &mut self)
1001///
1002/// A method should have:
1003/// * `#[document_signature]` - always recommended for documenting the Hindley-Milner signature
1004/// * `#[document_type_parameters]` if it has type parameters
1005/// * `#[document_parameters]` if it has non-receiver parameters
1006/// * `#[document_returns]` if it has a return type
1007/// * `#[document_examples]` - always recommended
1008///
1009/// A free function should have:
1010/// * `#[document_examples]` - always recommended
1011///
1012/// Documentation attributes must not be duplicated and must appear in canonical order:
1013/// `#[document_signature]` -> `#[document_type_parameters]` -> `#[document_parameters]` ->
1014/// `#[document_returns]` -> `#[document_examples]`.
1015///
1016/// Additionally, a lint warns when a named generic type parameter could be replaced with
1017/// `impl Trait` (i.e., it has trait bounds, appears in exactly one parameter position, does
1018/// not appear in the return type, and is not cross-referenced by other type parameters).
1019/// This lint skips trait implementations. Suppress it on individual functions or methods
1020/// with `#[allow_named_generics]`.
1021///
1022/// #### Examples of Validation
1023///
1024/// ```ignore
1025/// // This will emit warnings:
1026/// #[fp_macros::document_module]
1027/// mod inner {
1028///     pub struct MyType;
1029///
1030///     // WARNING: Impl block contains methods with receiver parameters
1031///     // but no #[document_parameters] attribute
1032///     impl MyType {
1033///         // WARNING: Method should have #[document_signature] attribute
1034///         // WARNING: Method has parameters but no #[document_parameters] attribute
1035///         // WARNING: Method has a return type but no #[document_returns] attribute
1036///         // WARNING: Method should have a #[document_examples] attribute
1037///         pub fn process(&self, x: i32) -> i32 { x }
1038///     }
1039/// }
1040/// ```
1041///
1042/// ```ignore
1043/// // Properly documented (no warnings):
1044/// #[fp_macros::document_module]
1045/// mod inner {
1046///     pub struct MyType;
1047///
1048///     #[document_parameters("The MyType instance")]
1049///     impl MyType {
1050///         #[document_signature]
1051///         #[document_parameters("The input value")]
1052///         #[document_returns("The input value unchanged.")]
1053///         #[document_examples]
1054///         ///
1055///         /// ```
1056///         /// # use my_crate::MyType;
1057///         /// let t = MyType;
1058///         /// assert_eq!(t.process(42), 42);
1059///         /// ```
1060///         pub fn process(&self, x: i32) -> i32 { x }
1061///     }
1062/// }
1063/// ```
1064///
1065/// ```ignore
1066/// // Disable validation to suppress warnings:
1067/// #[fp_macros::document_module(no_validation)]
1068/// mod inner {
1069///     // ... undocumented code won't produce warnings ...
1070/// }
1071/// ```
1072///
1073/// ### Hierarchical Configuration
1074///
1075/// When resolving the concrete type of `Self`, the macro follows this precedence:
1076///
1077/// 1. **Method Override**: `#[document_use = "AssocName"]` on the method.
1078/// 2. **Impl Block Override**: `#[document_use = "AssocName"]` on the `impl` block.
1079/// 3. **(Type, Trait)-Scoped Default**: `#[document_default]` on the associated type definition
1080///    in a trait `impl` block.
1081/// 4. **Module Default**: `#[document_default]` on the associated type definition in `impl_kind!`.
1082///
1083/// ### Examples
1084///
1085/// ```ignore
1086/// // Invocation
1087/// #[fp_macros::document_module]
1088/// mod inner {
1089///     use super::*;
1090///
1091///     impl_kind! {
1092///         for MyBrand {
1093///             #[document_default]
1094///             type Of<'a, T: 'a>: 'a = MyType<T>;
1095///         }
1096///     }
1097///
1098///     impl Functor for MyBrand {
1099///         #[document_signature]
1100///         fn map<'a, A: 'a, B: 'a, Func>(
1101///             f: Func,
1102///             fa: Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, A>),
1103///         ) -> Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, B>)
1104///         where
1105///             Func: Fn(A) -> B + 'a
1106///         {
1107///             todo!()
1108///         }
1109///     }
1110/// }
1111/// pub use inner::*;
1112///
1113/// // Expanded code
1114/// mod inner {
1115///     use super::*;
1116///
1117///     // ... generated Kind implementations ...
1118///
1119///     impl Functor for MyBrand {
1120///         /// ### Type Signature
1121///         /// `forall a b. (a -> b, MyType a) -> MyType b`
1122///         fn map<'a, A: 'a, B: 'a, Func>(
1123///             f: Func,
1124///             fa: Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, A>),
1125///         ) -> Apply!(<Self as Kind!(type Of<'a, T: 'a>: 'a;)>::Of<'a, B>)
1126///         where
1127///             Func: Fn(A) -> B + 'a
1128///         {
1129///             todo!()
1130///         }
1131///     }
1132/// }
1133/// pub use inner::*;
1134/// ```
1135#[proc_macro_attribute]
1136pub fn document_module(
1137	attr: TokenStream,
1138	item: TokenStream,
1139) -> TokenStream {
1140	match document_module_worker(attr.into(), item.into()) {
1141		Ok(tokens) => tokens.into(),
1142		Err(e) => e.to_compile_error().into(),
1143	}
1144}
1145
1146/// Monadic do-notation.
1147///
1148/// Desugars flat monadic syntax into nested `bind` calls, matching
1149/// Haskell/PureScript `do` notation. Supports both explicit-brand and
1150/// inferred-brand modes.
1151///
1152/// ### Syntax
1153///
1154/// ```ignore
1155/// // Explicit mode: brand specified, pure() rewritten automatically
1156/// m_do!(Brand {
1157///     x <- expr;            // Bind: extract value from monadic computation
1158///     y: Type <- expr;      // Typed bind: with explicit type annotation
1159///     _ <- expr;            // Discard bind: sequence, discarding the result
1160///     expr;                 // Sequence: discard result (shorthand for `_ <- expr;`)
1161///     let z = expr;         // Let binding: pure, not monadic
1162///     let w: Type = expr;   // Typed let binding
1163///     pure(z)               // pure() rewritten to pure::<Brand, _>(z)
1164/// })
1165///
1166/// // Inferred mode: brand inferred from container types
1167/// m_do!({
1168///     x <- Some(5);         // Brand inferred from Some(5) via InferableBrand
1169///     y <- Some(x + 1);
1170///     Some(x + y)           // Write concrete constructor (pure() not available)
1171/// })
1172///
1173/// // By-reference modes:
1174/// m_do!(ref Brand { ... })  // Explicit, ref dispatch
1175/// m_do!(ref { ... })        // Inferred, ref dispatch
1176/// ```
1177///
1178/// * `Brand` (optional): The monad brand type. When omitted, the brand is inferred
1179///   from container types via `InferableBrand`.
1180/// * `ref` (optional): Enables by-reference dispatch. Closures receive `&A`
1181///   instead of `A`, routing through `RefSemimonad::ref_bind`. Typed binds
1182///   use the type as-is (include `&` in the type annotation). Untyped binds
1183///   get `: &_` added automatically.
1184/// * In explicit mode, bare `pure(args)` calls are rewritten to `pure::<Brand, _>(args)`
1185///   (or `ref_pure::<Brand, _>(&args)` in ref mode).
1186/// * In inferred mode, bare `pure(args)` calls emit a `compile_error!` because
1187///   `pure` has no container argument to infer the brand from. Write concrete
1188///   constructors instead (e.g., `Some(x)` instead of `pure(x)`).
1189///
1190/// ### Statement Forms
1191///
1192/// | Syntax | Explicit expansion | Inferred expansion |
1193/// |--------|--------------------|--------------------|
1194/// | `x <- expr;` | `explicit::bind::<Brand, _, _, _, _>(expr, move \|x\| { ... })` | `bind(expr, move \|x\| { ... })` |
1195/// | `x: Type <- expr;` | Same with `\|x: Type\|` | Same with `\|x: Type\|` |
1196/// | `expr;` | `explicit::bind::<Brand, _, _, _, _>(expr, move \|_\| { ... })` | `bind(expr, move \|_\| { ... })` |
1197/// | `let x = expr;` | `{ let x = expr; ... }` | `{ let x = expr; ... }` |
1198/// | `expr` (final) | Emitted as-is | Emitted as-is |
1199///
1200/// ### Examples
1201///
1202/// ```ignore
1203/// // Inferred mode (primary API for single-brand types)
1204/// let result = m_do!({
1205///     x <- Some(5);
1206///     y <- Some(x + 1);
1207///     let z = x * y;
1208///     Some(z)
1209/// });
1210/// assert_eq!(result, Some(30));
1211///
1212/// // Expands to:
1213/// let result = bind(Some(5), move |x| {
1214///     bind(Some(x + 1), move |y| {
1215///         let z = x * y;
1216///         Some(z)
1217///     })
1218/// });
1219/// ```
1220///
1221/// ```ignore
1222/// // Explicit mode (for ambiguous types or to use pure())
1223/// let result = m_do!(VecBrand {
1224///     x <- vec![1, 2];
1225///     y <- vec![10, 20];
1226///     pure(x + y)
1227/// });
1228/// assert_eq!(result, vec![11, 21, 12, 22]);
1229///
1230/// // Expands to:
1231/// let result = explicit::bind::<VecBrand, _, _, _, _>(vec![1, 2], move |x| {
1232///     explicit::bind::<VecBrand, _, _, _, _>(vec![10, 20], move |y| {
1233///         pure::<VecBrand, _>(x + y)
1234///     })
1235/// });
1236/// ```
1237///
1238/// ### Ref mode: multi-bind limitation
1239///
1240/// In ref mode, each bind generates a `move` closure that receives `&A`.
1241/// Inner closures cannot capture references from outer binds because the
1242/// reference lifetime is scoped to the outer closure. Attempting to use a
1243/// ref-bound variable in a later bind produces a lifetime error.
1244///
1245/// **Workaround:** use `let` bindings to dereference or clone values so
1246/// they become owned and can be captured by later closures:
1247///
1248/// ```ignore
1249/// m_do!(ref LazyBrand {
1250///     x: &i32 <- lazy_a;
1251///     let x_val = *x;          // dereference into owned value
1252///     y: &i32 <- lazy_b;
1253///     pure(x_val + *y)         // x_val is owned, safe to use here
1254/// })
1255/// ```
1256///
1257/// When all binds are independent (no bind uses the result of another),
1258/// prefer [`a_do!`] instead. Applicative do-notation evaluates all
1259/// expressions independently, so there is no closure nesting and no
1260/// capture issue.
1261#[proc_macro]
1262pub fn m_do(input: TokenStream) -> TokenStream {
1263	let input = parse_macro_input!(input as DoInput);
1264	match m_do_worker(input) {
1265		Ok(tokens) => tokens.into(),
1266		Err(e) => e.to_compile_error().into(),
1267	}
1268}
1269
1270/// Applicative do-notation.
1271///
1272/// Desugars flat applicative syntax into `pure` / `map` / `lift2`-`lift5`
1273/// calls, matching PureScript `ado` notation. Unlike [`m_do!`], bindings are
1274/// independent: later bind expressions cannot reference earlier bound variables.
1275/// Supports both explicit-brand and inferred-brand modes.
1276///
1277/// ### Syntax
1278///
1279/// ```ignore
1280/// // Explicit mode
1281/// a_do!(Brand {
1282///     x <- expr;            // Bind: independent applicative computation
1283///     y: Type <- expr;      // Typed bind: with explicit type annotation
1284///     _ <- expr;            // Discard bind: compute for effect
1285///     expr;                 // Sequence: shorthand for `_ <- expr;`
1286///     let z = expr;         // Let binding: placed inside the combining closure
1287///     expr                  // Final expression: the combining body
1288/// })
1289///
1290/// // Inferred mode (brand inferred from container types)
1291/// a_do!({
1292///     x <- Some(3);
1293///     y <- Some(4);
1294///     x + y
1295/// })
1296///
1297/// // By-reference modes:
1298/// a_do!(ref Brand { ... })  // Explicit, ref dispatch
1299/// a_do!(ref { ... })        // Inferred, ref dispatch
1300/// ```
1301///
1302/// * `Brand` (optional): The applicative brand type. When omitted, the brand is
1303///   inferred from container types via `InferableBrand`.
1304/// * `ref` (optional): Enables by-reference dispatch. The combining closure
1305///   receives references (`&A`, `&B`, etc.) via `RefLift::ref_lift2`. Typed
1306///   binds use the type as-is (include `&`). Untyped binds get `: &_`.
1307/// * Bind expressions are evaluated independently (applicative, not monadic).
1308/// * `let` bindings before any `<-` are hoisted outside the combinator call.
1309/// * `let` bindings after a `<-` are placed inside the combining closure.
1310/// * In explicit mode, bare `pure(args)` calls are rewritten to `pure::<Brand, _>(args)`.
1311/// * In inferred mode, bare `pure(args)` calls emit a `compile_error!`.
1312/// * In inferred mode with 0 binds, a `compile_error!` is emitted because
1313///   `pure()` requires a brand. Write the concrete constructor directly.
1314///
1315/// ### Desugaring
1316///
1317/// | Binds | Explicit expansion | Inferred expansion |
1318/// |-------|--------------------|--------------------|
1319/// | 0 | `pure::<Brand, _>(final_expr)` | `compile_error!` |
1320/// | 1 | `explicit::map::<Brand, _, _, _, _>(\|x\| body, expr)` | `map(\|x\| body, expr)` |
1321/// | N (2-5) | `explicit::liftN::<Brand, ...>(\|x, y, ...\| body, ...)` | `liftN(\|x, y, ...\| body, ...)` |
1322///
1323/// ### Examples
1324///
1325/// ```ignore
1326/// use fp_library::functions::*;
1327/// use fp_macros::a_do;
1328///
1329/// // Inferred mode: two independent computations combined with lift2
1330/// let result = a_do!({
1331///     x <- Some(3);
1332///     y <- Some(4);
1333///     x + y
1334/// });
1335/// assert_eq!(result, Some(7));
1336///
1337/// // Expands to:
1338/// let result = lift2(|x, y| x + y, Some(3), Some(4));
1339///
1340/// // Inferred mode: single bind uses map
1341/// let result = a_do!({ x <- Some(5); x * 2 });
1342/// assert_eq!(result, Some(10));
1343///
1344/// // Expands to:
1345/// let result = map(|x| x * 2, Some(5));
1346/// ```
1347///
1348/// ```ignore
1349/// // Explicit mode: zero-bind block uses pure (requires brand)
1350/// let result: Option<i32> = a_do!(OptionBrand { 42 });
1351/// assert_eq!(result, Some(42));
1352///
1353/// // Expands to:
1354/// let result: Option<i32> = pure::<OptionBrand, _>(42);
1355///
1356/// // Explicit mode: single bind
1357/// let result = a_do!(OptionBrand { x <- Some(5); x * 2 });
1358///
1359/// // Expands to:
1360/// let result = explicit::map::<OptionBrand, _, _, _, _>(|x| x * 2, Some(5));
1361/// ```
1362#[proc_macro]
1363pub fn a_do(input: TokenStream) -> TokenStream {
1364	let input = parse_macro_input!(input as DoInput);
1365	match a_do_worker(input) {
1366		Ok(tokens) => tokens.into(),
1367		Err(e) => e.to_compile_error().into(),
1368	}
1369}
1370
1371/// Includes a markdown file with relative `.md` links rewritten to rustdoc intra-doc links.
1372///
1373/// This macro reads a markdown file at compile time (relative to `CARGO_MANIFEST_DIR`)
1374/// and rewrites same-directory `.md` links to point at `crate::docs::module_name`
1375/// submodules, making cross-document links work in rendered rustdoc output.
1376///
1377/// ### Syntax
1378///
1379/// ```ignore
1380/// #![doc = include_documentation!("docs/hkt.md")]
1381/// ```
1382///
1383/// * `path`: A string literal path to a markdown file, relative to `CARGO_MANIFEST_DIR`.
1384///
1385/// ### Generates
1386///
1387/// A string literal containing the file contents with rewritten links.
1388/// Same-directory `.md` links are converted to rustdoc intra-doc link references;
1389/// all other links are left unchanged.
1390///
1391/// ### Examples
1392///
1393/// ```ignore
1394/// // Invocation
1395/// #![doc = include_documentation!("docs/hkt.md")]
1396///
1397/// // Link rewriting:
1398/// //   [text](./foo-bar.md)  ->  [text][crate::docs::foo_bar]
1399/// //   [text](foo-bar.md)    ->  [text][crate::docs::foo_bar]
1400/// //   [text](../other.md)   ->  unchanged (contains path separator)
1401/// //   [text](https://...)   ->  unchanged (not .md)
1402/// ```
1403#[proc_macro]
1404pub fn include_documentation(input: TokenStream) -> TokenStream {
1405	match include_documentation_worker(input.into()) {
1406		Ok(tokens) => tokens.into(),
1407		Err(e) => e.to_compile_error().into(),
1408	}
1409}