@@ -454,6 +454,8 @@ struct EmbargoVisitor<'tcx> {
454
454
/// n::p::f()
455
455
/// }
456
456
macro_reachable : FxHashSet < ( LocalDefId , LocalDefId ) > ,
457
+ /// Preliminary pass for marking all underlying types of `impl Trait`s as reachable.
458
+ impl_trait_pass : bool ,
457
459
/// Has something changed in the level map?
458
460
changed : bool ,
459
461
}
@@ -700,6 +702,20 @@ impl<'tcx> EmbargoVisitor<'tcx> {
700
702
701
703
impl < ' tcx > Visitor < ' tcx > for EmbargoVisitor < ' tcx > {
702
704
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
+
703
719
// Update levels of nested things and mark all items
704
720
// in interfaces of reachable items as reachable.
705
721
let item_ev = self . get ( item. owner_id . def_id ) ;
@@ -709,28 +725,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
709
725
| hir:: ItemKind :: ExternCrate ( ..)
710
726
| hir:: ItemKind :: GlobalAsm ( ..) => { }
711
727
// The interface is empty, and all nested items are processed by `visit_item`.
712
- hir:: ItemKind :: Mod ( ..) => { }
728
+ hir:: ItemKind :: Mod ( ..) | hir :: ItemKind :: OpaqueTy ( .. ) => { }
713
729
hir:: ItemKind :: Macro ( ref macro_def, _) => {
714
730
if let Some ( item_ev) = item_ev {
715
731
self . update_reachability_from_macro ( item. owner_id . def_id , macro_def, item_ev) ;
716
732
}
717
733
}
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
- }
734
734
hir:: ItemKind :: Const ( ..)
735
735
| hir:: ItemKind :: Static ( ..)
736
736
| hir:: ItemKind :: Fn ( ..)
@@ -2130,10 +2130,22 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
2130
2130
tcx,
2131
2131
effective_visibilities : tcx. resolutions ( ( ) ) . effective_visibilities . clone ( ) ,
2132
2132
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 ,
2133
2137
changed : false ,
2134
2138
} ;
2135
2139
2136
2140
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
+
2137
2149
loop {
2138
2150
tcx. hir ( ) . visit_all_item_likes_in_crate ( & mut visitor) ;
2139
2151
if visitor. changed {
0 commit comments