rustc_attr_ir/lib.rs
1//! Data structures for representing parsed attributes in the Rust compiler.
2//!
3//! For detailed documentation about attribute processing,
4//! see [rustc_attr_parsing](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_attr_parsing/index.html).
5
6// tidy-alphabetical-start
7#![feature(const_default)]
8#![feature(const_trait_impl)]
9#![feature(default_field_values)]
10#![feature(derive_const)]
11#![feature(exhaustive_patterns)]
12#![feature(variant_count)]
13#![recursion_limit = "256"]
14// tidy-alphabetical-end
15
16pub use attr::*;
17pub use data_structures::*;
18pub use encode_cross_crate::EncodeCrossCrate;
19pub use lang_items::*;
20pub use pretty_printing::PrintAttribute;
21pub use stability::*;
22
23// FIXME remove pub on some of these modules? It's fairly inconsistent.
24mod attr;
25mod canonical_symbols;
26mod data_structures;
27pub mod diagnostic;
28pub mod diagnostic_items;
29mod encode_cross_crate;
30pub mod lang_items;
31mod pretty_printing;
32mod stability;
33pub mod target;
34pub mod weak_lang_items;
35
36/// A trait for types that can provide a list of attributes given a `TyCtxt`.
37///
38/// It allows `find_attr!` to accept either a `DefId`, `LocalDefId`, `OwnerId`, or `HirId`.
39/// It is defined here with a generic `Tcx` because `rustc_hir` can't depend on `rustc_middle`.
40/// The concrete implementations are in `rustc_middle`.
41pub trait HasAttrs<'tcx, Tcx> {
42 fn get_attrs(self, tcx: &Tcx) -> &'tcx [crate::attr::Attribute];
43}
44
45/// Finds attributes in sequences of attributes by pattern matching.
46///
47/// A little like `matches` but for attributes.
48///
49/// ```rust,ignore (illustrative)
50/// // finds the repr attribute
51/// if let Some(r) = find_attr!(attrs, AttributeKind::Repr(r) => r) {
52///
53/// }
54///
55/// // checks if one has matched
56/// if find_attr!(attrs, AttributeKind::Repr(_)) {
57///
58/// }
59/// ```
60///
61/// Often this requires you to first end up with a list of attributes.
62/// Often these are available through the `tcx`.
63///
64/// As a convenience, this macro can do that for you!
65///
66/// Instead of providing an attribute list, provide the `tcx` and an id
67/// (a `DefId`, `LocalDefId`, `OwnerId` or `HirId`).
68///
69/// ```rust,ignore (illustrative)
70/// find_attr!(tcx, def_id, <pattern>)
71/// find_attr!(tcx, hir_id, <pattern>)
72/// ```
73///
74/// Another common case is finding attributes applied to the root of the current crate.
75/// For that, use the shortcut:
76///
77/// ```rust, ignore (illustrative)
78/// find_attr!(tcx, crate, <pattern>)
79/// ```
80#[macro_export]
81macro_rules! find_attr {
82 ($tcx: expr, crate, $pattern: pat $(if $guard: expr)?) => {
83 $crate::find_attr!($tcx, crate, $pattern $(if $guard)? => ()).is_some()
84 };
85 ($tcx: expr, crate, $pattern: pat $(if $guard: expr)? => $e: expr) => {
86 $crate::find_attr!($tcx.hir_krate_attrs(), $pattern $(if $guard)? => $e)
87 };
88
89 ($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)?) => {
90 $crate::find_attr!($tcx, $id, $pattern $(if $guard)? => ()).is_some()
91 };
92 ($tcx: expr, $id: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
93 $crate::find_attr!(
94 $crate::HasAttrs::get_attrs($id, &$tcx),
95 $pattern $(if $guard)? => $e
96 )
97 }};
98
99
100 ($attributes_list: expr, $pattern: pat $(if $guard: expr)?) => {{
101 $crate::find_attr!($attributes_list, $pattern $(if $guard)? => ()).is_some()
102 }};
103
104 ($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
105 'done: {
106 for i in $attributes_list {
107 #[allow(unused_imports)]
108 use $crate::AttributeKind::*;
109 let i: &$crate::Attribute = i;
110 match i {
111 $crate::Attribute::Parsed($pattern) $(if $guard)? => {
112 break 'done Some($e);
113 }
114 $crate::Attribute::Unparsed(..) => {}
115 // In lint emitting, there's a specific exception for this warning.
116 // It's not usually emitted from inside macros from other crates
117 // (see https://github.com/rust-lang/rust/issues/110613)
118 // But this one is!
119 #[deny(unreachable_patterns)]
120 _ => {}
121 }
122 }
123
124 None
125 }
126 }};
127}