Expand description
§announce crate


Make a definition visible to proc macros in any crate.
A proc macro only sees the tokens it is applied to. Put #[announce] on a
struct, enum, union, trait, type alias or inline mod, and any crate can ask for
its tokens: #[announce] keeps the item and emits a macro_rules! with the
item’s name, and calling that macro passes the definition to a callback macro.
#[announce::announce]
pub trait Greet { fn hi(&self) -> &'static str; }
macro_rules! show {
(@announce_format "1" [$($list:tt)*] $($key:ident)::+ ! => [$($meta:tt)*] { $($item:tt)* } $($rest:tt)*) => {
const SHOWN: &str = stringify!($($item)*);
};
}
Greet! { [Greet!, show!] }
assert!(SHOWN.contains("trait Greet"));From another crate the call reads path::to::Greet! { [path::to::Greet!, show!] REST }.
The callback receives the definition, and REST unchanged:
show! {
@announce_format "1"
[show!]
path::to::Greet! => [META] { pub trait Greet { fn hi(&self) -> &'static str; } }
REST
}META lists what the definer attached (checks, meta entries). Callers and
callbacks need no dependency on announce.
Every call that announce makes to the next macro of a chain starts with
@announce_format "1", the version of the wire format, before [LIST]. A macro of
yours can match it to know that announce called it. A call you write by hand
(Greet! { [Greet!, show!] }) needs no prefix:
#[announce::announce]
pub trait Greet { fn hi(&self) -> &'static str; }
macro_rules! who {
// Called by announce.
(@announce_format "1" $($call:tt)*) => { const CALLER: &str = "announce"; };
// Called by hand.
($($call:tt)*) => { const CALLER: &str = "hand"; };
}
Greet! { [Greet!, who!] }
assert_eq!(CALLER, "announce");The prefix is part of the wire format. An item and a macro built with different, incompatible versions of announce stop with one error that names both versions.
§Calling a trampoline
One callback can take many definitions. The list names the trampolines, then
the callback, which runs once. A long chain may need a higher recursion_limit
(details).
path::Item! { [path::Item!, other::Def!, cb!] REST }§Features
- Works in any position: item, statement, expression, type, pattern.
- Evaluates
#[cfg]in the defining crate;crate::paths keep pointing there. - Leaves docs out of the item the callback receives (
docs = truekeeps them). - Checks at the definition, which can own attributes of their own inside the item:
#[announce(my_lib::check)]. - Metadata for consumers:
#[announce(meta = my_lib::info(k = v))]. - Types that are relative to the defining crate:
repeater. - Transformers chosen by the caller, such as
signature_only!. - A derive or attribute may own the name: rename the trampoline with
macro_name.
All options of #[announce(..)] are in the
API docs.
§Crates
| crate | use it to |
|---|---|
announce | everything below |
announce-std | announce std/core traits (announce_std::iter::Iterator!) |
In announce:
#[announce]and the traitAnnouncedefine announced items.announce::helperwrites callbacks and checks, starts chains and redirects derives.announce::machineryannounces items that your own proc macro builds.helper,machineryandtype_leakneed the featureproc-macro-api, on by default; a#![no_std]crate that only defines items usesdefault-features = false.
announce-core and announce-macros are internal; depend on announce.
Minimum Rust version: 1.57.
§Performance
Traits with S methods each, K of them passed to one callback; rustc nightly,
dev profile. Lines: color = S (darker is larger), solid = announced or one
chain, dashed = plain or K separate calls; both axes logarithmic. Details and
how to run it: bench/.
- The cost is metadata of the defining crate: about 6 KiB per definition plus copies of the item (one copy for items above about 21 trait methods). Doc comments are not recorded.
- Executables are unaffected, and calling crates stay small (12–60 KiB of
.rmetaat K = 96). [profile.dev.build-override] opt-level = 3in your workspace builds the proc macros optimized: 1,117 ms becomes 763 ms at S = 200, K = 96.
§Related crates
- macro_magic has the same core idea. announce adds continuation lists, definition-side cfg evaluation and checks, and type context handling.
- reify_types makes a definition available when compiled code runs. announce delivers it at compile time.
Re-exports§
pub use type_leak;
Modules§
- helper
- Helpers for proc-macro crates that use
announcetrampolines:announce::helper. - machinery
- What
#[announce(..)]does, as functions that another proc-macro crate can call.
Macros§
- define_
repeater - Defines the repeater trait that
#[announce(repeater = ..)]needs. - signature_
only - Transformer that strips the newest entry’s item down to signatures.
Traits§
- Announce
- Marks an announced item.
Attribute Macros§
- announce
- Makes an item readable by macros in any crate.