summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_hir/src/target.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir/src/target.rs')
-rw-r--r--compiler/rustc_hir/src/target.rs188
1 files changed, 188 insertions, 0 deletions
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
new file mode 100644
index 000000000..6236dea10
--- /dev/null
+++ b/compiler/rustc_hir/src/target.rs
@@ -0,0 +1,188 @@
+//! This module implements some validity checks for attributes.
+//! In particular it verifies that `#[inline]` and `#[repr]` attributes are
+//! attached to items that actually support them and if there are
+//! conflicts between multiple such attributes attached to the same
+//! item.
+
+use crate::hir;
+use crate::{Item, ItemKind, TraitItem, TraitItemKind};
+
+use crate::def::DefKind;
+use std::fmt::{self, Display};
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum GenericParamKind {
+ Type,
+ Lifetime,
+ Const,
+}
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum MethodKind {
+ Trait { body: bool },
+ Inherent,
+}
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub enum Target {
+ ExternCrate,
+ Use,
+ Static,
+ Const,
+ Fn,
+ Closure,
+ Mod,
+ ForeignMod,
+ GlobalAsm,
+ TyAlias,
+ OpaqueTy,
+ Enum,
+ Variant,
+ Struct,
+ Field,
+ Union,
+ Trait,
+ TraitAlias,
+ Impl,
+ Expression,
+ Statement,
+ Arm,
+ AssocConst,
+ Method(MethodKind),
+ AssocTy,
+ ForeignFn,
+ ForeignStatic,
+ ForeignTy,
+ GenericParam(GenericParamKind),
+ MacroDef,
+ Param,
+}
+
+impl Display for Target {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", Self::name(*self))
+ }
+}
+
+impl Target {
+ pub fn from_item(item: &Item<'_>) -> Target {
+ match item.kind {
+ ItemKind::ExternCrate(..) => Target::ExternCrate,
+ ItemKind::Use(..) => Target::Use,
+ ItemKind::Static(..) => Target::Static,
+ ItemKind::Const(..) => Target::Const,
+ ItemKind::Fn(..) => Target::Fn,
+ ItemKind::Macro(..) => Target::MacroDef,
+ ItemKind::Mod(..) => Target::Mod,
+ ItemKind::ForeignMod { .. } => Target::ForeignMod,
+ ItemKind::GlobalAsm(..) => Target::GlobalAsm,
+ ItemKind::TyAlias(..) => Target::TyAlias,
+ ItemKind::OpaqueTy(..) => Target::OpaqueTy,
+ ItemKind::Enum(..) => Target::Enum,
+ ItemKind::Struct(..) => Target::Struct,
+ ItemKind::Union(..) => Target::Union,
+ ItemKind::Trait(..) => Target::Trait,
+ ItemKind::TraitAlias(..) => Target::TraitAlias,
+ ItemKind::Impl { .. } => Target::Impl,
+ }
+ }
+
+ // FIXME: For now, should only be used with def_kinds from ItemIds
+ pub fn from_def_kind(def_kind: DefKind) -> Target {
+ match def_kind {
+ DefKind::ExternCrate => Target::ExternCrate,
+ DefKind::Use => Target::Use,
+ DefKind::Static(..) => Target::Static,
+ DefKind::Const => Target::Const,
+ DefKind::Fn => Target::Fn,
+ DefKind::Macro(..) => Target::MacroDef,
+ DefKind::Mod => Target::Mod,
+ DefKind::ForeignMod => Target::ForeignMod,
+ DefKind::GlobalAsm => Target::GlobalAsm,
+ DefKind::TyAlias => Target::TyAlias,
+ DefKind::OpaqueTy => Target::OpaqueTy,
+ DefKind::Enum => Target::Enum,
+ DefKind::Struct => Target::Struct,
+ DefKind::Union => Target::Union,
+ DefKind::Trait => Target::Trait,
+ DefKind::TraitAlias => Target::TraitAlias,
+ DefKind::Impl => Target::Impl,
+ _ => panic!("impossible case reached"),
+ }
+ }
+
+ pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target {
+ match trait_item.kind {
+ TraitItemKind::Const(..) => Target::AssocConst,
+ TraitItemKind::Fn(_, hir::TraitFn::Required(_)) => {
+ Target::Method(MethodKind::Trait { body: false })
+ }
+ TraitItemKind::Fn(_, hir::TraitFn::Provided(_)) => {
+ Target::Method(MethodKind::Trait { body: true })
+ }
+ TraitItemKind::Type(..) => Target::AssocTy,
+ }
+ }
+
+ pub fn from_foreign_item(foreign_item: &hir::ForeignItem<'_>) -> Target {
+ match foreign_item.kind {
+ hir::ForeignItemKind::Fn(..) => Target::ForeignFn,
+ hir::ForeignItemKind::Static(..) => Target::ForeignStatic,
+ hir::ForeignItemKind::Type => Target::ForeignTy,
+ }
+ }
+
+ pub fn from_generic_param(generic_param: &hir::GenericParam<'_>) -> Target {
+ match generic_param.kind {
+ hir::GenericParamKind::Type { .. } => Target::GenericParam(GenericParamKind::Type),
+ hir::GenericParamKind::Lifetime { .. } => {
+ Target::GenericParam(GenericParamKind::Lifetime)
+ }
+ hir::GenericParamKind::Const { .. } => Target::GenericParam(GenericParamKind::Const),
+ }
+ }
+
+ pub fn name(self) -> &'static str {
+ match self {
+ Target::ExternCrate => "extern crate",
+ Target::Use => "use",
+ Target::Static => "static item",
+ Target::Const => "constant item",
+ Target::Fn => "function",
+ Target::Closure => "closure",
+ Target::Mod => "module",
+ Target::ForeignMod => "foreign module",
+ Target::GlobalAsm => "global asm",
+ Target::TyAlias => "type alias",
+ Target::OpaqueTy => "opaque type",
+ Target::Enum => "enum",
+ Target::Variant => "enum variant",
+ Target::Struct => "struct",
+ Target::Field => "struct field",
+ Target::Union => "union",
+ Target::Trait => "trait",
+ Target::TraitAlias => "trait alias",
+ Target::Impl => "implementation block",
+ Target::Expression => "expression",
+ Target::Statement => "statement",
+ Target::Arm => "match arm",
+ Target::AssocConst => "associated const",
+ Target::Method(kind) => match kind {
+ MethodKind::Inherent => "inherent method",
+ MethodKind::Trait { body: false } => "required trait method",
+ MethodKind::Trait { body: true } => "provided trait method",
+ },
+ Target::AssocTy => "associated type",
+ Target::ForeignFn => "foreign function",
+ Target::ForeignStatic => "foreign static item",
+ Target::ForeignTy => "foreign type",
+ Target::GenericParam(kind) => match kind {
+ GenericParamKind::Type => "type parameter",
+ GenericParamKind::Lifetime => "lifetime parameter",
+ GenericParamKind::Const => "const parameter",
+ },
+ Target::MacroDef => "macro def",
+ Target::Param => "function param",
+ }
+ }
+}