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
//! [`zoet`](https://docs.rs/zoet/)'s proc-macro implementation. See that crate for documentation,
//! and do not use this crate directly.
/* Firstly, if we have the "clippy-insane" feature and a dev build -- it's assumed that a release
* build has taken the diagnostics into account -- we turn on far too many warnings. */
#![cfg_attr(
all(feature = "clippy-insane", debug_assertions),
warn(
/* Turn the "allow" lints listed by `rustc -W help` ["rustc 1.77.1 (7cf61ebde 2024-03-27)"]
* into warn lints: */
absolute_paths_not_starting_with_crate, box_pointers, deprecated_in_future,
elided_lifetimes_in_paths, explicit_outlives_requirements, ffi_unwind_calls,
keyword_idents_2018, keyword_idents_2024, let_underscore_drop, macro_use_extern_crate,
meta_variable_misuse, missing_abi, missing_copy_implementations,
missing_debug_implementations, missing_docs, non_ascii_idents, non_local_definitions,
redundant_lifetimes, 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,
unit_bindings, unnameable_types, unreachable_pub, unsafe_code, unsafe_op_in_unsafe_fn,
unstable_features, unused_crate_dependencies, unused_extern_crates, unused_import_braces,
unused_lifetimes, unused_macro_rules, unused_qualifications, unused_results,
variant_size_differences,
//// stable compiler claims this is unstable, but unstable compiler claims it doesn't exist.
// dereferencing_mut_binding,
/* Ditto for clippy lint categories (see https://github.com/rust-lang/rust-clippy): */
clippy::all, clippy::nursery, clippy::pedantic, clippy::restriction,
// clippy::cargo,
),
/* Sometimes there are lints listed in the stable compiler's -W help output which are actually
* nightly-only. If there are any, they get listed here instead of above. */
cfg_attr(
feature = "nightly",
feature(
multiple_supertrait_upcastable,
must_not_suspend,
non_exhaustive_omitted_patterns_lint,
strict_provenance,
),
warn(
fuzzy_provenance_casts,
lossy_provenance_casts,
multiple_supertrait_upcastable,
must_not_suspend,
non_exhaustive_omitted_patterns,
)
),
/* Now go back and turn back off any lints which turned out to be too noisy or annoying. In
* particular, clippy::all and clippy::restriction are "blanket" lints which turn on a lot of
* things, not all of which are useful. */
allow(
clippy::blanket_clippy_restriction_lints,
/* Turn off individual noisy/buggy lints enabled by broader categories above: */
box_pointers, //// obsolete/don't care
clippy::allow_attributes, //// the recommended "expect" does not have the desired behaviour
clippy::implicit_return, //// not idiomatic Rust
clippy::min_ident_chars, //// single character idents are okay
clippy::missing_docs_in_private_items, //// don't care
clippy::needless_borrowed_reference, //// can't decide if this is good or bad
clippy::option_if_let_else, //// `.map_or{_else}` is not the same thing.
clippy::pub_with_shorthand, //// demands `pub(in crate)` but rustfmt disagrees
clippy::question_mark_used, ////
clippy::redundant_pub_crate, //// conflicts with unreachable_pub
clippy::ref_patterns, ////
clippy::shadow_reuse, //// e.g. `let foo = bar(foo)`
clippy::single_call_fn, //// What am I expected to do with this information?
clippy::single_char_lifetime_names, ////
clippy::std_instead_of_alloc, //// don't care
clippy::std_instead_of_core, //// `proc_macro_error` again; also don't care
clippy::wildcard_enum_match_arm, //// excessively pedantic
elided_lifetimes_in_paths, //// demands adding <'_> noise
non_exhaustive_omitted_patterns, //// TODO: Sort of useful but loads of noise.
reason = "can't see the wood for the trees"
))]
/* Any nightly-only features we actually want. This should be relatively small because we want the
* crate to run on stable, and so nightly-only features can only be used for enhancement, such as
* better error messages during development. */
// #![cfg_attr(
// feature = "nightly",
// // TODO: #[deny(internal_features)] is now the default, which forbids rustc_attrs. Should we
// // take the hint and find some other way to achieve our ends than rustc_attrs?
// allow(unstable_features, internal_features),
// feature(negative_impls, rustc_attrs),
// feature(doc_auto_cfg, doc_cfg, doc_notable_trait)
// )]
#![cfg_attr(test, feature(test))]
//#![no_std]
#![forbid(unsafe_code)]
macro_rules! diagnostic_error {
($SPAN:expr, $($REST:tt)+) => {
::proc_macro_error::diagnostic!($SPAN, ::proc_macro_error::Level::Error, $($REST)+)
}
}
mod function_args;
mod self_replacer;
mod traits;
mod with_tokens;
mod zoet;
pub(crate) type Error = proc_macro_error::Diagnostic;
pub(crate) type Result<T, E = Error> = core::result::Result<T, E>;
/// 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 {
zoet::zoet(&attr.into(), &item.into()).into()
}