diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 2a659a97db5..bdeae1659dd 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. - } +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()) + ); - 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); + 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); + } + } } + _ => {} } } - 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 => { + let item = self.tcx.hir().item(id); + if self.mode == MonoItemCollectionMode::Eager { + 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_typeck/src/outlives/implicit_infer.rs b/compiler/rustc_typeck/src/outlives/implicit_infer.rs index 00163c72974..6f842c6e71a 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>, -} + 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()); -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 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 = + 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); } - - _ => {} - }; - - // 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); } } - 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>(