diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 36eada4c1d7..f67c4cb922c 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -402,8 +402,6 @@ struct EmbargoVisitor<'tcx> { /// n::p::f() /// } macro_reachable: FxHashSet<(LocalModDefId, LocalModDefId)>, - /// Preliminary pass for marking all underlying types of `impl Trait`s as reachable. - impl_trait_pass: bool, /// Has something changed in the level map? changed: bool, } @@ -634,48 +632,6 @@ impl<'tcx> EmbargoVisitor<'tcx> { } impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { - fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) { - if self.impl_trait_pass { - let should_visit = match opaque.origin { - hir::OpaqueTyOrigin::FnReturn { - parent, - in_trait_or_impl: Some(hir::RpitContext::Trait), - } - | hir::OpaqueTyOrigin::AsyncFn { - parent, - in_trait_or_impl: Some(hir::RpitContext::Trait), - } => match self.tcx.hir_node_by_def_id(parent).expect_trait_item().expect_fn().1 { - hir::TraitFn::Required(_) => false, - hir::TraitFn::Provided(..) => true, - }, - - // Always visit RPITs in functions that have definitions, - // and all TAITs. - hir::OpaqueTyOrigin::FnReturn { - in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), - .. - } - | hir::OpaqueTyOrigin::AsyncFn { - in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), - .. - } - | hir::OpaqueTyOrigin::TyAlias { .. } => true, - }; - - if should_visit { - // FIXME: This is some serious pessimization intended to workaround deficiencies - // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time - // reachable if they are returned via `impl Trait`, even from private functions. - let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public); - self.reach_through_impl_trait(opaque.def_id, pub_ev).generics().predicates().ty(); - return; - } - } - - // Visit nested items. - intravisit::walk_opaque_ty(self, opaque) - } - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { // Update levels of nested things and mark all items // in interfaces of reachable items as reachable. @@ -1752,19 +1708,59 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { tcx, effective_visibilities: tcx.resolutions(()).effective_visibilities.clone(), macro_reachable: Default::default(), - // HACK(jynelson): trying to infer the type of `impl Trait` breaks `async-std` (and - // `pub async fn` in general). Since rustdoc never needs to do codegen and doesn't - // care about link-time reachability, keep them unreachable (issue #75100). - impl_trait_pass: !tcx.sess.opts.actually_rustdoc, changed: false, }; visitor.effective_visibilities.check_invariants(tcx); - if visitor.impl_trait_pass { + + // HACK(jynelson): trying to infer the type of `impl Trait` breaks `async-std` (and + // `pub async fn` in general). Since rustdoc never needs to do codegen and doesn't + // care about link-time reachability, keep them unreachable (issue #75100). + let impl_trait_pass = !tcx.sess.opts.actually_rustdoc; + if impl_trait_pass { // Underlying types of `impl Trait`s are marked as reachable unconditionally, // so this pass doesn't need to be a part of the fixed point iteration below. - tcx.hir().visit_all_item_likes_in_crate(&mut visitor); - visitor.impl_trait_pass = false; + let krate = tcx.hir_crate_items(()); + for id in krate.opaques() { + let opaque = tcx.hir_node_by_def_id(id).expect_opaque_ty(); + let should_visit = match opaque.origin { + hir::OpaqueTyOrigin::FnReturn { + parent, + in_trait_or_impl: Some(hir::RpitContext::Trait), + } + | hir::OpaqueTyOrigin::AsyncFn { + parent, + in_trait_or_impl: Some(hir::RpitContext::Trait), + } => match tcx.hir_node_by_def_id(parent).expect_trait_item().expect_fn().1 { + hir::TraitFn::Required(_) => false, + hir::TraitFn::Provided(..) => true, + }, + + // Always visit RPITs in functions that have definitions, + // and all TAITs. + hir::OpaqueTyOrigin::FnReturn { + in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), + .. + } + | hir::OpaqueTyOrigin::AsyncFn { + in_trait_or_impl: None | Some(hir::RpitContext::TraitImpl), + .. + } + | hir::OpaqueTyOrigin::TyAlias { .. } => true, + }; + if should_visit { + // FIXME: This is some serious pessimization intended to workaround deficiencies + // in the reachability pass (`middle/reachable.rs`). Types are marked as link-time + // reachable if they are returned via `impl Trait`, even from private functions. + let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public); + visitor + .reach_through_impl_trait(opaque.def_id, pub_ev) + .generics() + .predicates() + .ty(); + } + } + visitor.changed = false; }