Skip to content

Commit edf95b5

Browse files
committed
rustc_privacy: Reach underlying types of impl Traits in a separate pass
outside of fixed point iteration.
1 parent e41c422 commit edf95b5

File tree

1 file changed

+29
-17
lines changed
  • compiler/rustc_privacy/src

1 file changed

+29
-17
lines changed

compiler/rustc_privacy/src/lib.rs

+29-17
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,8 @@ struct EmbargoVisitor<'tcx> {
454454
/// n::p::f()
455455
/// }
456456
macro_reachable: FxHashSet<(LocalDefId, LocalDefId)>,
457+
/// Preliminary pass for marking all underlying types of `impl Trait`s as reachable.
458+
impl_trait_pass: bool,
457459
/// Has something changed in the level map?
458460
changed: bool,
459461
}
@@ -700,6 +702,20 @@ impl<'tcx> EmbargoVisitor<'tcx> {
700702

701703
impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
702704
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
705+
if self.impl_trait_pass
706+
&& let hir::ItemKind::OpaqueTy(ref opaque) = item.kind
707+
&& !opaque.in_trait {
708+
// FIXME: This is some serious pessimization intended to workaround deficiencies
709+
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
710+
// reachable if they are returned via `impl Trait`, even from private functions.
711+
let pub_ev = EffectiveVisibility::from_vis(ty::Visibility::Public);
712+
self.reach_through_impl_trait(item.owner_id.def_id, pub_ev)
713+
.generics()
714+
.predicates()
715+
.ty();
716+
return;
717+
}
718+
703719
// Update levels of nested things and mark all items
704720
// in interfaces of reachable items as reachable.
705721
let item_ev = self.get(item.owner_id.def_id);
@@ -709,28 +725,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
709725
| hir::ItemKind::ExternCrate(..)
710726
| hir::ItemKind::GlobalAsm(..) => {}
711727
// The interface is empty, and all nested items are processed by `visit_item`.
712-
hir::ItemKind::Mod(..) => {}
728+
hir::ItemKind::Mod(..) | hir::ItemKind::OpaqueTy(..) => {}
713729
hir::ItemKind::Macro(ref macro_def, _) => {
714730
if let Some(item_ev) = item_ev {
715731
self.update_reachability_from_macro(item.owner_id.def_id, macro_def, item_ev);
716732
}
717733
}
718-
hir::ItemKind::OpaqueTy(ref opaque) => {
719-
// HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
720-
// Since rustdoc never needs to do codegen and doesn't care about link-time reachability,
721-
// mark this as unreachable.
722-
// See https://github.com/rust-lang/rust/issues/75100
723-
if !opaque.in_trait && !self.tcx.sess.opts.actually_rustdoc {
724-
// FIXME: This is some serious pessimization intended to workaround deficiencies
725-
// in the reachability pass (`middle/reachable.rs`). Types are marked as link-time
726-
// reachable if they are returned via `impl Trait`, even from private functions.
727-
let exist_ev = EffectiveVisibility::from_vis(ty::Visibility::Public);
728-
self.reach_through_impl_trait(item.owner_id.def_id, exist_ev)
729-
.generics()
730-
.predicates()
731-
.ty();
732-
}
733-
}
734734
hir::ItemKind::Const(..)
735735
| hir::ItemKind::Static(..)
736736
| hir::ItemKind::Fn(..)
@@ -2130,10 +2130,22 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
21302130
tcx,
21312131
effective_visibilities: tcx.resolutions(()).effective_visibilities.clone(),
21322132
macro_reachable: Default::default(),
2133+
// HACK(jynelson): trying to infer the type of `impl Trait` breaks `async-std` (and
2134+
// `pub async fn` in general). Since rustdoc never needs to do codegen and doesn't
2135+
// care about link-time reachability, keep them unreachable (issue #75100).
2136+
impl_trait_pass: !tcx.sess.opts.actually_rustdoc,
21332137
changed: false,
21342138
};
21352139

21362140
visitor.effective_visibilities.check_invariants(tcx, true);
2141+
if visitor.impl_trait_pass {
2142+
// Underlying types of `impl Trait`s are marked as reachable unconditionally,
2143+
// so this pass doesn't need to be a part of the fixed point iteration below.
2144+
tcx.hir().visit_all_item_likes_in_crate(&mut visitor);
2145+
visitor.impl_trait_pass = false;
2146+
visitor.changed = false;
2147+
}
2148+
21372149
loop {
21382150
tcx.hir().visit_all_item_likes_in_crate(&mut visitor);
21392151
if visitor.changed {

0 commit comments

Comments
 (0)