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
//! [`module@zoet`]'s proc-macro implementation. See that crate for documentation, and do not use
//! this crate directly.

#![cfg_attr(all(feature = "clippy-insane", debug_assertions), warn(
    //// Turn the "allow" lints listed by `rustc -W help` ["rustc 1.56.0 (09c42c458 2021-10-18)"]
    //// into warn lints:
    absolute_paths_not_starting_with_crate, box_pointers, deprecated_in_future,
    elided_lifetimes_in_paths, explicit_outlives_requirements, keyword_idents,
    macro_use_extern_crate, meta_variable_misuse, missing_abi, missing_copy_implementations,
    missing_debug_implementations, missing_docs, non_ascii_idents, noop_method_call,
    pointer_structural_match, rust_2021_incompatible_closure_captures,
    rust_2021_incompatible_or_patterns, rust_2021_prefixes_incompatible_syntax,
    rust_2021_prelude_collisions, single_use_lifetimes, trivial_casts, trivial_numeric_casts,
    unreachable_pub, unsafe_code, unsafe_op_in_unsafe_fn, unstable_features,
    unused_crate_dependencies, unused_extern_crates, unused_import_braces, unused_lifetimes,
    unused_qualifications, unused_results, variant_size_differences,

    //// Ditto for clippy lint categories (see https://github.com/rust-lang/rust-clippy):
    clippy::all, clippy::cargo, clippy::nursery, clippy::pedantic, clippy::restriction,
))]
#![allow(
    clippy::blanket_clippy_restriction_lints,
    //// turn off individual noisy/buggy lints enabled by broader categories above:
    box_pointers,                          // obsolete/don't care
    clippy::arithmetic_side_effects,       // what's a computer for?
    clippy::implicit_return,               // not idiomatic Rust
    clippy::min_ident_chars,               // we like `a`, `b`, etc.
    clippy::missing_const_for_fn,          // not relevant
    clippy::missing_docs_in_private_items, // don't care
    clippy::missing_trait_methods,         // too noisy, especially with syn's fold
    clippy::needless_borrowed_reference,   // can't decide if this is good or bad
    clippy::pub_with_shorthand,            // disagrees with rustfmt on syntax
    clippy::question_mark_used,            // not idiomatic Rust
    clippy::redundant_pub_crate,           // a bit broken/unhelpful
    clippy::ref_patterns,                  // can't decide if this is good or bad
    clippy::shadow_reuse,                  // hmm...
    clippy::shadow_same,                   // hmm...
    clippy::shadow_unrelated,              // hmm...
    clippy::single_call_fn,                // don't care
    clippy::single_char_lifetime_names,    // annoying
    clippy::std_instead_of_alloc,          // don't care
    clippy::std_instead_of_core,           // `proc_macro_error` again; also don't care
    clippy::str_to_string,                 // triggered by `proc_macro_error` macros
    clippy::uninlined_format_args,         // reasonable, but LSP has issues
    clippy::wildcard_enum_match_arm,       // don't care
    clippy::wildcard_imports,              // don't care
    elided_lifetimes_in_paths,             // adding <'_> everywhere is ugly
)]
#![forbid(unsafe_code)]

macro_rules! diagnostic_error {
    ($SPAN:expr, $($REST:tt)+) => {
        diagnostic!($SPAN, ::proc_macro_error::Level::Error, $($REST)+)
    }
}

pub(crate) mod prelude {
    pub(crate) use proc_macro_error::{
        abort, diagnostic, emit_error, emit_warning, Diagnostic, OptionExt as _, ResultExt as _,
    };
    pub(crate) type Result<T, E = Diagnostic> = core::result::Result<T, E>;
}
mod function_args;
mod self_replacer;
mod traits;
mod with_tokens;
mod zoet;

/// The `#[zoet]` macro.
#[proc_macro_error::proc_macro_error]
#[proc_macro_attribute]
pub fn zoet(
    attr: proc_macro::TokenStream, item: proc_macro::TokenStream,
) -> proc_macro::TokenStream {
    crate::zoet::zoet(&attr.into(), &item.into()).into()
}