| //! This module lists attribute targets, with conversions from other types. | |
| use std::fmt::{self, Display}; | |
| use rustc_ast::visit::AssocCtxt; | |
| use rustc_ast::{AssocItemKind, ForeignItemKind, ast}; | |
| use rustc_macros::HashStable_Generic; | |
| use crate::def::DefKind; | |
| use crate::{Item, ItemKind, TraitItem, TraitItemKind, hir}; | |
| #[derive(Copy, Clone, PartialEq, Debug, Eq, HashStable_Generic)] | |
| pub enum GenericParamKind { | |
| Type, | |
| Lifetime, | |
| Const, | |
| } | |
| #[derive(Copy, Clone, PartialEq, Debug, Eq, HashStable_Generic)] | |
| pub enum MethodKind { | |
| /// Method in a `trait Trait` block | |
| Trait { | |
| /// Whether a default is provided for this method | |
| body: bool, | |
| }, | |
| /// Method in a `impl Trait for Type` block | |
| TraitImpl, | |
| /// Method in a `impl Type` block | |
| Inherent, | |
| } | |
| #[derive(Copy, Clone, PartialEq, Debug, Eq, HashStable_Generic)] | |
| pub enum Target { | |
| ExternCrate, | |
| Use, | |
| Static, | |
| Const, | |
| Fn, | |
| Closure, | |
| Mod, | |
| ForeignMod, | |
| GlobalAsm, | |
| TyAlias, | |
| Enum, | |
| Variant, | |
| Struct, | |
| Field, | |
| Union, | |
| Trait, | |
| TraitAlias, | |
| Impl { of_trait: bool }, | |
| Expression, | |
| Statement, | |
| Arm, | |
| AssocConst, | |
| Method(MethodKind), | |
| AssocTy, | |
| ForeignFn, | |
| ForeignStatic, | |
| ForeignTy, | |
| GenericParam { kind: GenericParamKind, has_default: bool }, | |
| MacroDef, | |
| Param, | |
| PatField, | |
| ExprField, | |
| WherePredicate, | |
| MacroCall, | |
| Crate, | |
| Delegation { mac: bool }, | |
| } | |
| impl Display for Target { | |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
| write!(f, "{}", Self::name(*self)) | |
| } | |
| } | |
| rustc_error_messages::into_diag_arg_using_display!(Target); | |
| impl Target { | |
| pub fn is_associated_item(self) -> bool { | |
| match self { | |
| Target::AssocConst | Target::AssocTy | Target::Method(_) => true, | |
| Target::ExternCrate | |
| | Target::Use | |
| | Target::Static | |
| | Target::Const | |
| | Target::Fn | |
| | Target::Closure | |
| | Target::Mod | |
| | Target::ForeignMod | |
| | Target::GlobalAsm | |
| | Target::TyAlias | |
| | Target::Enum | |
| | Target::Variant | |
| | Target::Struct | |
| | Target::Field | |
| | Target::Union | |
| | Target::Trait | |
| | Target::TraitAlias | |
| | Target::Impl { .. } | |
| | Target::Expression | |
| | Target::Statement | |
| | Target::Arm | |
| | Target::ForeignFn | |
| | Target::ForeignStatic | |
| | Target::ForeignTy | |
| | Target::GenericParam { .. } | |
| | Target::MacroDef | |
| | Target::Param | |
| | Target::PatField | |
| | Target::ExprField | |
| | Target::MacroCall | |
| | Target::Crate | |
| | Target::WherePredicate | |
| | Target::Delegation { .. } => false, | |
| } | |
| } | |
| 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::Enum(..) => Target::Enum, | |
| ItemKind::Struct(..) => Target::Struct, | |
| ItemKind::Union(..) => Target::Union, | |
| ItemKind::Trait(..) => Target::Trait, | |
| ItemKind::TraitAlias(..) => Target::TraitAlias, | |
| ItemKind::Impl(imp_) => Target::Impl { of_trait: imp_.of_trait.is_some() }, | |
| } | |
| } | |
| // 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::Enum => Target::Enum, | |
| DefKind::Struct => Target::Struct, | |
| DefKind::Union => Target::Union, | |
| DefKind::Trait => Target::Trait, | |
| DefKind::TraitAlias => Target::TraitAlias, | |
| DefKind::Impl { of_trait } => Target::Impl { of_trait }, | |
| _ => panic!("impossible case reached"), | |
| } | |
| } | |
| pub fn from_ast_item(item: &ast::Item) -> Target { | |
| match item.kind { | |
| ast::ItemKind::ExternCrate(..) => Target::ExternCrate, | |
| ast::ItemKind::Use(..) => Target::Use, | |
| ast::ItemKind::Static { .. } => Target::Static, | |
| ast::ItemKind::Const(..) => Target::Const, | |
| ast::ItemKind::ConstBlock(..) => Target::Const, | |
| ast::ItemKind::Fn { .. } => Target::Fn, | |
| ast::ItemKind::Mod(..) => Target::Mod, | |
| ast::ItemKind::ForeignMod { .. } => Target::ForeignMod, | |
| ast::ItemKind::GlobalAsm { .. } => Target::GlobalAsm, | |
| ast::ItemKind::TyAlias(..) => Target::TyAlias, | |
| ast::ItemKind::Enum(..) => Target::Enum, | |
| ast::ItemKind::Struct(..) => Target::Struct, | |
| ast::ItemKind::Union(..) => Target::Union, | |
| ast::ItemKind::Trait(..) => Target::Trait, | |
| ast::ItemKind::TraitAlias(..) => Target::TraitAlias, | |
| ast::ItemKind::Impl(ref i) => Target::Impl { of_trait: i.of_trait.is_some() }, | |
| ast::ItemKind::MacCall(..) => Target::MacroCall, | |
| ast::ItemKind::MacroDef(..) => Target::MacroDef, | |
| ast::ItemKind::Delegation(..) => Target::Delegation { mac: false }, | |
| ast::ItemKind::DelegationMac(..) => Target::Delegation { mac: true }, | |
| } | |
| } | |
| pub fn from_foreign_item_kind(kind: &ast::ForeignItemKind) -> Target { | |
| match kind { | |
| ForeignItemKind::Static(_) => Target::ForeignStatic, | |
| ForeignItemKind::Fn(_) => Target::ForeignFn, | |
| ForeignItemKind::TyAlias(_) => Target::ForeignTy, | |
| ForeignItemKind::MacCall(_) => Target::MacroCall, | |
| } | |
| } | |
| 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 { default, .. } => Target::GenericParam { | |
| kind: GenericParamKind::Type, | |
| has_default: default.is_some(), | |
| }, | |
| hir::GenericParamKind::Lifetime { .. } => { | |
| Target::GenericParam { kind: GenericParamKind::Lifetime, has_default: false } | |
| } | |
| hir::GenericParamKind::Const { default, .. } => Target::GenericParam { | |
| kind: GenericParamKind::Const, | |
| has_default: default.is_some(), | |
| }, | |
| } | |
| } | |
| pub fn from_assoc_item_kind(kind: &ast::AssocItemKind, assoc_ctxt: AssocCtxt) -> Target { | |
| match kind { | |
| AssocItemKind::Const(_) => Target::AssocConst, | |
| AssocItemKind::Fn(f) => Target::Method(match assoc_ctxt { | |
| AssocCtxt::Trait => MethodKind::Trait { body: f.body.is_some() }, | |
| AssocCtxt::Impl { of_trait, .. } => { | |
| if of_trait { | |
| MethodKind::TraitImpl | |
| } else { | |
| MethodKind::Inherent | |
| } | |
| } | |
| }), | |
| AssocItemKind::Type(_) => Target::AssocTy, | |
| AssocItemKind::Delegation(_) => Target::Delegation { mac: false }, | |
| AssocItemKind::DelegationMac(_) => Target::Delegation { mac: true }, | |
| AssocItemKind::MacCall(_) => Target::MacroCall, | |
| } | |
| } | |
| pub fn from_expr(expr: &ast::Expr) -> Self { | |
| match &expr.kind { | |
| ast::ExprKind::Closure(..) | ast::ExprKind::Gen(..) => Self::Closure, | |
| ast::ExprKind::Paren(e) => Self::from_expr(&e), | |
| _ => Self::Expression, | |
| } | |
| } | |
| pub fn name(self) -> &'static str { | |
| match self { | |
| Target::ExternCrate => "extern crate", | |
| Target::Use => "use", | |
| Target::Static => "static", | |
| Target::Const => "constant", | |
| Target::Fn => "function", | |
| Target::Closure => "closure", | |
| Target::Mod => "module", | |
| Target::ForeignMod => "foreign module", | |
| Target::GlobalAsm => "global asm", | |
| Target::TyAlias => "type alias", | |
| 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", | |
| MethodKind::TraitImpl => "trait method in an impl block", | |
| }, | |
| 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", | |
| Target::PatField => "pattern field", | |
| Target::ExprField => "struct field", | |
| Target::WherePredicate => "where predicate", | |
| Target::MacroCall => "macro call", | |
| Target::Crate => "crate", | |
| Target::Delegation { .. } => "delegation", | |
| } | |
| } | |
| pub fn plural_name(self) -> &'static str { | |
| match self { | |
| Target::ExternCrate => "extern crates", | |
| Target::Use => "use statements", | |
| Target::Static => "statics", | |
| Target::Const => "constants", | |
| Target::Fn => "functions", | |
| Target::Closure => "closures", | |
| Target::Mod => "modules", | |
| Target::ForeignMod => "foreign modules", | |
| Target::GlobalAsm => "global asms", | |
| Target::TyAlias => "type aliases", | |
| Target::Enum => "enums", | |
| Target::Variant => "enum variants", | |
| Target::Struct => "structs", | |
| Target::Field => "struct fields", | |
| Target::Union => "unions", | |
| Target::Trait => "traits", | |
| Target::TraitAlias => "trait aliases", | |
| Target::Impl { of_trait: false } => "inherent impl blocks", | |
| Target::Impl { of_trait: true } => "trait impl blocks", | |
| Target::Expression => "expressions", | |
| Target::Statement => "statements", | |
| Target::Arm => "match arms", | |
| Target::AssocConst => "associated consts", | |
| Target::Method(kind) => match kind { | |
| MethodKind::Inherent => "inherent methods", | |
| MethodKind::Trait { body: false } => "required trait methods", | |
| MethodKind::Trait { body: true } => "provided trait methods", | |
| MethodKind::TraitImpl => "trait methods in impl blocks", | |
| }, | |
| Target::AssocTy => "associated types", | |
| Target::ForeignFn => "foreign functions", | |
| Target::ForeignStatic => "foreign statics", | |
| Target::ForeignTy => "foreign types", | |
| Target::GenericParam { kind, has_default: _ } => match kind { | |
| GenericParamKind::Type => "type parameters", | |
| GenericParamKind::Lifetime => "lifetime parameters", | |
| GenericParamKind::Const => "const parameters", | |
| }, | |
| Target::MacroDef => "macro defs", | |
| Target::Param => "function params", | |
| Target::PatField => "pattern fields", | |
| Target::ExprField => "struct fields", | |
| Target::WherePredicate => "where predicates", | |
| Target::MacroCall => "macro calls", | |
| Target::Crate => "crates", | |
| Target::Delegation { .. } => "delegations", | |
| } | |
| } | |
| } |