about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2023-06-15 17:15:24 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2023-06-15 21:25:47 +0300
commit17edd1a77907c4c4c03c0c4e22de9e4ec7dd9243 (patch)
tree0e5c1000eddbd0d8bb80ef357cb9a3778bfab0cf
parentd326aed46f6fdc741fe78f29c948a4c358150094 (diff)
downloadrust-17edd1a77907c4c4c03c0c4e22de9e4ec7dd9243.tar.gz
rust-17edd1a77907c4c4c03c0c4e22de9e4ec7dd9243.zip
privacy: Remove `(Non)ShallowEffectiveVis`
Use a boolean constant parameter instead.

Also turn some methods on `DefIdVisitor` into associated constants.
-rw-r--r--compiler/rustc_privacy/src/lib.rs145
1 files changed, 61 insertions, 84 deletions
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index a51a1c9a8a4..11b024d7fc9 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -73,14 +73,10 @@ impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
 /// in `impl Trait`, see individual comments in `DefIdVisitorSkeleton::visit_ty`.
 trait DefIdVisitor<'tcx> {
     type BreakTy = ();
+    const SHALLOW: bool = false;
+    const SKIP_ASSOC_TYS: bool = false;
 
     fn tcx(&self) -> TyCtxt<'tcx>;
-    fn shallow(&self) -> bool {
-        false
-    }
-    fn skip_assoc_tys(&self) -> bool {
-        false
-    }
     fn visit_def_id(
         &mut self,
         def_id: DefId,
@@ -129,11 +125,7 @@ where
     fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<V::BreakTy> {
         let TraitRef { def_id, substs, .. } = trait_ref;
         self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref.print_only_trait_path())?;
-        if self.def_id_visitor.shallow() {
-            ControlFlow::Continue(())
-        } else {
-            substs.visit_with(self)
-        }
+        if V::SHALLOW { ControlFlow::Continue(()) } else { substs.visit_with(self) }
     }
 
     fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> {
@@ -152,7 +144,7 @@ where
             )
         };
         self.visit_trait(trait_ref)?;
-        if self.def_id_visitor.shallow() {
+        if V::SHALLOW {
             ControlFlow::Continue(())
         } else {
             assoc_substs.iter().try_for_each(|subst| subst.visit_with(self))
@@ -222,7 +214,7 @@ where
             | ty::Closure(def_id, ..)
             | ty::Generator(def_id, ..) => {
                 self.def_id_visitor.visit_def_id(def_id, "type", &ty)?;
-                if self.def_id_visitor.shallow() {
+                if V::SHALLOW {
                     return ControlFlow::Continue(());
                 }
                 // Default type visitor doesn't visit signatures of fn types.
@@ -243,7 +235,7 @@ where
                 }
             }
             ty::Alias(ty::Projection, proj) => {
-                if self.def_id_visitor.skip_assoc_tys() {
+                if V::SKIP_ASSOC_TYS {
                     // Visitors searching for minimal visibility/reachability want to
                     // conservatively approximate associated types like `<Type as Trait>::Alias`
                     // as visible/reachable even if both `Type` and `Trait` are private.
@@ -255,7 +247,7 @@ where
                 return self.visit_projection_ty(proj);
             }
             ty::Alias(ty::Inherent, data) => {
-                if self.def_id_visitor.skip_assoc_tys() {
+                if V::SKIP_ASSOC_TYS {
                     // Visitors searching for minimal visibility/reachability want to
                     // conservatively approximate associated types like `Type::Alias`
                     // as visible/reachable even if `Type` is private.
@@ -271,7 +263,7 @@ where
                 )?;
 
                 // This will also visit substs if necessary, so we don't need to recurse.
-                return if self.def_id_visitor.shallow() {
+                return if V::SHALLOW {
                     ControlFlow::Continue(())
                 } else {
                     data.substs.iter().try_for_each(|subst| subst.visit_with(self))
@@ -333,11 +325,7 @@ where
             }
         }
 
-        if self.def_id_visitor.shallow() {
-            ControlFlow::Continue(())
-        } else {
-            ty.super_visit_with(self)
-        }
+        if V::SHALLOW { ControlFlow::Continue(()) } else { ty.super_visit_with(self) }
     }
 
     fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
@@ -354,22 +342,20 @@ fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visib
 /// Visitor used to determine impl visibility and reachability.
 ////////////////////////////////////////////////////////////////////////////////
 
-struct FindMin<'a, 'tcx, VL: VisibilityLike> {
+struct FindMin<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> {
     tcx: TyCtxt<'tcx>,
     effective_visibilities: &'a EffectiveVisibilities,
     min: VL,
 }
 
-impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL> {
+impl<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> DefIdVisitor<'tcx>
+    for FindMin<'a, 'tcx, VL, SHALLOW>
+{
+    const SHALLOW: bool = SHALLOW;
+    const SKIP_ASSOC_TYS: bool = true;
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
-    fn shallow(&self) -> bool {
-        VL::SHALLOW
-    }
-    fn skip_assoc_tys(&self) -> bool {
-        true
-    }
     fn visit_def_id(
         &mut self,
         def_id: DefId,
@@ -385,17 +371,19 @@ impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL>
 
 trait VisibilityLike: Sized {
     const MAX: Self;
-    const SHALLOW: bool = false;
-    fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self;
+    fn new_min<const SHALLOW: bool>(
+        find: &FindMin<'_, '_, Self, SHALLOW>,
+        def_id: LocalDefId,
+    ) -> Self;
 
-    // Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to
+    // Returns an over-approximation (`SKIP_ASSOC_TYS` = true) of visibility due to
     // associated types for which we can't determine visibility precisely.
-    fn of_impl(
+    fn of_impl<const SHALLOW: bool>(
         def_id: LocalDefId,
         tcx: TyCtxt<'_>,
         effective_visibilities: &EffectiveVisibilities,
     ) -> Self {
-        let mut find = FindMin { tcx, effective_visibilities, min: Self::MAX };
+        let mut find = FindMin::<_, SHALLOW> { tcx, effective_visibilities, min: Self::MAX };
         find.visit(tcx.type_of(def_id).subst_identity());
         if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
             find.visit_trait(trait_ref.subst_identity());
@@ -405,49 +393,28 @@ trait VisibilityLike: Sized {
 }
 impl VisibilityLike for ty::Visibility {
     const MAX: Self = ty::Visibility::Public;
-    fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
+    fn new_min<const SHALLOW: bool>(
+        find: &FindMin<'_, '_, Self, SHALLOW>,
+        def_id: LocalDefId,
+    ) -> Self {
         min(find.tcx.local_visibility(def_id), find.min, find.tcx)
     }
 }
 
-struct NonShallowEffectiveVis(EffectiveVisibility);
-
-impl VisibilityLike for NonShallowEffectiveVis {
-    const MAX: Self = NonShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public));
-    const SHALLOW: bool = false;
-
-    fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
-        let find = FindMin {
-            tcx: find.tcx,
-            effective_visibilities: find.effective_visibilities,
-            min: ShallowEffectiveVis(find.min.0),
-        };
-        NonShallowEffectiveVis(VisibilityLike::new_min(&find, def_id).0)
-    }
-}
-
-struct ShallowEffectiveVis(EffectiveVisibility);
-impl VisibilityLike for ShallowEffectiveVis {
-    const MAX: Self = ShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public));
-    // Type inference is very smart sometimes.
-    // It can make an impl reachable even some components of its type or trait are unreachable.
-    // E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
-    // can be usable from other crates (#57264). So we skip substs when calculating reachability
-    // and consider an impl reachable if its "shallow" type and trait are reachable.
-    //
-    // The assumption we make here is that type-inference won't let you use an impl without knowing
-    // both "shallow" version of its self type and "shallow" version of its trait if it exists
-    // (which require reaching the `DefId`s in them).
-    const SHALLOW: bool = true;
-    fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
+impl VisibilityLike for EffectiveVisibility {
+    const MAX: Self = EffectiveVisibility::from_vis(ty::Visibility::Public);
+    fn new_min<const SHALLOW: bool>(
+        find: &FindMin<'_, '_, Self, SHALLOW>,
+        def_id: LocalDefId,
+    ) -> Self {
         let effective_vis =
-            find.effective_visibilities.effective_vis(def_id).cloned().unwrap_or_else(|| {
+            find.effective_visibilities.effective_vis(def_id).copied().unwrap_or_else(|| {
                 let private_vis =
                     ty::Visibility::Restricted(find.tcx.parent_module_from_def_id(def_id));
                 EffectiveVisibility::from_vis(private_vis)
             });
 
-        ShallowEffectiveVis(effective_vis.min(find.min.0, find.tcx))
+        effective_vis.min(find.min, find.tcx)
     }
 }
 
@@ -785,12 +752,21 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
                 }
             }
             hir::ItemKind::Impl(ref impl_) => {
-                let item_ev = ShallowEffectiveVis::of_impl(
+                // Type inference is very smart sometimes. It can make an impl reachable even some
+                // components of its type or trait are unreachable. E.g. methods of
+                // `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
+                // can be usable from other crates (#57264). So we skip substs when calculating
+                // reachability and consider an impl reachable if its "shallow" type and trait are
+                // reachable.
+                //
+                // The assumption we make here is that type-inference won't let you use an impl
+                // without knowing both "shallow" version of its self type and "shallow" version of
+                // its trait if it exists (which require reaching the `DefId`s in them).
+                let item_ev = EffectiveVisibility::of_impl::<true>(
                     item.owner_id.def_id,
                     self.tcx,
                     &self.effective_visibilities,
-                )
-                .0;
+                );
 
                 self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct);
 
@@ -2154,27 +2130,28 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
             DefKind::Impl { .. } => {
                 let item = tcx.hir().item(id);
                 if let hir::ItemKind::Impl(ref impl_) = item.kind {
-                    let impl_vis =
-                        ty::Visibility::of_impl(item.owner_id.def_id, tcx, &Default::default());
+                    let impl_vis = ty::Visibility::of_impl::<false>(
+                        item.owner_id.def_id,
+                        tcx,
+                        &Default::default(),
+                    );
 
-                    // we are using the non-shallow version here, unlike when building the
+                    // We are using the non-shallow version here, unlike when building the
                     // effective visisibilities table to avoid large number of false positives.
-                    // For example:
+                    // For example in
                     //
                     // impl From<Priv> for Pub {
                     //     fn from(_: Priv) -> Pub {...}
                     // }
                     //
-                    // lints shouldn't be emmited even `from` effective visibility
-                    // is larger then `Priv` nominal visibility.
-                    let impl_ev = Some(
-                        NonShallowEffectiveVis::of_impl(
-                            item.owner_id.def_id,
-                            tcx,
-                            self.effective_visibilities,
-                        )
-                        .0,
-                    );
+                    // lints shouldn't be emmited even if `from` effective visibility
+                    // is larger than `Priv` nominal visibility and if `Priv` can leak
+                    // in some scenarios due to type inference.
+                    let impl_ev = Some(EffectiveVisibility::of_impl::<false>(
+                        item.owner_id.def_id,
+                        tcx,
+                        self.effective_visibilities,
+                    ));
 
                     // check that private components do not appear in the generics or predicates of inherent impls
                     // this check is intentionally NOT performed for impls of traits, per #90586