rustc_hir/attrs/mod.rs
1//! Data structures for representing parsed attributes in the Rust compiler.
2//! Formerly `rustc_attr_data_structures`.
3//!
4//! For detailed documentation about attribute processing,
5//! see [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html).
6
7pub use data_structures::*;
8pub use encode_cross_crate::EncodeCrossCrate;
9pub use pretty_printing::PrintAttribute;
10
11mod data_structures;
12mod encode_cross_crate;
13mod pretty_printing;
14
15/// Finds attributes in sequences of attributes by pattern matching.
16///
17/// A little like `matches` but for attributes.
18///
19/// ```rust,ignore (illustrative)
20/// // finds the repr attribute
21/// if let Some(r) = find_attr!(attrs, AttributeKind::Repr(r) => r) {
22///
23/// }
24///
25/// // checks if one has matched
26/// if find_attr!(attrs, AttributeKind::Repr(_)) {
27///
28/// }
29/// ```
30///
31/// Often this requires you to first end up with a list of attributes.
32/// Often these are available through the `tcx`.
33///
34/// As a convenience, this macro can do that for you!
35///
36/// Instead of providing an attribute list, provide the `tcx` and a `DefId`.
37///
38/// ```rust,ignore (illustrative)
39/// find_attr!(tcx, def_id, <pattern>)
40/// ```
41///
42/// Another common case is finding attributes applied to the root of the current crate.
43/// For that, use the shortcut:
44///
45/// ```rust, ignore (illustrative)
46/// find_attr!(tcx, crate, <pattern>)
47/// ```
48#[macro_export]
49macro_rules! find_attr {
50 ($tcx: expr, crate, $pattern: pat $(if $guard: expr)?) => {
51 $crate::find_attr!($tcx, crate, $pattern $(if $guard)? => ()).is_some()
52 };
53 ($tcx: expr, crate, $pattern: pat $(if $guard: expr)? => $e: expr) => {
54 $crate::find_attr!($tcx.hir_krate_attrs(), $pattern $(if $guard)? => $e)
55 };
56
57 ($tcx: expr, $def_id: expr, $pattern: pat $(if $guard: expr)?) => {
58 $crate::find_attr!($tcx, $def_id, $pattern $(if $guard)? => ()).is_some()
59 };
60 ($tcx: expr, $def_id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
61 #[allow(deprecated)] {
62 $crate::find_attr!($tcx.get_all_attrs($def_id), $pattern $(if $guard)? => $e)
63 }
64 }};
65
66
67 ($attributes_list: expr, $pattern: pat $(if $guard: expr)?) => {{
68 $crate::find_attr!($attributes_list, $pattern $(if $guard)? => ()).is_some()
69 }};
70
71 ($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
72 'done: {
73 for i in $attributes_list {
74 #[allow(unused_imports)]
75 use rustc_hir::attrs::AttributeKind::*;
76 let i: &rustc_hir::Attribute = i;
77 match i {
78 rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => {
79 break 'done Some($e);
80 }
81 rustc_hir::Attribute::Unparsed(..) => {}
82 // In lint emitting, there's a specific exception for this warning.
83 // It's not usually emitted from inside macros from other crates
84 // (see https://github.com/rust-lang/rust/issues/110613)
85 // But this one is!
86 #[deny(unreachable_patterns)]
87 _ => {}
88 }
89 }
90
91 None
92 }
93 }};
94}