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