@@ -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
701703impl < ' 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