From f0a89914692b0c7c237d4d6a688c399ee3705742 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Jan 2020 17:13:28 +0100 Subject: [PATCH 1/5] Move check_attr.rs to librustc_passes. --- src/{librustc/hir => librustc_passes}/check_attr.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{librustc/hir => librustc_passes}/check_attr.rs (100%) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc_passes/check_attr.rs similarity index 100% rename from src/librustc/hir/check_attr.rs rename to src/librustc_passes/check_attr.rs From 1b7e79a9bc68e09cbe04ed160b2e7769753991eb Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Jan 2020 17:27:30 +0100 Subject: [PATCH 2/5] Move check_mod_attr query in librustc_passes. --- src/librustc/hir/check_attr.rs | 125 +++++++++++++++++++++++++++++ src/librustc/hir/mod.rs | 1 - src/librustc_passes/check_attr.rs | 126 ++---------------------------- src/librustc_passes/lib.rs | 2 + 4 files changed, 135 insertions(+), 119 deletions(-) create mode 100644 src/librustc/hir/check_attr.rs diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs new file mode 100644 index 00000000000..db5e31981c0 --- /dev/null +++ b/src/librustc/hir/check_attr.rs @@ -0,0 +1,125 @@ +//! 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 rustc_hir as hir; +use rustc_hir::{Item, ItemKind, TraitItem, TraitItemKind}; + +use std::fmt::{self, Display}; + +#[derive(Copy, Clone, PartialEq)] +pub enum MethodKind { + Trait { body: bool }, + Inherent, +} + +#[derive(Copy, Clone, PartialEq)] +pub enum Target { + ExternCrate, + Use, + Static, + Const, + Fn, + Closure, + Mod, + ForeignMod, + GlobalAsm, + TyAlias, + OpaqueTy, + Enum, + Struct, + Union, + Trait, + TraitAlias, + Impl, + Expression, + Statement, + AssocConst, + Method(MethodKind), + AssocTy, + ForeignFn, + ForeignStatic, + ForeignTy, +} + +impl Display for Target { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "{}", + 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::Struct => "struct", + Target::Union => "union", + Target::Trait => "trait", + Target::TraitAlias => "trait alias", + Target::Impl => "item", + Target::Expression => "expression", + Target::Statement => "statement", + Target::AssocConst => "associated const", + Target::Method(_) => "method", + Target::AssocTy => "associated type", + Target::ForeignFn => "foreign function", + Target::ForeignStatic => "foreign static item", + Target::ForeignTy => "foreign type", + } + ) + } +} + +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::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, + } + } + + pub fn from_trait_item(trait_item: &TraitItem<'_>) -> Target { + match trait_item.kind { + TraitItemKind::Const(..) => Target::AssocConst, + TraitItemKind::Method(_, hir::TraitMethod::Required(_)) => { + Target::Method(MethodKind::Trait { body: false }) + } + TraitItemKind::Method(_, hir::TraitMethod::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, + } + } +} diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 97c14dd7e00..9f4d04a4978 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -10,7 +10,6 @@ pub mod upvars; use crate::ty::query::Providers; pub fn provide(providers: &mut Providers<'_>) { - check_attr::provide(providers); map::provide(providers); upvars::provide(providers); } diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index 03fa426460d..b5425e8b351 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -4,138 +4,28 @@ //! conflicts between multiple such attributes attached to the same //! item. -use crate::hir::map::Map; -use crate::ty::query::Providers; -use crate::ty::TyCtxt; +use rustc::hir::check_attr::{MethodKind, Target}; +use rustc::hir::map::Map; +use rustc::ty::query::Providers; +use rustc::ty::TyCtxt; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::DUMMY_HIR_ID; -use rustc_hir::{self, HirId, Item, ItemKind, TraitItem, TraitItemKind}; +use rustc_hir::{self, HirId, Item, ItemKind, TraitItem}; use rustc_session::lint::builtin::{CONFLICTING_REPR_HINTS, UNUSED_ATTRIBUTES}; use rustc_span::symbol::sym; use rustc_span::Span; use syntax::ast::Attribute; use syntax::attr; -use std::fmt::{self, Display}; - -#[derive(Copy, Clone, PartialEq)] -pub(crate) enum MethodKind { - Trait { body: bool }, - Inherent, +pub(crate) trait TargetExt { + fn from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target; } -#[derive(Copy, Clone, PartialEq)] -pub(crate) enum Target { - ExternCrate, - Use, - Static, - Const, - Fn, - Closure, - Mod, - ForeignMod, - GlobalAsm, - TyAlias, - OpaqueTy, - Enum, - Struct, - Union, - Trait, - TraitAlias, - Impl, - Expression, - Statement, - AssocConst, - Method(MethodKind), - AssocTy, - ForeignFn, - ForeignStatic, - ForeignTy, -} - -impl Display for Target { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "{}", - 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::Struct => "struct", - Target::Union => "union", - Target::Trait => "trait", - Target::TraitAlias => "trait alias", - Target::Impl => "item", - Target::Expression => "expression", - Target::Statement => "statement", - Target::AssocConst => "associated const", - Target::Method(_) => "method", - Target::AssocTy => "associated type", - Target::ForeignFn => "foreign function", - Target::ForeignStatic => "foreign static item", - Target::ForeignTy => "foreign type", - } - ) - } -} - -impl Target { - pub(crate) 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::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, - } - } - - fn from_trait_item(trait_item: &TraitItem<'_>) -> Target { - match trait_item.kind { - TraitItemKind::Const(..) => Target::AssocConst, - TraitItemKind::Method(_, hir::TraitMethod::Required(_)) => { - Target::Method(MethodKind::Trait { body: false }) - } - TraitItemKind::Method(_, hir::TraitMethod::Provided(_)) => { - Target::Method(MethodKind::Trait { body: true }) - } - TraitItemKind::Type(..) => Target::AssocTy, - } - } - - 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, - } - } - +impl TargetExt for Target { fn from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target { match impl_item.kind { hir::ImplItemKind::Const(..) => Target::AssocConst, diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index d746f097928..5494a652bc8 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -17,6 +17,7 @@ extern crate log; use rustc::ty::query::Providers; +mod check_attr; mod check_const; pub mod dead; mod diagnostic_items; @@ -32,6 +33,7 @@ mod region; pub mod stability; pub fn provide(providers: &mut Providers<'_>) { + check_attr::provide(providers); check_const::provide(providers); diagnostic_items::provide(providers); entry::provide(providers); From 62c2c99d7d75cb35c60ff8bc3d5c876a0a820b93 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Jan 2020 17:28:12 +0100 Subject: [PATCH 3/5] Move upvars.rs to librustc_passes. --- src/{librustc/hir => librustc_passes}/upvars.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{librustc/hir => librustc_passes}/upvars.rs (100%) diff --git a/src/librustc/hir/upvars.rs b/src/librustc_passes/upvars.rs similarity index 100% rename from src/librustc/hir/upvars.rs rename to src/librustc_passes/upvars.rs From 124fd9d2a43bfadfb3f05b5a7fb46ce884357818 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Jan 2020 17:31:03 +0100 Subject: [PATCH 4/5] Move upvars query to librustc_passes. --- src/librustc/hir/mod.rs | 2 -- src/librustc_passes/lib.rs | 2 ++ src/librustc_passes/upvars.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 9f4d04a4978..6275c0aabe8 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -5,11 +5,9 @@ pub mod check_attr; pub mod exports; pub mod map; -pub mod upvars; use crate::ty::query::Providers; pub fn provide(providers: &mut Providers<'_>) { map::provide(providers); - upvars::provide(providers); } diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 5494a652bc8..4c0fd903db0 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -31,6 +31,7 @@ pub mod loops; mod reachable; mod region; pub mod stability; +mod upvars; pub fn provide(providers: &mut Providers<'_>) { check_attr::provide(providers); @@ -44,4 +45,5 @@ pub fn provide(providers: &mut Providers<'_>) { reachable::provide(providers); region::provide(providers); stability::provide(providers); + upvars::provide(providers); } diff --git a/src/librustc_passes/upvars.rs b/src/librustc_passes/upvars.rs index 4ca294f4861..a2397f27338 100644 --- a/src/librustc_passes/upvars.rs +++ b/src/librustc_passes/upvars.rs @@ -1,8 +1,8 @@ //! Upvar (closure capture) collection from cross-body HIR uses of `Res::Local`s. -use crate::hir::map::Map; -use crate::ty::query::Providers; -use crate::ty::TyCtxt; +use rustc::hir::map::Map; +use rustc::ty::query::Providers; +use rustc::ty::TyCtxt; use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_hir as hir; use rustc_hir::def::Res; From f9335e990897b9ad1f072eb0a8e7385d720538f2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 27 Jan 2020 19:37:36 +0100 Subject: [PATCH 5/5] Make Target::from_impl_item a free function. --- src/librustc_passes/check_attr.rs | 38 +++++++++++++------------------ 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/librustc_passes/check_attr.rs b/src/librustc_passes/check_attr.rs index b5425e8b351..3ff1ba3bbfc 100644 --- a/src/librustc_passes/check_attr.rs +++ b/src/librustc_passes/check_attr.rs @@ -21,29 +21,23 @@ use rustc_span::Span; use syntax::ast::Attribute; use syntax::attr; -pub(crate) trait TargetExt { - fn from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target; -} - -impl TargetExt for Target { - fn from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target { - match impl_item.kind { - hir::ImplItemKind::Const(..) => Target::AssocConst, - hir::ImplItemKind::Method(..) => { - let parent_hir_id = tcx.hir().get_parent_item(impl_item.hir_id); - let containing_item = tcx.hir().expect_item(parent_hir_id); - let containing_impl_is_for_trait = match &containing_item.kind { - hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(), - _ => bug!("parent of an ImplItem must be an Impl"), - }; - if containing_impl_is_for_trait { - Target::Method(MethodKind::Trait { body: true }) - } else { - Target::Method(MethodKind::Inherent) - } +fn target_from_impl_item<'tcx>(tcx: TyCtxt<'tcx>, impl_item: &hir::ImplItem<'_>) -> Target { + match impl_item.kind { + hir::ImplItemKind::Const(..) => Target::AssocConst, + hir::ImplItemKind::Method(..) => { + let parent_hir_id = tcx.hir().get_parent_item(impl_item.hir_id); + let containing_item = tcx.hir().expect_item(parent_hir_id); + let containing_impl_is_for_trait = match &containing_item.kind { + hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(), + _ => bug!("parent of an ImplItem must be an Impl"), + }; + if containing_impl_is_for_trait { + Target::Method(MethodKind::Trait { body: true }) + } else { + Target::Method(MethodKind::Inherent) } - hir::ImplItemKind::TyAlias(..) | hir::ImplItemKind::OpaqueTy(..) => Target::AssocTy, } + hir::ImplItemKind::TyAlias(..) | hir::ImplItemKind::OpaqueTy(..) => Target::AssocTy, } } @@ -437,7 +431,7 @@ impl Visitor<'tcx> for CheckAttrVisitor<'tcx> { } fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { - let target = Target::from_impl_item(self.tcx, impl_item); + let target = target_from_impl_item(self.tcx, impl_item); self.check_attributes(impl_item.hir_id, &impl_item.attrs, &impl_item.span, target, None); intravisit::walk_impl_item(self, impl_item) }