about summary refs log tree commit diff
path: root/compiler/rustc_privacy/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_privacy/src/lib.rs')
-rw-r--r--compiler/rustc_privacy/src/lib.rs100
1 files changed, 48 insertions, 52 deletions
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index d00e7eff752..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,
 }
@@ -635,48 +633,6 @@ impl<'tcx> EmbargoVisitor<'tcx> {
 
 impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
     fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
-        if self.impl_trait_pass
-            && let hir::ItemKind::OpaqueTy(opaque) = item.kind
-        {
-            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(item.owner_id.def_id, pub_ev)
-                    .generics()
-                    .predicates()
-                    .ty();
-                return;
-            }
-        }
-
         // Update levels of nested things and mark all items
         // in interfaces of reachable items as reachable.
         let item_ev = self.get(item.owner_id.def_id);
@@ -686,7 +642,7 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
             | hir::ItemKind::ExternCrate(..)
             | hir::ItemKind::GlobalAsm(..) => {}
             // The interface is empty, and all nested items are processed by `visit_item`.
-            hir::ItemKind::Mod(..) | hir::ItemKind::OpaqueTy(..) => {}
+            hir::ItemKind::Mod(..) => {}
             hir::ItemKind::Macro(macro_def, _) => {
                 if let Some(item_ev) = item_ev {
                     self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev);
@@ -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;
     }