| //! This module lists attribute targets, with conversions from other types. |
| |
| use std::fmt::{self, Display}; |
| |
| pub use rustc_ast::visit::AssocCtxt; |
| use rustc_ast::{AssocItemKind, ForeignItemKind, ast}; |
| use rustc_macros::StableHash; |
| |
| #[derive(Copy, Clone, PartialEq, Debug, Eq, StableHash)] |
| pub enum GenericParamKind { |
| Type, |
| Lifetime, |
| Const, |
| } |
| |
| #[derive(Copy, Clone, PartialEq, Debug, Eq, StableHash)] |
| 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, StableHash)] |
| 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(AssocCtxt), |
| Method(MethodKind), |
| AssocTy(AssocCtxt), |
| ForeignFn, |
| ForeignStatic, |
| ForeignTy, |
| GenericParam { kind: GenericParamKind, has_default: bool }, |
| MacroDef, |
| Param, |
| PatField, |
| ExprField, |
| WherePredicate, |
| MacroCall, |
| Crate, |
| Delegation { mac: bool }, |
| ForLoop, |
| While, |
| Loop, |
| Break, |
| } |
| |
| 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 { .. } |
| | Target::Loop |
| | Target::While |
| | Target::ForLoop |
| | Target::Break => false, |
| } |
| } |
| 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 }, |
| ast::ItemKind::TestBinderConstraints(..) => Target::MacroCall, |
| } |
| } |
| |
| 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_assoc_item_kind(kind: &ast::AssocItemKind, assoc_ctxt: AssocCtxt) -> Target { |
| match kind { |
| AssocItemKind::Const(_) => Target::AssocConst(assoc_ctxt), |
| 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(assoc_ctxt), |
| 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), |
| ast::ExprKind::ForLoop { .. } => Self::ForLoop, |
| ast::ExprKind::Loop(..) => Self::Loop, |
| ast::ExprKind::While(..) => Self::While, |
| ast::ExprKind::Break(..) => Self::Break, |
| _ => 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", |
| Target::Loop => "loop", |
| Target::ForLoop => "for loop", |
| Target::While => "while loop", |
| Target::Break => "break expression", |
| } |
| } |
| |
| 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", |
| Target::ForLoop => "for loops", |
| Target::Loop => "loops", |
| Target::While => "while loops", |
| Target::Break => "break expressions", |
| } |
| } |
| } |