]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_hir/src/target.rs
Rollup merge of #98204 - Kixiron:stable-unzip, r=thomcc
[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     ImplTraitPlaceholder,
40     Enum,
41     Variant,
42     Struct,
43     Field,
44     Union,
45     Trait,
46     TraitAlias,
47     Impl,
48     Expression,
49     Statement,
50     Arm,
51     AssocConst,
52     Method(MethodKind),
53     AssocTy,
54     ForeignFn,
55     ForeignStatic,
56     ForeignTy,
57     GenericParam(GenericParamKind),
58     MacroDef,
59     Param,
60     PatField,
61     ExprField,
62 }
63
64 impl Display for Target {
65     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66         write!(f, "{}", Self::name(*self))
67     }
68 }
69
70 impl Target {
71     pub fn from_item(item: &Item<'_>) -> Target {
72         match item.kind {
73             ItemKind::ExternCrate(..) => Target::ExternCrate,
74             ItemKind::Use(..) => Target::Use,
75             ItemKind::Static(..) => Target::Static,
76             ItemKind::Const(..) => Target::Const,
77             ItemKind::Fn(..) => Target::Fn,
78             ItemKind::Macro(..) => Target::MacroDef,
79             ItemKind::Mod(..) => Target::Mod,
80             ItemKind::ForeignMod { .. } => Target::ForeignMod,
81             ItemKind::GlobalAsm(..) => Target::GlobalAsm,
82             ItemKind::TyAlias(..) => Target::TyAlias,
83             ItemKind::OpaqueTy(ref opaque) => {
84                 if opaque.in_trait {
85                     Target::ImplTraitPlaceholder
86                 } else {
87                     Target::OpaqueTy
88                 }
89             }
90             ItemKind::Enum(..) => Target::Enum,
91             ItemKind::Struct(..) => Target::Struct,
92             ItemKind::Union(..) => Target::Union,
93             ItemKind::Trait(..) => Target::Trait,
94             ItemKind::TraitAlias(..) => Target::TraitAlias,
95             ItemKind::Impl { .. } => Target::Impl,
96         }
97     }
98
99     // FIXME: For now, should only be used with def_kinds from ItemIds
100     pub fn from_def_kind(def_kind: DefKind) -> Target {
101         match def_kind {
102             DefKind::ExternCrate => Target::ExternCrate,
103             DefKind::Use => Target::Use,
104             DefKind::Static(..) => Target::Static,
105             DefKind::Const => Target::Const,
106             DefKind::Fn => Target::Fn,
107             DefKind::Macro(..) => Target::MacroDef,
108             DefKind::Mod => Target::Mod,
109             DefKind::ForeignMod => Target::ForeignMod,
110             DefKind::GlobalAsm => Target::GlobalAsm,
111             DefKind::TyAlias => Target::TyAlias,
112             DefKind::OpaqueTy => Target::OpaqueTy,
113             DefKind::ImplTraitPlaceholder => Target::ImplTraitPlaceholder,
114             DefKind::Enum => Target::Enum,
115             DefKind::Struct => Target::Struct,
116             DefKind::Union => Target::Union,
117             DefKind::Trait => Target::Trait,
118             DefKind::TraitAlias => Target::TraitAlias,
119             DefKind::Impl => Target::Impl,
120             _ => panic!("impossible case reached"),
121         }
122     }
123
124     pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
125         match trait_item.kind {
126             TraitItemKind::Const(..) => Target::AssocConst,
127             TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => {
128                 Target::Method(MethodKind::Trait { body: false })
129             }
130             TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => {
131                 Target::Method(MethodKind::Trait { body: true })
132             }
133             TraitItemKind::Type(..) => Target::AssocTy,
134         }
135     }
136
137     pub fn from_foreign_item(foreign_item: &hir::ForeignItem<'_>) -> Target {
138         match foreign_item.kind {
139             hir::ForeignItemKind::Fn(..) => Target::ForeignFn,
140             hir::ForeignItemKind::Static(..) => Target::ForeignStatic,
141             hir::ForeignItemKind::Type => Target::ForeignTy,
142         }
143     }
144
145     pub fn from_generic_param(generic_param: &hir::GenericParam<'_>) -> Target {
146         match generic_param.kind {
147             hir::GenericParamKind::Type { .. } => Target::GenericParam(GenericParamKind::Type),
148             hir::GenericParamKind::Lifetime { .. } => {
149                 Target::GenericParam(GenericParamKind::Lifetime)
150             }
151             hir::GenericParamKind::Const { .. } => Target::GenericParam(GenericParamKind::Const),
152         }
153     }
154
155     pub fn name(self) -> &'static str {
156         match self {
157             Target::ExternCrate => "extern crate",
158             Target::Use => "use",
159             Target::Static => "static item",
160             Target::Const => "constant item",
161             Target::Fn => "function",
162             Target::Closure => "closure",
163             Target::Mod => "module",
164             Target::ForeignMod => "foreign module",
165             Target::GlobalAsm => "global asm",
166             Target::TyAlias => "type alias",
167             Target::OpaqueTy => "opaque type",
168             Target::ImplTraitPlaceholder => "opaque type in trait",
169             Target::Enum => "enum",
170             Target::Variant => "enum variant",
171             Target::Struct => "struct",
172             Target::Field => "struct field",
173             Target::Union => "union",
174             Target::Trait => "trait",
175             Target::TraitAlias => "trait alias",
176             Target::Impl => "implementation block",
177             Target::Expression => "expression",
178             Target::Statement => "statement",
179             Target::Arm => "match arm",
180             Target::AssocConst => "associated const",
181             Target::Method(kind) => match kind {
182                 MethodKind::Inherent => "inherent method",
183                 MethodKind::Trait { body: false } => "required trait method",
184                 MethodKind::Trait { body: true } => "provided trait method",
185             },
186             Target::AssocTy => "associated type",
187             Target::ForeignFn => "foreign function",
188             Target::ForeignStatic => "foreign static item",
189             Target::ForeignTy => "foreign type",
190             Target::GenericParam(kind) => match kind {
191                 GenericParamKind::Type => "type parameter",
192                 GenericParamKind::Lifetime => "lifetime parameter",
193                 GenericParamKind::Const => "const parameter",
194             },
195             Target::MacroDef => "macro def",
196             Target::Param => "function param",
197             Target::PatField => "pattern field",
198             Target::ExprField => "struct field",
199         }
200     }
201 }