mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 13:04:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			202 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //! 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,
 | |
|     ImplTraitPlaceholder,
 | |
|     Enum,
 | |
|     Variant,
 | |
|     Struct,
 | |
|     Field,
 | |
|     Union,
 | |
|     Trait,
 | |
|     TraitAlias,
 | |
|     Impl,
 | |
|     Expression,
 | |
|     Statement,
 | |
|     Arm,
 | |
|     AssocConst,
 | |
|     Method(MethodKind),
 | |
|     AssocTy,
 | |
|     ForeignFn,
 | |
|     ForeignStatic,
 | |
|     ForeignTy,
 | |
|     GenericParam(GenericParamKind),
 | |
|     MacroDef,
 | |
|     Param,
 | |
|     PatField,
 | |
|     ExprField,
 | |
| }
 | |
| 
 | |
| 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(ref opaque) => {
 | |
|                 if opaque.in_trait {
 | |
|                     Target::ImplTraitPlaceholder
 | |
|                 } else {
 | |
|                     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::ImplTraitPlaceholder => Target::ImplTraitPlaceholder,
 | |
|             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::ImplTraitPlaceholder => "opaque type in trait",
 | |
|             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",
 | |
|             Target::PatField => "pattern field",
 | |
|             Target::ExprField => "struct field",
 | |
|         }
 | |
|     }
 | |
| }
 | 
