]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_hir/src/target.rs
Rollup merge of #96777 - JohnTitor:do-not-run-pass-save-analysis, r=Mark-Simulacrum
[rust.git] / compiler / rustc_hir / src / target.rs
1 //! This module implements some validity checks for attributes.
2 //! In particular it verifies that `#[inline]` and `#[repr]` attributes are
3 //! attached to items that actually support them and if there are
4 //! conflicts between multiple such attributes attached to the same
5 //! item.
6
7 use crate::hir;
8 use crate::{Item, ItemKind, TraitItem, TraitItemKind};
9
10 use crate::def::DefKind;
11 use std::fmt::{self, Display};
12
13 #[derive(Copy, Clone, PartialEq, Debug)]
14 pub enum GenericParamKind {
15     Type,
16     Lifetime,
17     Const,
18 }
19
20 #[derive(Copy, Clone, PartialEq, Debug)]
21 pub enum MethodKind {
22     Trait { body: bool },
23     Inherent,
24 }
25
26 #[derive(Copy, Clone, PartialEq, Debug)]
27 pub enum Target {
28     ExternCrate,
29     Use,
30     Static,
31     Const,
32     Fn,
33     Closure,
34     Mod,
35     ForeignMod,
36     GlobalAsm,
37     TyAlias,
38     OpaqueTy,
39     Enum,
40     Variant,
41     Struct,
42     Field,
43     Union,
44     Trait,
45     TraitAlias,
46     Impl,
47     Expression,
48     Statement,
49     Arm,
50     AssocConst,
51     Method(MethodKind),
52     AssocTy,
53     ForeignFn,
54     ForeignStatic,
55     ForeignTy,
56     GenericParam(GenericParamKind),
57     MacroDef,
58     Param,
59 }
60
61 impl Display for Target {
62     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63         write!(
64             f,
65             "{}",
66             match *self {
67                 Target::ExternCrate => "extern crate",
68                 Target::Use => "use",
69                 Target::Static => "static item",
70                 Target::Const => "constant item",
71                 Target::Fn => "function",
72                 Target::Closure => "closure",
73                 Target::Mod => "module",
74                 Target::ForeignMod => "foreign module",
75                 Target::GlobalAsm => "global asm",
76                 Target::TyAlias => "type alias",
77                 Target::OpaqueTy => "opaque type",
78                 Target::Enum => "enum",
79                 Target::Variant => "enum variant",
80                 Target::Struct => "struct",
81                 Target::Field => "struct field",
82                 Target::Union => "union",
83                 Target::Trait => "trait",
84                 Target::TraitAlias => "trait alias",
85                 Target::Impl => "item",
86                 Target::Expression => "expression",
87                 Target::Statement => "statement",
88                 Target::Arm => "match arm",
89                 Target::AssocConst => "associated const",
90                 Target::Method(kind) => match kind {
91                     MethodKind::Inherent => "inherent method",
92                     MethodKind::Trait { body: false } => "required trait method",
93                     MethodKind::Trait { body: true } => "provided trait method",
94                 },
95                 Target::AssocTy => "associated type",
96                 Target::ForeignFn => "foreign function",
97                 Target::ForeignStatic => "foreign static item",
98                 Target::ForeignTy => "foreign type",
99                 Target::GenericParam(kind) => match kind {
100                     GenericParamKind::Type => "type parameter",
101                     GenericParamKind::Lifetime => "lifetime parameter",
102                     GenericParamKind::Const => "const parameter",
103                 },
104                 Target::MacroDef => "macro def",
105                 Target::Param => "function param",
106             }
107         )
108     }
109 }
110
111 impl Target {
112     pub fn from_item(item: &Item<'_>) -> Target {
113         match item.kind {
114             ItemKind::ExternCrate(..) => Target::ExternCrate,
115             ItemKind::Use(..) => Target::Use,
116             ItemKind::Static(..) => Target::Static,
117             ItemKind::Const(..) => Target::Const,
118             ItemKind::Fn(..) => Target::Fn,
119             ItemKind::Macro(..) => Target::MacroDef,
120             ItemKind::Mod(..) => Target::Mod,
121             ItemKind::ForeignMod { .. } => Target::ForeignMod,
122             ItemKind::GlobalAsm(..) => Target::GlobalAsm,
123             ItemKind::TyAlias(..) => Target::TyAlias,
124             ItemKind::OpaqueTy(..) => Target::OpaqueTy,
125             ItemKind::Enum(..) => Target::Enum,
126             ItemKind::Struct(..) => Target::Struct,
127             ItemKind::Union(..) => Target::Union,
128             ItemKind::Trait(..) => Target::Trait,
129             ItemKind::TraitAlias(..) => Target::TraitAlias,
130             ItemKind::Impl { .. } => Target::Impl,
131         }
132     }
133
134     // FIXME: For now, should only be used with def_kinds from ItemIds
135     pub fn from_def_kind(def_kind: DefKind) -> Target {
136         match def_kind {
137             DefKind::ExternCrate => Target::ExternCrate,
138             DefKind::Use => Target::Use,
139             DefKind::Static(..) => Target::Static,
140             DefKind::Const => Target::Const,
141             DefKind::Fn => Target::Fn,
142             DefKind::Macro(..) => Target::MacroDef,
143             DefKind::Mod => Target::Mod,
144             DefKind::ForeignMod => Target::ForeignMod,
145             DefKind::GlobalAsm => Target::GlobalAsm,
146             DefKind::TyAlias => Target::TyAlias,
147             DefKind::OpaqueTy => Target::OpaqueTy,
148             DefKind::Enum => Target::Enum,
149             DefKind::Struct => Target::Struct,
150             DefKind::Union => Target::Union,
151             DefKind::Trait => Target::Trait,
152             DefKind::TraitAlias => Target::TraitAlias,
153             DefKind::Impl => Target::Impl,
154             _ => panic!("impossible case reached"),
155         }
156     }
157
158     pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
159         match trait_item.kind {
160             TraitItemKind::Const(..) => Target::AssocConst,
161             TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => {
162                 Target::Method(MethodKind::Trait { body: false })
163             }
164             TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => {
165                 Target::Method(MethodKind::Trait { body: true })
166             }
167             TraitItemKind::Type(..) => Target::AssocTy,
168         }
169     }
170
171     pub fn from_foreign_item(foreign_item: &hir::ForeignItem<'_>) -> Target {
172         match foreign_item.kind {
173             hir::ForeignItemKind::Fn(..) => Target::ForeignFn,
174             hir::ForeignItemKind::Static(..) => Target::ForeignStatic,
175             hir::ForeignItemKind::Type => Target::ForeignTy,
176         }
177     }
178
179     pub fn from_generic_param(generic_param: &hir::GenericParam<'_>) -> Target {
180         match generic_param.kind {
181             hir::GenericParamKind::Type { .. } => Target::GenericParam(GenericParamKind::Type),
182             hir::GenericParamKind::Lifetime { .. } => {
183                 Target::GenericParam(GenericParamKind::Lifetime)
184             }
185             hir::GenericParamKind::Const { .. } => Target::GenericParam(GenericParamKind::Const),
186         }
187     }
188 }