diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs index 70d9db4a84ba1..96dd00ec5cff1 100644 --- a/compiler/rustc_hir/src/target.rs +++ b/compiler/rustc_hir/src/target.rs @@ -7,6 +7,7 @@ use crate::hir; use crate::{Item, ItemKind, TraitItem, TraitItemKind}; +use crate::def::DefKind; use std::fmt::{self, Display}; #[derive(Copy, Clone, PartialEq, Debug)] @@ -130,6 +131,30 @@ impl Target { } } + // 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, diff --git a/compiler/rustc_incremental/src/persist/dirty_clean.rs b/compiler/rustc_incremental/src/persist/dirty_clean.rs index 8a4ed02f6aea1..aaf24636598b9 100644 --- a/compiler/rustc_incremental/src/persist/dirty_clean.rs +++ b/compiler/rustc_incremental/src/persist/dirty_clean.rs @@ -24,7 +24,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit; -use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::Node as HirNode; use rustc_hir::{ImplItemKind, ItemKind as HirItem, TraitItemKind}; use rustc_middle::dep_graph::{label_strs, DepNode, DepNodeExt}; @@ -147,7 +146,24 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs: Default::default() }; - tcx.hir().visit_all_item_likes(&mut dirty_clean_visitor); + + let crate_items = tcx.hir_crate_items(()); + + for id in crate_items.items() { + dirty_clean_visitor.check_item(id.def_id); + } + + for id in crate_items.trait_items() { + dirty_clean_visitor.check_item(id.def_id); + } + + for id in crate_items.impl_items() { + dirty_clean_visitor.check_item(id.def_id); + } + + for id in crate_items.foreign_items() { + dirty_clean_visitor.check_item(id.def_id); + } let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] }; tcx.hir().walk_attributes(&mut all_attrs); @@ -365,7 +381,8 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { } } - fn check_item(&mut self, item_id: LocalDefId, item_span: Span) { + fn check_item(&mut self, item_id: LocalDefId) { + let item_span = self.tcx.def_span(item_id.to_def_id()); let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id()); for attr in self.tcx.get_attrs(item_id.to_def_id()).iter() { let Some(assertion) = self.assertion_maybe(item_id, attr) else { @@ -388,24 +405,6 @@ impl<'tcx> DirtyCleanVisitor<'tcx> { } } -impl<'tcx> ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'tcx> { - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - self.check_item(item.def_id, item.span); - } - - fn visit_trait_item(&mut self, item: &hir::TraitItem<'_>) { - self.check_item(item.def_id, item.span); - } - - fn visit_impl_item(&mut self, item: &hir::ImplItem<'_>) { - self.check_item(item.def_id, item.span); - } - - fn visit_foreign_item(&mut self, item: &hir::ForeignItem<'_>) { - self.check_item(item.def_id, item.span); - } -} - /// Given a `#[rustc_clean]` attribute, scan for a `cfg="foo"` attribute and check whether we have /// a cfg flag called `foo`. fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool { diff --git a/compiler/rustc_interface/src/proc_macro_decls.rs b/compiler/rustc_interface/src/proc_macro_decls.rs index c0316ce58d26e..5371c513d2981 100644 --- a/compiler/rustc_interface/src/proc_macro_decls.rs +++ b/compiler/rustc_interface/src/proc_macro_decls.rs @@ -1,35 +1,25 @@ use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; -use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_middle::ty::query::Providers; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; fn proc_macro_decls_static(tcx: TyCtxt<'_>, (): ()) -> Option { let mut finder = Finder { tcx, decls: None }; - tcx.hir().visit_all_item_likes(&mut finder); - finder.decls.map(|id| tcx.hir().local_def_id(id)) -} - -struct Finder<'tcx> { - tcx: TyCtxt<'tcx>, - decls: Option, -} - -impl<'v> ItemLikeVisitor<'v> for Finder<'_> { - fn visit_item(&mut self, item: &hir::Item<'_>) { - let attrs = self.tcx.hir().attrs(item.hir_id()); - if self.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) { - self.decls = Some(item.hir_id()); + for id in tcx.hir().items() { + let attrs = finder.tcx.hir().attrs(id.hir_id()); + if finder.tcx.sess.contains_name(attrs, sym::rustc_proc_macro_decls) { + finder.decls = Some(id.def_id); } } - fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {} - - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {} + finder.decls +} - fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {} +struct Finder<'tcx> { + tcx: TyCtxt<'tcx>, + decls: Option, } pub(crate) fn provide(providers: &mut Providers) { diff --git a/compiler/rustc_metadata/src/foreign_modules.rs b/compiler/rustc_metadata/src/foreign_modules.rs index c4ee1e191286d..97fcbeb4ccc59 100644 --- a/compiler/rustc_metadata/src/foreign_modules.rs +++ b/compiler/rustc_metadata/src/foreign_modules.rs @@ -1,29 +1,19 @@ use rustc_hir as hir; -use rustc_hir::itemlikevisit::ItemLikeVisitor; +use rustc_hir::def::DefKind; use rustc_middle::ty::TyCtxt; use rustc_session::cstore::ForeignModule; crate fn collect(tcx: TyCtxt<'_>) -> Vec { - let mut collector = Collector { modules: Vec::new() }; - tcx.hir().visit_all_item_likes(&mut collector); - collector.modules -} - -struct Collector { - modules: Vec, -} - -impl<'tcx> ItemLikeVisitor<'tcx> for Collector { - fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) { - let hir::ItemKind::ForeignMod { items, .. } = it.kind else { - return; - }; - - let foreign_items = items.iter().map(|it| it.id.def_id.to_def_id()).collect(); - self.modules.push(ForeignModule { foreign_items, def_id: it.def_id.to_def_id() }); + let mut modules = Vec::new(); + for id in tcx.hir().items() { + if !matches!(tcx.hir().def_kind(id.def_id), DefKind::ForeignMod) { + continue; + } + let item = tcx.hir().item(id); + if let hir::ItemKind::ForeignMod { items, .. } = item.kind { + let foreign_items = items.iter().map(|it| it.id.def_id.to_def_id()).collect(); + modules.push(ForeignModule { foreign_items, def_id: id.def_id.to_def_id() }); + } } - - fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {} - fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {} - fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {} + modules } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 1cbfb0bd5546b..43b6ecee794cd 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -3,7 +3,7 @@ use rustc_attr as attr; use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; use rustc_hir as hir; -use rustc_hir::itemlikevisit::ItemLikeVisitor; +use rustc_hir::def::DefKind; use rustc_middle::ty::{List, ParamEnv, ParamEnvAnd, Ty, TyCtxt}; use rustc_session::cstore::{DllCallingConvention, DllImport, NativeLib}; use rustc_session::parse::feature_err; @@ -15,7 +15,9 @@ use rustc_target::spec::abi::Abi; crate fn collect(tcx: TyCtxt<'_>) -> Vec { let mut collector = Collector { tcx, libs: Vec::new() }; - tcx.hir().visit_all_item_likes(&mut collector); + for id in tcx.hir().items() { + collector.process_item(id); + } collector.process_command_line(); collector.libs } @@ -32,8 +34,13 @@ struct Collector<'tcx> { libs: Vec, } -impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> { - fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) { +impl<'tcx> Collector<'tcx> { + fn process_item(&mut self, id: rustc_hir::ItemId) { + if !matches!(self.tcx.hir().def_kind(id.def_id), DefKind::ForeignMod) { + return; + } + + let it = self.tcx.hir().item(id); let hir::ItemKind::ForeignMod { abi, items: foreign_mod_items } = it.kind else { return; }; @@ -252,12 +259,6 @@ impl<'tcx> ItemLikeVisitor<'tcx> for Collector<'tcx> { } } - fn visit_trait_item(&mut self, _it: &'tcx hir::TraitItem<'tcx>) {} - fn visit_impl_item(&mut self, _it: &'tcx hir::ImplItem<'tcx>) {} - fn visit_foreign_item(&mut self, _it: &'tcx hir::ForeignItem<'tcx>) {} -} - -impl Collector<'_> { fn register_native_lib(&mut self, span: Option, lib: NativeLib) { if lib.name.as_ref().map_or(false, |&s| s == kw::Empty) { match span { diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 6c758b8e5b633..51bba3ddcf746 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1783,10 +1783,27 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("EncodeContext::encode_traits_and_impls()"); empty_proc_macro!(self); let tcx = self.tcx; - let mut visitor = ImplsVisitor { tcx, impls: FxHashMap::default() }; - tcx.hir().visit_all_item_likes(&mut visitor); + let mut fx_hash_map: FxHashMap)>> = + FxHashMap::default(); - let mut all_impls: Vec<_> = visitor.impls.into_iter().collect(); + for id in tcx.hir().items() { + if matches!(tcx.hir().def_kind(id.def_id), DefKind::Impl) { + if let Some(trait_ref) = tcx.impl_trait_ref(id.def_id.to_def_id()) { + let simplified_self_ty = fast_reject::simplify_type( + self.tcx, + trait_ref.self_ty(), + TreatParams::AsPlaceholders, + ); + + fx_hash_map + .entry(trait_ref.def_id) + .or_default() + .push((id.def_id.local_def_index, simplified_self_ty)); + } + } + } + + let mut all_impls: Vec<_> = fx_hash_map.into_iter().collect(); // Bring everything into deterministic order for hashing all_impls.sort_by_cached_key(|&(trait_def_id, _)| tcx.def_path_hash(trait_def_id)); @@ -2049,41 +2066,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } -struct ImplsVisitor<'tcx> { - tcx: TyCtxt<'tcx>, - impls: FxHashMap)>>, -} - -impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplsVisitor<'tcx> { - fn visit_item(&mut self, item: &hir::Item<'_>) { - match item.kind { - hir::ItemKind::Impl(..) => { - if let Some(trait_ref) = self.tcx.impl_trait_ref(item.def_id.to_def_id()) { - let simplified_self_ty = fast_reject::simplify_type( - self.tcx, - trait_ref.self_ty(), - TreatParams::AsPlaceholders, - ); - - self.impls - .entry(trait_ref.def_id) - .or_default() - .push((item.def_id.local_def_index, simplified_self_ty)); - } - } - _ => {} - } - } - - fn visit_trait_item(&mut self, _trait_item: &'v hir::TraitItem<'v>) {} - - fn visit_impl_item(&mut self, _impl_item: &'v hir::ImplItem<'v>) { - // handled in `visit_item` above - } - - fn visit_foreign_item(&mut self, _foreign_item: &'v hir::ForeignItem<'v>) {} -} - /// Used to prefetch queries which will be needed later by metadata encoding. /// Only a subset of the queries are actually prefetched to keep this code smaller. fn prefetch_mir(tcx: TyCtxt<'_>) { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 561653f3bebf7..ac5f8fa56a999 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -18,7 +18,6 @@ use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::Span; use rustc_target::spec::abi::Abi; -use std::collections::VecDeque; fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> { match node { @@ -159,12 +158,12 @@ impl<'hir> Map<'hir> { } } - pub fn items(self) -> impl Iterator> + 'hir { - let krate = self.krate(); - krate.owners.iter().filter_map(|owner| match owner.as_owner()?.node() { - OwnerNode::Item(item) => Some(item), - _ => None, - }) + pub fn items(self) -> impl Iterator + 'hir { + self.tcx.hir_crate_items(()).items.iter().copied() + } + + pub fn par_for_each_item(self, f: impl Fn(ItemId) + Sync + Send) { + par_for_each_in(&self.tcx.hir_crate_items(()).items[..], |id| f(*id)); } pub fn def_key(self, def_id: LocalDefId) -> DefKey { @@ -677,13 +676,9 @@ impl<'hir> Map<'hir> { } pub fn for_each_module(self, f: impl Fn(LocalDefId)) { - let mut queue = VecDeque::new(); - queue.push_back(CRATE_DEF_ID); - - while let Some(id) = queue.pop_front() { - f(id); - let items = self.tcx.hir_module_items(id); - queue.extend(items.submodules.iter().copied()) + let crate_items = self.tcx.hir_crate_items(()); + for module in crate_items.submodules.iter() { + f(*module) } } @@ -1310,3 +1305,69 @@ pub(super) fn hir_module_items(tcx: TyCtxt<'_>, module_id: LocalDefId) -> Module } } } + +pub(crate) fn hir_crate_items(tcx: TyCtxt<'_>, _: ()) -> ModuleItems { + let mut collector = CrateCollector { + tcx, + submodules: Vec::default(), + items: Vec::default(), + trait_items: Vec::default(), + impl_items: Vec::default(), + foreign_items: Vec::default(), + }; + + tcx.hir().walk_toplevel_module(&mut collector); + + let CrateCollector { submodules, items, trait_items, impl_items, foreign_items, .. } = + collector; + + return ModuleItems { + submodules: submodules.into_boxed_slice(), + items: items.into_boxed_slice(), + trait_items: trait_items.into_boxed_slice(), + impl_items: impl_items.into_boxed_slice(), + foreign_items: foreign_items.into_boxed_slice(), + }; + + struct CrateCollector<'tcx> { + tcx: TyCtxt<'tcx>, + submodules: Vec, + items: Vec, + trait_items: Vec, + impl_items: Vec, + foreign_items: Vec, + } + + impl<'hir> Visitor<'hir> for CrateCollector<'hir> { + type NestedFilter = nested_filter::All; + + fn nested_visit_map(&mut self) -> Self::Map { + self.tcx.hir() + } + + fn visit_item(&mut self, item: &'hir Item<'hir>) { + self.items.push(item.item_id()); + intravisit::walk_item(self, item) + } + + fn visit_mod(&mut self, m: &'hir Mod<'hir>, _s: Span, n: HirId) { + self.submodules.push(n.owner); + intravisit::walk_mod(self, m, n); + } + + fn visit_foreign_item(&mut self, item: &'hir ForeignItem<'hir>) { + self.foreign_items.push(item.foreign_item_id()); + intravisit::walk_foreign_item(self, item) + } + + fn visit_trait_item(&mut self, item: &'hir TraitItem<'hir>) { + self.trait_items.push(item.trait_item_id()); + intravisit::walk_trait_item(self, item) + } + + fn visit_impl_item(&mut self, item: &'hir ImplItem<'hir>) { + self.impl_items.push(item.impl_item_id()); + intravisit::walk_impl_item(self, item) + } + } +} diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index a9e22d16ee050..f18067145dd4a 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -45,6 +45,24 @@ pub struct ModuleItems { foreign_items: Box<[ForeignItemId]>, } +impl ModuleItems { + pub fn items(&self) -> impl Iterator + '_ { + self.items.iter().copied() + } + + pub fn trait_items(&self) -> impl Iterator + '_ { + self.trait_items.iter().copied() + } + + pub fn impl_items(&self) -> impl Iterator + '_ { + self.impl_items.iter().copied() + } + + pub fn foreign_items(&self) -> impl Iterator + '_ { + self.foreign_items.iter().copied() + } +} + impl<'tcx> TyCtxt<'tcx> { #[inline(always)] pub fn hir(self) -> map::Map<'tcx> { @@ -68,6 +86,7 @@ pub fn provide(providers: &mut Providers) { hir.get_module_parent_node(hir.local_def_id_to_hir_id(id)) }; providers.hir_crate = |tcx, ()| tcx.untracked_crate; + providers.hir_crate_items = map::hir_crate_items; providers.crate_hash = map::crate_hash; providers.hir_module_items = map::hir_module_items; providers.hir_owner = |tcx, id| { diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 89761bf4e27a0..6733e0f7f3c76 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -45,6 +45,13 @@ rustc_queries! { desc { "get the crate HIR" } } + /// All items in the crate. + query hir_crate_items(_: ()) -> rustc_middle::hir::ModuleItems { + storage(ArenaCacheSelector<'tcx>) + eval_always + desc { "get HIR crate items" } + } + /// The items in a module. /// /// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`. diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 9a9c529f24552..8fd1e4cdb767b 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -9,7 +9,6 @@ use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace}; use rustc_hir::def_id::{DefId, DefIdSet, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData}; -use rustc_hir::ItemKind; use rustc_session::config::TrimmedDefPaths; use rustc_session::cstore::{ExternCrate, ExternCrateSource}; use rustc_span::symbol::{kw, Ident, Symbol}; @@ -2682,8 +2681,13 @@ define_print_and_forward_display! { fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, Namespace, DefId)) { // Iterate all local crate items no matter where they are defined. let hir = tcx.hir(); - for item in hir.items() { - if item.ident.name.as_str().is_empty() || matches!(item.kind, ItemKind::Use(_, _)) { + for id in hir.items() { + if matches!(hir.def_kind(id.def_id), DefKind::Use) { + continue; + } + + let item = hir.item(id); + if item.ident.name == kw::Empty { continue; } diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 2a659a97db5f9..59114d1a7bbe6 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -181,8 +181,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::sync::{par_iter, MTLock, MTRef, ParallelIterator}; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId, LOCAL_CRATE}; -use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::lang_items::LangItem; use rustc_index::bit_set::GrowableBitSet; use rustc_middle::mir::interpret::{AllocId, ConstValue}; @@ -327,11 +327,19 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec { entry_fn: Option<(DefId, EntryFnType)>, } -impl<'v> ItemLikeVisitor<'v> for RootCollector<'_, 'v> { - fn visit_item(&mut self, item: &'v hir::Item<'v>) { - match item.kind { - hir::ItemKind::ExternCrate(..) - | hir::ItemKind::Use(..) - | hir::ItemKind::Macro(..) - | hir::ItemKind::ForeignMod { .. } - | hir::ItemKind::TyAlias(..) - | hir::ItemKind::Trait(..) - | hir::ItemKind::TraitAlias(..) - | hir::ItemKind::OpaqueTy(..) - | hir::ItemKind::Mod(..) => { - // Nothing to do, just keep recursing. - } - - hir::ItemKind::Impl { .. } => { - if self.mode == MonoItemCollectionMode::Eager { - create_mono_items_for_default_impls(self.tcx, item, self.output); - } - } - - hir::ItemKind::Enum(_, ref generics) - | hir::ItemKind::Struct(_, ref generics) - | hir::ItemKind::Union(_, ref generics) => { - if generics.params.is_empty() { - if self.mode == MonoItemCollectionMode::Eager { - debug!( - "RootCollector: ADT drop-glue for {}", - self.tcx.def_path_str(item.def_id.to_def_id()) - ); - - let ty = Instance::new(item.def_id.to_def_id(), InternalSubsts::empty()) - .ty(self.tcx, ty::ParamEnv::reveal_all()); - visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); +impl<'v> RootCollector<'_, 'v> { + fn process_item(&mut self, id: hir::ItemId) { + match self.tcx.hir().def_kind(id.def_id) { + DefKind::Enum | DefKind::Struct | DefKind::Union => { + let item = self.tcx.hir().item(id); + match item.kind { + hir::ItemKind::Enum(_, ref generics) + | hir::ItemKind::Struct(_, ref generics) + | hir::ItemKind::Union(_, ref generics) => { + if generics.params.is_empty() { + if self.mode == MonoItemCollectionMode::Eager { + debug!( + "RootCollector: ADT drop-glue for {}", + self.tcx.def_path_str(item.def_id.to_def_id()) + ); + + let ty = + Instance::new(item.def_id.to_def_id(), InternalSubsts::empty()) + .ty(self.tcx, ty::ParamEnv::reveal_all()); + visit_drop_use(self.tcx, ty, true, DUMMY_SP, self.output); + } + } } + _ => bug!(), } } - hir::ItemKind::GlobalAsm(..) => { + DefKind::GlobalAsm => { debug!( "RootCollector: ItemKind::GlobalAsm({})", - self.tcx.def_path_str(item.def_id.to_def_id()) + self.tcx.def_path_str(id.def_id.to_def_id()) ); - self.output.push(dummy_spanned(MonoItem::GlobalAsm(item.item_id()))); + self.output.push(dummy_spanned(MonoItem::GlobalAsm(id))); } - hir::ItemKind::Static(..) => { + DefKind::Static(..) => { debug!( "RootCollector: ItemKind::Static({})", - self.tcx.def_path_str(item.def_id.to_def_id()) + self.tcx.def_path_str(id.def_id.to_def_id()) ); - self.output.push(dummy_spanned(MonoItem::Static(item.def_id.to_def_id()))); + self.output.push(dummy_spanned(MonoItem::Static(id.def_id.to_def_id()))); } - hir::ItemKind::Const(..) => { + DefKind::Const => { // const items only generate mono items if they are // actually used somewhere. Just declaring them is insufficient. // but even just declaring them must collect the items they refer to - if let Ok(val) = self.tcx.const_eval_poly(item.def_id.to_def_id()) { + if let Ok(val) = self.tcx.const_eval_poly(id.def_id.to_def_id()) { collect_const_value(self.tcx, val, &mut self.output); } } - hir::ItemKind::Fn(..) => { - self.push_if_root(item.def_id); + DefKind::Impl => { + if self.mode == MonoItemCollectionMode::Eager { + let item = self.tcx.hir().item(id); + create_mono_items_for_default_impls(self.tcx, item, self.output); + } + } + DefKind::Fn => { + self.push_if_root(id.def_id); } + _ => {} } } - fn visit_trait_item(&mut self, _: &'v hir::TraitItem<'v>) { - // Even if there's a default body with no explicit generics, - // it's still generic over some `Self: Trait`, so not a root. - } - - fn visit_impl_item(&mut self, ii: &'v hir::ImplItem<'v>) { - if let hir::ImplItemKind::Fn(hir::FnSig { .. }, _) = ii.kind { - self.push_if_root(ii.def_id); + fn process_impl_item(&mut self, id: hir::ImplItemId) { + if matches!(self.tcx.hir().def_kind(id.def_id), DefKind::AssocFn) { + self.push_if_root(id.def_id); } } - fn visit_foreign_item(&mut self, _foreign_item: &'v hir::ForeignItem<'v>) {} -} - -impl<'v> RootCollector<'_, 'v> { fn is_root(&self, def_id: LocalDefId) -> bool { !item_requires_monomorphization(self.tcx, def_id) && match self.mode { diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 0c934ecc91376..18d9bdf8e1792 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -12,8 +12,8 @@ use crate::weak_lang_items; use rustc_errors::{pluralize, struct_span_err}; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_hir::lang_items::{extract, GenericRequirement, ITEM_REFS}; use rustc_hir::{HirId, LangItem, LanguageItems, Target}; use rustc_middle::ty::TyCtxt; @@ -27,28 +27,6 @@ struct LanguageItemCollector<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'v, 'tcx> ItemLikeVisitor<'v> for LanguageItemCollector<'tcx> { - fn visit_item(&mut self, item: &hir::Item<'_>) { - self.check_for_lang(Target::from_item(item), item.hir_id()); - - if let hir::ItemKind::Enum(def, ..) = &item.kind { - for variant in def.variants { - self.check_for_lang(Target::Variant, variant.id); - } - } - } - - fn visit_trait_item(&mut self, trait_item: &hir::TraitItem<'_>) { - self.check_for_lang(Target::from_trait_item(trait_item), trait_item.hir_id()) - } - - fn visit_impl_item(&mut self, impl_item: &hir::ImplItem<'_>) { - self.check_for_lang(target_from_impl_item(self.tcx, impl_item), impl_item.hir_id()) - } - - fn visit_foreign_item(&mut self, _: &hir::ForeignItem<'_>) {} -} - impl<'tcx> LanguageItemCollector<'tcx> { fn new(tcx: TyCtxt<'tcx>) -> LanguageItemCollector<'tcx> { LanguageItemCollector { tcx, items: LanguageItems::new() } @@ -259,7 +237,32 @@ fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems { } // Collect lang items in this crate. - tcx.hir().visit_all_item_likes(&mut collector); + let crate_items = tcx.hir_crate_items(()); + + for id in crate_items.items() { + collector.check_for_lang(Target::from_def_kind(tcx.hir().def_kind(id.def_id)), id.hir_id()); + + if matches!(tcx.hir().def_kind(id.def_id), DefKind::Enum) { + let item = tcx.hir().item(id); + if let hir::ItemKind::Enum(def, ..) = &item.kind { + for variant in def.variants { + collector.check_for_lang(Target::Variant, variant.id); + } + } + } + } + + // FIXME: avoid calling trait_item() when possible + for id in crate_items.trait_items() { + let item = tcx.hir().trait_item(id); + collector.check_for_lang(Target::from_trait_item(item), item.hir_id()) + } + + // FIXME: avoid calling impl_item() when possible + for id in crate_items.impl_items() { + let item = tcx.hir().impl_item(id); + collector.check_for_lang(target_from_impl_item(tcx, item), item.hir_id()) + } // Extract out the found lang items. let LanguageItemCollector { mut items, .. } = collector; diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs index 6b73c95011940..5411946343b74 100644 --- a/compiler/rustc_passes/src/weak_lang_items.rs +++ b/compiler/rustc_passes/src/weak_lang_items.rs @@ -2,20 +2,11 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::struct_span_err; -use rustc_hir as hir; -use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::lang_items::{self, LangItem}; use rustc_hir::weak_lang_items::WEAK_ITEMS_REFS; use rustc_middle::middle::lang_items::required; use rustc_middle::ty::TyCtxt; use rustc_session::config::CrateType; -use rustc_span::symbol::Symbol; -use rustc_span::Span; - -struct Context<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - items: &'a mut lang_items::LanguageItems, -} /// Checks the crate for usage of weak lang items, returning a vector of all the /// language items required by this crate, but not defined yet. @@ -30,10 +21,28 @@ pub fn check_crate<'tcx>(tcx: TyCtxt<'tcx>, items: &mut lang_items::LanguageItem items.missing.push(LangItem::EhCatchTypeinfo); } - { - let mut cx = Context { tcx, items }; - tcx.hir().visit_all_item_likes(&mut cx.as_deep_visitor()); + let crate_items = tcx.hir_crate_items(()); + for id in crate_items.foreign_items() { + let attrs = tcx.hir().attrs(id.hir_id()); + if let Some((lang_item, _)) = lang_items::extract(attrs) { + if let Some(&item) = WEAK_ITEMS_REFS.get(&lang_item) { + if items.require(item).is_err() { + items.missing.push(item); + } + } else { + let span = tcx.def_span(id.def_id); + struct_span_err!( + tcx.sess, + span, + E0264, + "unknown external lang item: `{}`", + lang_item + ) + .emit(); + } + } } + verify(tcx, items); } @@ -80,26 +89,3 @@ fn verify<'tcx>(tcx: TyCtxt<'tcx>, items: &lang_items::LanguageItems) { } } } - -impl<'a, 'tcx> Context<'a, 'tcx> { - fn register(&mut self, name: Symbol, span: Span) { - if let Some(&item) = WEAK_ITEMS_REFS.get(&name) { - if self.items.require(item).is_err() { - self.items.missing.push(item); - } - } else { - struct_span_err!(self.tcx.sess, span, E0264, "unknown external lang item: `{}`", name) - .emit(); - } - } -} - -impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> { - fn visit_foreign_item(&mut self, i: &hir::ForeignItem<'_>) { - let attrs = self.tcx.hir().attrs(i.hir_id()); - if let Some((lang_item, _)) = lang_items::extract(attrs) { - self.register(lang_item, i.span); - } - intravisit::walk_foreign_item(self, i) - } -} diff --git a/compiler/rustc_symbol_mangling/src/test.rs b/compiler/rustc_symbol_mangling/src/test.rs index 611943652a6a1..37d1cffa2a52b 100644 --- a/compiler/rustc_symbol_mangling/src/test.rs +++ b/compiler/rustc_symbol_mangling/src/test.rs @@ -4,7 +4,6 @@ //! def-path. This is used for unit testing the code that generates //! paths etc in all kinds of annoying scenarios. -use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{subst::InternalSubsts, Instance, TyCtxt}; @@ -22,8 +21,24 @@ pub fn report_symbol_names(tcx: TyCtxt<'_>) { } tcx.dep_graph.with_ignore(|| { - let mut visitor = SymbolNamesTest { tcx }; - tcx.hir().visit_all_item_likes(&mut visitor); + let mut symbol_names = SymbolNamesTest { tcx }; + let crate_items = tcx.hir_crate_items(()); + + for id in crate_items.items() { + symbol_names.process_attrs(id.def_id); + } + + for id in crate_items.trait_items() { + symbol_names.process_attrs(id.def_id); + } + + for id in crate_items.impl_items() { + symbol_names.process_attrs(id.def_id); + } + + for id in crate_items.foreign_items() { + symbol_names.process_attrs(id.def_id); + } }) } @@ -58,21 +73,3 @@ impl SymbolNamesTest<'_> { } } } - -impl<'tcx> hir::itemlikevisit::ItemLikeVisitor<'tcx> for SymbolNamesTest<'tcx> { - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - self.process_attrs(item.def_id); - } - - fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { - self.process_attrs(trait_item.def_id); - } - - fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { - self.process_attrs(impl_item.def_id); - } - - fn visit_foreign_item(&mut self, foreign_item: &'tcx hir::ForeignItem<'tcx>) { - self.process_attrs(foreign_item.def_id); - } -} diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs index 1826c3f5f7fa5..4f792fa25a12b 100644 --- a/compiler/rustc_typeck/src/check_unused.rs +++ b/compiler/rustc_typeck/src/check_unused.rs @@ -1,72 +1,58 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::Applicability; use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_middle::ty::TyCtxt; use rustc_session::lint; use rustc_span::{Span, Symbol}; pub fn check_crate(tcx: TyCtxt<'_>) { - let mut used_trait_imports = FxHashSet::default(); + let mut used_trait_imports: FxHashSet = FxHashSet::default(); + for item_def_id in tcx.hir().body_owners() { let imports = tcx.used_trait_imports(item_def_id); debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports); used_trait_imports.extend(imports.iter()); } - let mut visitor = CheckVisitor { tcx, used_trait_imports }; - tcx.hir().visit_all_item_likes(&mut visitor); - - unused_crates_lint(tcx); -} - -impl<'tcx> ItemLikeVisitor<'_> for CheckVisitor<'tcx> { - fn visit_item(&mut self, item: &hir::Item<'_>) { - if item.vis.node.is_pub() || item.span.is_dummy() { - return; - } - if let hir::ItemKind::Use(path, _) = item.kind { - self.check_import(item.item_id(), path.span); + for id in tcx.hir().items() { + if matches!(tcx.hir().def_kind(id.def_id), DefKind::Use) { + let item = tcx.hir().item(id); + if item.vis.node.is_pub() || item.span.is_dummy() { + continue; + } + if let hir::ItemKind::Use(path, _) = item.kind { + check_import(tcx, &mut used_trait_imports, item.item_id(), path.span); + } } } - fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {} - - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {} - - fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {} + unused_crates_lint(tcx); } -struct CheckVisitor<'tcx> { +fn check_import<'tcx>( tcx: TyCtxt<'tcx>, - used_trait_imports: FxHashSet, -} - -impl<'tcx> CheckVisitor<'tcx> { - fn check_import(&self, item_id: hir::ItemId, span: Span) { - if !self.tcx.maybe_unused_trait_import(item_id.def_id) { - return; - } - - if self.used_trait_imports.contains(&item_id.def_id) { - return; - } + used_trait_imports: &mut FxHashSet, + item_id: hir::ItemId, + span: Span, +) { + if !tcx.maybe_unused_trait_import(item_id.def_id) { + return; + } - self.tcx.struct_span_lint_hir( - lint::builtin::UNUSED_IMPORTS, - item_id.hir_id(), - span, - |lint| { - let msg = if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { - format!("unused import: `{}`", snippet) - } else { - "unused import".to_owned() - }; - lint.build(&msg).emit(); - }, - ); + if used_trait_imports.contains(&item_id.def_id) { + return; } + + tcx.struct_span_lint_hir(lint::builtin::UNUSED_IMPORTS, item_id.hir_id(), span, |lint| { + let msg = if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) { + format!("unused import: `{}`", snippet) + } else { + "unused import".to_owned() + }; + lint.build(&msg).emit(); + }); } fn unused_crates_lint(tcx: TyCtxt<'_>) { @@ -110,9 +96,20 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) { // Collect all the extern crates (in a reliable order). let mut crates_to_lint = vec![]; - tcx.hir().visit_all_item_likes(&mut CollectExternCrateVisitor { - crates_to_lint: &mut crates_to_lint, - }); + + for id in tcx.hir().items() { + if matches!(tcx.hir().def_kind(id.def_id), DefKind::ExternCrate) { + let item = tcx.hir().item(id); + if let hir::ItemKind::ExternCrate(orig_name) = item.kind { + crates_to_lint.push(ExternCrateToLint { + def_id: item.def_id.to_def_id(), + span: item.span, + orig_name, + warn_if_unused: !item.ident.as_str().starts_with('_'), + }); + } + } + } let extern_prelude = &tcx.resolutions(()).extern_prelude; @@ -193,10 +190,6 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) { } } -struct CollectExternCrateVisitor<'a> { - crates_to_lint: &'a mut Vec, -} - struct ExternCrateToLint { /// `DefId` of the extern crate def_id: DefId, @@ -213,22 +206,3 @@ struct ExternCrateToLint { /// about it going unused (but we should still emit idiom lints). warn_if_unused: bool, } - -impl<'a, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a> { - fn visit_item(&mut self, item: &hir::Item<'_>) { - if let hir::ItemKind::ExternCrate(orig_name) = item.kind { - self.crates_to_lint.push(ExternCrateToLint { - def_id: item.def_id.to_def_id(), - span: item.span, - orig_name, - warn_if_unused: !item.ident.as_str().starts_with('_'), - }); - } - } - - fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem<'_>) {} - - fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem<'_>) {} - - fn visit_foreign_item(&mut self, _foreign_item: &hir::ForeignItem<'_>) {} -} diff --git a/compiler/rustc_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 00163c72974ad..6f842c6e71a5b 100644 --- a/compiler/rustc_typeck/src/outlives/implicit_infer.rs +++ b/compiler/rustc_typeck/src/outlives/implicit_infer.rs @@ -1,7 +1,6 @@ use rustc_data_structures::fx::FxHashMap; -use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_hir::itemlikevisit::ItemLikeVisitor; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::Span; @@ -29,81 +28,57 @@ pub fn infer_predicates<'tcx>( while predicates_added { predicates_added = false; - let mut visitor = InferVisitor { - tcx, - global_inferred_outlives: &mut global_inferred_outlives, - predicates_added: &mut predicates_added, - explicit_map, - }; - // Visit all the crates and infer predicates - tcx.hir().visit_all_item_likes(&mut visitor); - } + for id in tcx.hir().items() { + let item_did = id.def_id; - global_inferred_outlives -} + debug!("InferVisitor::visit_item(item={:?})", item_did); -pub struct InferVisitor<'cx, 'tcx> { - tcx: TyCtxt<'tcx>, - global_inferred_outlives: &'cx mut FxHashMap>, - predicates_added: &'cx mut bool, - explicit_map: &'cx mut ExplicitPredicatesMap<'tcx>, -} - -impl<'cx, 'tcx> ItemLikeVisitor<'tcx> for InferVisitor<'cx, 'tcx> { - fn visit_item(&mut self, item: &hir::Item<'_>) { - let item_did = item.def_id; - - debug!("InferVisitor::visit_item(item={:?})", item_did); + let mut item_required_predicates = RequiredPredicates::default(); + match tcx.hir().def_kind(item_did) { + DefKind::Union | DefKind::Enum | DefKind::Struct => { + let adt_def = tcx.adt_def(item_did.to_def_id()); - let mut item_required_predicates = RequiredPredicates::default(); - match item.kind { - hir::ItemKind::Union(..) | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) => { - let adt_def = self.tcx.adt_def(item_did.to_def_id()); - - // Iterate over all fields in item_did - for field_def in adt_def.all_fields() { - // Calculating the predicate requirements necessary - // for item_did. - // - // For field of type &'a T (reference) or Adt - // (struct/enum/union) there will be outlive - // requirements for adt_def. - let field_ty = self.tcx.type_of(field_def.did); - let field_span = self.tcx.def_span(field_def.did); - insert_required_predicates_to_be_wf( - self.tcx, - field_ty, - field_span, - self.global_inferred_outlives, - &mut item_required_predicates, - &mut self.explicit_map, - ); + // Iterate over all fields in item_did + for field_def in adt_def.all_fields() { + // Calculating the predicate requirements necessary + // for item_did. + // + // For field of type &'a T (reference) or Adt + // (struct/enum/union) there will be outlive + // requirements for adt_def. + let field_ty = tcx.type_of(field_def.did); + let field_span = tcx.def_span(field_def.did); + insert_required_predicates_to_be_wf( + tcx, + field_ty, + field_span, + &mut global_inferred_outlives, + &mut item_required_predicates, + explicit_map, + ); + } } - } - _ => {} - }; + _ => {} + }; - // If new predicates were added (`local_predicate_map` has more - // predicates than the `global_inferred_outlives`), the new predicates - // might result in implied predicates for their parent types. - // Therefore mark `predicates_added` as true and which will ensure - // we walk the crates again and re-calculate predicates for all - // items. - let item_predicates_len: usize = - self.global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.len()); - if item_required_predicates.len() > item_predicates_len { - *self.predicates_added = true; - self.global_inferred_outlives.insert(item_did.to_def_id(), item_required_predicates); + // If new predicates were added (`local_predicate_map` has more + // predicates than the `global_inferred_outlives`), the new predicates + // might result in implied predicates for their parent types. + // Therefore mark `predicates_added` as true and which will ensure + // we walk the crates again and re-calculate predicates for all + // items. + let item_predicates_len: usize = + global_inferred_outlives.get(&item_did.to_def_id()).map_or(0, |p| p.len()); + if item_required_predicates.len() > item_predicates_len { + predicates_added = true; + global_inferred_outlives.insert(item_did.to_def_id(), item_required_predicates); + } } } - fn visit_trait_item(&mut self, _trait_item: &'tcx hir::TraitItem<'tcx>) {} - - fn visit_impl_item(&mut self, _impl_item: &'tcx hir::ImplItem<'tcx>) {} - - fn visit_foreign_item(&mut self, _foreign_item: &'tcx hir::ForeignItem<'tcx>) {} + global_inferred_outlives } fn insert_required_predicates_to_be_wf<'tcx>( diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs index 22b4589695512..a01e2f2db3afb 100644 --- a/src/tools/clippy/clippy_lints/src/same_name_method.rs +++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs @@ -50,7 +50,12 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod { fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { let mut map = FxHashMap::::default(); - for item in cx.tcx.hir().items() { + for id in cx.tcx.hir().items() { + if !matches!(cx.tcx.hir().def_kind(id.def_id), DefKind::Impl) { + continue; + } + + let item = cx.tcx.hir().item(id); if let ItemKind::Impl(Impl { items, of_trait, diff --git a/src/tools/clippy/tests/ui/same_name_method.stderr b/src/tools/clippy/tests/ui/same_name_method.stderr index c32c3dd9880f6..cf06eb32e0c7f 100644 --- a/src/tools/clippy/tests/ui/same_name_method.stderr +++ b/src/tools/clippy/tests/ui/same_name_method.stderr @@ -11,6 +11,19 @@ note: existing `foo` defined here LL | fn foo() {} | ^^^^^^^^^^^ +error: method's name is the same as an existing method in a trait + --> $DIR/same_name_method.rs:34:13 + | +LL | fn clone() {} + | ^^^^^^^^^^^^^ + | +note: existing `clone` defined here + --> $DIR/same_name_method.rs:30:18 + | +LL | #[derive(Clone)] + | ^^^^^ + = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) + error: method's name is the same as an existing method in a trait --> $DIR/same_name_method.rs:44:13 | @@ -47,18 +60,5 @@ note: existing `foo` defined here LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ -error: method's name is the same as an existing method in a trait - --> $DIR/same_name_method.rs:34:13 - | -LL | fn clone() {} - | ^^^^^^^^^^^^^ - | -note: existing `clone` defined here - --> $DIR/same_name_method.rs:30:18 - | -LL | #[derive(Clone)] - | ^^^^^ - = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) - error: aborting due to 5 previous errors