From df326946ed5668bf05c37ece50e271b1c9fbdf1e Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume.gomez@huawei.com>
Date: Thu, 3 Nov 2022 18:15:24 +0100
Subject: [PATCH] Remove rustdoc clean::Visibility type

---
 src/librustdoc/clean/inline.rs           |   5 +-
 src/librustdoc/clean/mod.rs              |   9 +-
 src/librustdoc/clean/types.rs            |  40 ++----
 src/librustdoc/clean/utils.rs            |   9 +-
 src/librustdoc/html/format.rs            | 151 +++++++++++------------
 src/librustdoc/html/render/mod.rs        |   8 +-
 src/librustdoc/html/render/print_item.rs |  41 +++---
 src/librustdoc/json/conversions.rs       |  11 +-
 src/librustdoc/passes/stripper.rs        |   8 +-
 9 files changed, 129 insertions(+), 153 deletions(-)

diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index ec93eefb7d1ee..841c4f9d53005 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -19,8 +19,7 @@ use rustc_span::symbol::{kw, sym, Symbol};
 use crate::clean::{
     self, clean_fn_decl_from_did_and_sig, clean_generics, clean_impl_item, clean_middle_assoc_item,
     clean_middle_field, clean_middle_ty, clean_trait_ref_with_bindings, clean_ty,
-    clean_ty_generics, clean_variant_def, clean_visibility, utils, Attributes, AttributesExt,
-    ImplKind, ItemId, Type,
+    clean_ty_generics, clean_variant_def, utils, Attributes, AttributesExt, ImplKind, ItemId, Type,
 };
 use crate::core::DocContext;
 use crate::formats::item_type::ItemType;
@@ -654,7 +653,7 @@ fn build_macro(
     match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
         LoadedMacro::MacroDef(item_def, _) => {
             if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
-                let vis = clean_visibility(cx.tcx.visibility(import_def_id.unwrap_or(def_id)));
+                let vis = cx.tcx.visibility(import_def_id.unwrap_or(def_id));
                 clean::MacroItem(clean::Macro {
                     source: utils::display_macro_source(cx, name, def, def_id, vis),
                 })
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ad4ad4104e104..77cb7196cde34 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1799,13 +1799,6 @@ pub(crate) fn clean_field_with_def_id(
     Item::from_def_id_and_parts(def_id, Some(name), StructFieldItem(ty), cx)
 }
 
-pub(crate) fn clean_visibility(vis: ty::Visibility<DefId>) -> Visibility {
-    match vis {
-        ty::Visibility::Public => Visibility::Public,
-        ty::Visibility::Restricted(module) => Visibility::Restricted(module),
-    }
-}
-
 pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item {
     let kind = match variant.ctor_kind {
         CtorKind::Const => Variant::CLike(match variant.discr {
@@ -1962,7 +1955,7 @@ fn clean_maybe_renamed_item<'tcx>(
                 clean_fn_or_proc_macro(item, sig, generics, body_id, &mut name, cx)
             }
             ItemKind::Macro(ref macro_def, _) => {
-                let ty_vis = clean_visibility(cx.tcx.visibility(def_id));
+                let ty_vis = cx.tcx.visibility(def_id);
                 MacroItem(Macro {
                     source: display_macro_source(cx, name, macro_def, def_id, ty_vis),
                 })
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 439311f064029..8b265dda90c03 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -24,7 +24,7 @@ use rustc_hir::{BodyId, Mutability};
 use rustc_hir_analysis::check::intrinsic::intrinsic_operation_unsafety;
 use rustc_index::vec::IndexVec;
 use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::{self, DefIdTree, TyCtxt};
+use rustc_middle::ty::{self, DefIdTree, TyCtxt, Visibility};
 use rustc_session::Session;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::source_map::DUMMY_SP;
@@ -34,7 +34,6 @@ use rustc_target::abi::VariantIdx;
 use rustc_target::spec::abi::Abi;
 
 use crate::clean::cfg::Cfg;
-use crate::clean::clean_visibility;
 use crate::clean::external_path;
 use crate::clean::inline::{self, print_inlined_const};
 use crate::clean::utils::{is_literal_expr, print_const_expr, print_evaluated_const};
@@ -51,7 +50,6 @@ pub(crate) use self::Type::{
     Array, BareFunction, BorrowedRef, DynTrait, Generic, ImplTrait, Infer, Primitive, QPath,
     RawPointer, Slice, Tuple,
 };
-pub(crate) use self::Visibility::{Inherited, Public};
 
 #[cfg(test)]
 mod tests;
@@ -706,26 +704,28 @@ impl Item {
         Some(header)
     }
 
-    pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility {
+    /// Returns the visibility of the current item. If the visibility is "inherited", then `None`
+    /// is returned.
+    pub(crate) fn visibility(&self, tcx: TyCtxt<'_>) -> Option<Visibility<DefId>> {
         let def_id = match self.item_id {
             // Anything but DefId *shouldn't* matter, but return a reasonable value anyway.
-            ItemId::Auto { .. } | ItemId::Blanket { .. } => return Visibility::Inherited,
+            ItemId::Auto { .. } | ItemId::Blanket { .. } => return None,
             // Primitives and Keywords are written in the source code as private modules.
             // The modules need to be private so that nobody actually uses them, but the
             // keywords and primitives that they are documenting are public.
-            ItemId::Primitive(..) => return Visibility::Public,
+            ItemId::Primitive(..) => return Some(Visibility::Public),
             ItemId::DefId(def_id) => def_id,
         };
 
         match *self.kind {
             // Explication on `ItemId::Primitive` just above.
-            ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Visibility::Public,
+            ItemKind::KeywordItem | ItemKind::PrimitiveItem(_) => return Some(Visibility::Public),
             // Variant fields inherit their enum's visibility.
             StructFieldItem(..) if is_field_vis_inherited(tcx, def_id) => {
-                return Visibility::Inherited;
+                return None;
             }
             // Variants always inherit visibility
-            VariantItem(..) => return Visibility::Inherited,
+            VariantItem(..) => return None,
             // Trait items inherit the trait's visibility
             AssocConstItem(..) | TyAssocConstItem(..) | AssocTypeItem(..) | TyAssocTypeItem(..)
             | TyMethodItem(..) | MethodItem(..) => {
@@ -739,7 +739,7 @@ impl Item {
                     }
                 };
                 if is_trait_item {
-                    return Visibility::Inherited;
+                    return None;
                 }
             }
             _ => {}
@@ -748,7 +748,7 @@ impl Item {
             Some(inlined) => inlined,
             None => def_id,
         };
-        clean_visibility(tcx.visibility(def_id))
+        Some(tcx.visibility(def_id))
     }
 }
 
@@ -2078,24 +2078,6 @@ impl From<hir::PrimTy> for PrimitiveType {
     }
 }
 
-#[derive(Copy, Clone, Debug)]
-pub(crate) enum Visibility {
-    /// `pub`
-    Public,
-    /// Visibility inherited from parent.
-    ///
-    /// For example, this is the visibility of private items and of enum variants.
-    Inherited,
-    /// `pub(crate)`, `pub(super)`, or `pub(in path::to::somewhere)`
-    Restricted(DefId),
-}
-
-impl Visibility {
-    pub(crate) fn is_public(&self) -> bool {
-        matches!(self, Visibility::Public)
-    }
-}
-
 #[derive(Clone, Debug)]
 pub(crate) struct Struct {
     pub(crate) struct_type: CtorKind,
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 518e320235ff1..df20dc3fc3f7e 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -4,9 +4,10 @@ use crate::clean::render_macro_matchers::render_macro_matcher;
 use crate::clean::{
     clean_doc_module, clean_middle_const, clean_middle_region, clean_middle_ty, inline, Crate,
     ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime, Path,
-    PathSegment, Primitive, PrimitiveType, Type, TypeBinding, Visibility,
+    PathSegment, Primitive, PrimitiveType, Type, TypeBinding,
 };
 use crate::core::DocContext;
+use crate::html::format::visibility_to_src_with_space;
 
 use rustc_ast as ast;
 use rustc_ast::tokenstream::TokenTree;
@@ -583,7 +584,7 @@ pub(super) fn display_macro_source(
     name: Symbol,
     def: &ast::MacroDef,
     def_id: DefId,
-    vis: Visibility,
+    vis: ty::Visibility<DefId>,
 ) -> String {
     let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
     // Extract the spans of all matchers. They represent the "interface" of the macro.
@@ -595,14 +596,14 @@ pub(super) fn display_macro_source(
         if matchers.len() <= 1 {
             format!(
                 "{}macro {}{} {{\n    ...\n}}",
-                vis.to_src_with_space(cx.tcx, def_id),
+                visibility_to_src_with_space(Some(vis), cx.tcx, def_id),
                 name,
                 matchers.map(|matcher| render_macro_matcher(cx.tcx, matcher)).collect::<String>(),
             )
         } else {
             format!(
                 "{}macro {} {{\n{}}}",
-                vis.to_src_with_space(cx.tcx, def_id),
+                visibility_to_src_with_space(Some(vis), cx.tcx, def_id),
                 name,
                 render_macro_arms(cx.tcx, matchers, ","),
             )
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 37202f786ed80..06db3fb0ec400 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1420,87 +1420,84 @@ impl clean::FnDecl {
     }
 }
 
-impl clean::Visibility {
-    pub(crate) fn print_with_space<'a, 'tcx: 'a>(
-        self,
-        item_did: ItemId,
-        cx: &'a Context<'tcx>,
-    ) -> impl fmt::Display + 'a + Captures<'tcx> {
-        use std::fmt::Write as _;
-
-        let to_print: Cow<'static, str> = match self {
-            clean::Public => "pub ".into(),
-            clean::Inherited => "".into(),
-            clean::Visibility::Restricted(vis_did) => {
-                // FIXME(camelid): This may not work correctly if `item_did` is a module.
-                //                 However, rustdoc currently never displays a module's
-                //                 visibility, so it shouldn't matter.
-                let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
-
-                if vis_did.is_crate_root() {
-                    "pub(crate) ".into()
-                } else if parent_module == Some(vis_did) {
-                    // `pub(in foo)` where `foo` is the parent module
-                    // is the same as no visibility modifier
-                    "".into()
-                } else if parent_module
-                    .and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
-                    == Some(vis_did)
-                {
-                    "pub(super) ".into()
-                } else {
-                    let path = cx.tcx().def_path(vis_did);
-                    debug!("path={:?}", path);
-                    // modified from `resolved_path()` to work with `DefPathData`
-                    let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
-                    let anchor = anchor(vis_did, last_name, cx).to_string();
-
-                    let mut s = "pub(in ".to_owned();
-                    for seg in &path.data[..path.data.len() - 1] {
-                        let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap());
-                    }
-                    let _ = write!(s, "{}) ", anchor);
-                    s.into()
+pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
+    visibility: Option<ty::Visibility<DefId>>,
+    item_did: ItemId,
+    cx: &'a Context<'tcx>,
+) -> impl fmt::Display + 'a + Captures<'tcx> {
+    use std::fmt::Write as _;
+
+    let to_print: Cow<'static, str> = match visibility {
+        None => "".into(),
+        Some(ty::Visibility::Public) => "pub ".into(),
+        Some(ty::Visibility::Restricted(vis_did)) => {
+            // FIXME(camelid): This may not work correctly if `item_did` is a module.
+            //                 However, rustdoc currently never displays a module's
+            //                 visibility, so it shouldn't matter.
+            let parent_module = find_nearest_parent_module(cx.tcx(), item_did.expect_def_id());
+
+            if vis_did.is_crate_root() {
+                "pub(crate) ".into()
+            } else if parent_module == Some(vis_did) {
+                // `pub(in foo)` where `foo` is the parent module
+                // is the same as no visibility modifier
+                "".into()
+            } else if parent_module.and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
+                == Some(vis_did)
+            {
+                "pub(super) ".into()
+            } else {
+                let path = cx.tcx().def_path(vis_did);
+                debug!("path={:?}", path);
+                // modified from `resolved_path()` to work with `DefPathData`
+                let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
+                let anchor = anchor(vis_did, last_name, cx).to_string();
+
+                let mut s = "pub(in ".to_owned();
+                for seg in &path.data[..path.data.len() - 1] {
+                    let _ = write!(s, "{}::", seg.data.get_opt_name().unwrap());
                 }
+                let _ = write!(s, "{}) ", anchor);
+                s.into()
             }
-        };
-        display_fn(move |f| write!(f, "{}", to_print))
-    }
+        }
+    };
+    display_fn(move |f| write!(f, "{}", to_print))
+}
 
-    /// This function is the same as print_with_space, except that it renders no links.
-    /// It's used for macros' rendered source view, which is syntax highlighted and cannot have
-    /// any HTML in it.
-    pub(crate) fn to_src_with_space<'a, 'tcx: 'a>(
-        self,
-        tcx: TyCtxt<'tcx>,
-        item_did: DefId,
-    ) -> impl fmt::Display + 'a + Captures<'tcx> {
-        let to_print = match self {
-            clean::Public => "pub ".to_owned(),
-            clean::Inherited => String::new(),
-            clean::Visibility::Restricted(vis_did) => {
-                // FIXME(camelid): This may not work correctly if `item_did` is a module.
-                //                 However, rustdoc currently never displays a module's
-                //                 visibility, so it shouldn't matter.
-                let parent_module = find_nearest_parent_module(tcx, item_did);
-
-                if vis_did.is_crate_root() {
-                    "pub(crate) ".to_owned()
-                } else if parent_module == Some(vis_did) {
-                    // `pub(in foo)` where `foo` is the parent module
-                    // is the same as no visibility modifier
-                    String::new()
-                } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
-                    == Some(vis_did)
-                {
-                    "pub(super) ".to_owned()
-                } else {
-                    format!("pub(in {}) ", tcx.def_path_str(vis_did))
-                }
+/// This function is the same as print_with_space, except that it renders no links.
+/// It's used for macros' rendered source view, which is syntax highlighted and cannot have
+/// any HTML in it.
+pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>(
+    visibility: Option<ty::Visibility<DefId>>,
+    tcx: TyCtxt<'tcx>,
+    item_did: DefId,
+) -> impl fmt::Display + 'a + Captures<'tcx> {
+    let to_print = match visibility {
+        None => String::new(),
+        Some(ty::Visibility::Public) => "pub ".to_owned(),
+        Some(ty::Visibility::Restricted(vis_did)) => {
+            // FIXME(camelid): This may not work correctly if `item_did` is a module.
+            //                 However, rustdoc currently never displays a module's
+            //                 visibility, so it shouldn't matter.
+            let parent_module = find_nearest_parent_module(tcx, item_did);
+
+            if vis_did.is_crate_root() {
+                "pub(crate) ".to_owned()
+            } else if parent_module == Some(vis_did) {
+                // `pub(in foo)` where `foo` is the parent module
+                // is the same as no visibility modifier
+                String::new()
+            } else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
+                == Some(vis_did)
+            {
+                "pub(super) ".to_owned()
+            } else {
+                format!("pub(in {}) ", tcx.def_path_str(vis_did))
             }
-        };
-        display_fn(move |f| f.write_str(&to_print))
-    }
+        }
+    };
+    display_fn(move |f| f.write_str(&to_print))
 }
 
 pub(crate) trait PrintWithSpace {
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index adf501a024031..3a041ae15d618 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -70,8 +70,8 @@ use crate::formats::{AssocItemRender, Impl, RenderMode};
 use crate::html::escape::Escape;
 use crate::html::format::{
     href, join_with_double_colon, print_abi_with_space, print_constness_with_space,
-    print_default_space, print_generic_bounds, print_where_clause, Buffer, Ending, HrefError,
-    PrintWithSpace,
+    print_default_space, print_generic_bounds, print_where_clause, visibility_print_with_space,
+    Buffer, Ending, HrefError, PrintWithSpace,
 };
 use crate::html::highlight;
 use crate::html::markdown::{
@@ -752,7 +752,7 @@ fn assoc_const(
         w,
         "{extra}{vis}const <a{href} class=\"constant\">{name}</a>: {ty}",
         extra = extra,
-        vis = it.visibility(tcx).print_with_space(it.item_id, cx),
+        vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
         href = assoc_href_attr(it, link, cx),
         name = it.name.as_ref().unwrap(),
         ty = ty.print(cx),
@@ -809,7 +809,7 @@ fn assoc_method(
     let tcx = cx.tcx();
     let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item");
     let name = meth.name.as_ref().unwrap();
-    let vis = meth.visibility(tcx).print_with_space(meth.item_id, cx).to_string();
+    let vis = visibility_print_with_space(meth.visibility(tcx), meth.item_id, cx).to_string();
     // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove
     // this condition.
     let constness = match render_mode {
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 13df08280b5a8..3225ddabe2e75 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::middle::stability;
 use rustc_middle::span_bug;
 use rustc_middle::ty::layout::LayoutError;
-use rustc_middle::ty::{Adt, TyCtxt};
+use rustc_middle::ty::{self, Adt, TyCtxt};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_target::abi::{Layout, Primitive, TagEncoding, Variants};
@@ -28,7 +28,7 @@ use crate::formats::{AssocItemRender, Impl, RenderMode};
 use crate::html::escape::Escape;
 use crate::html::format::{
     join_with_double_colon, print_abi_with_space, print_constness_with_space, print_where_clause,
-    Buffer, Ending, PrintWithSpace,
+    visibility_print_with_space, Buffer, Ending, PrintWithSpace,
 };
 use crate::html::highlight;
 use crate::html::layout::Page;
@@ -328,14 +328,14 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
                     Some(src) => write!(
                         w,
                         "<div class=\"item-left\"><code>{}extern crate {} as {};",
-                        myitem.visibility(tcx).print_with_space(myitem.item_id, cx),
+                        visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
                         anchor(myitem.item_id.expect_def_id(), src, cx),
                         myitem.name.unwrap(),
                     ),
                     None => write!(
                         w,
                         "<div class=\"item-left\"><code>{}extern crate {};",
-                        myitem.visibility(tcx).print_with_space(myitem.item_id, cx),
+                        visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
                         anchor(myitem.item_id.expect_def_id(), myitem.name.unwrap(), cx),
                     ),
                 }
@@ -385,7 +385,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
                      </div>\
                      {stab_tags_before}{stab_tags}{stab_tags_after}",
                     stab = stab.unwrap_or_default(),
-                    vis = myitem.visibility(tcx).print_with_space(myitem.item_id, cx),
+                    vis = visibility_print_with_space(myitem.visibility(tcx), myitem.item_id, cx),
                     imp = import.print(cx),
                 );
                 w.write_str(ITEM_TABLE_ROW_CLOSE);
@@ -410,7 +410,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
                 let add = if stab.is_some() { " " } else { "" };
 
                 let visibility_emoji = match myitem.visibility(tcx) {
-                    clean::Visibility::Restricted(_) => {
+                    Some(ty::Visibility::Restricted(_)) => {
                         "<span title=\"Restricted Visibility\">&nbsp;🔒</span> "
                     }
                     _ => "",
@@ -503,7 +503,7 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
     let unsafety = header.unsafety.print_with_space();
     let abi = print_abi_with_space(header.abi).to_string();
     let asyncness = header.asyncness.print_with_space();
-    let visibility = it.visibility(tcx).print_with_space(it.item_id, cx).to_string();
+    let visibility = visibility_print_with_space(it.visibility(tcx), it.item_id, cx).to_string();
     let name = it.name.unwrap();
 
     let generics_len = format!("{:#}", f.generics.print(cx)).len();
@@ -561,7 +561,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
             write!(
                 w,
                 "{}{}{}trait {}{}{}",
-                it.visibility(tcx).print_with_space(it.item_id, cx),
+                visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
                 t.unsafety(tcx).print_with_space(),
                 if t.is_auto(tcx) { "auto " } else { "" },
                 it.name.unwrap(),
@@ -1086,7 +1086,7 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea
     fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
         wrap_item(w, "typedef", |w| {
             render_attributes_in_pre(w, it, "");
-            write!(w, "{}", it.visibility(cx.tcx()).print_with_space(it.item_id, cx));
+            write!(w, "{}", visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx));
             write!(
                 w,
                 "type {}{}{where_clause} = {type_};",
@@ -1183,7 +1183,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
             write!(
                 w,
                 "{}enum {}{}",
-                it.visibility(tcx).print_with_space(it.item_id, cx),
+                visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
                 it.name.unwrap(),
                 e.generics.print(cx),
             );
@@ -1398,7 +1398,7 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle
             write!(
                 w,
                 "{vis}const {name}: {typ}",
-                vis = it.visibility(tcx).print_with_space(it.item_id, cx),
+                vis = visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
                 name = it.name.unwrap(),
                 typ = c.type_.print(cx),
             );
@@ -1499,7 +1499,7 @@ fn item_static(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
             write!(
                 w,
                 "{vis}static {mutability}{name}: {typ}",
-                vis = it.visibility(cx.tcx()).print_with_space(it.item_id, cx),
+                vis = visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx),
                 mutability = s.mutability.print_with_space(),
                 name = it.name.unwrap(),
                 typ = s.type_.print(cx)
@@ -1517,7 +1517,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item) {
             write!(
                 w,
                 "    {}type {};\n}}",
-                it.visibility(cx.tcx()).print_with_space(it.item_id, cx),
+                visibility_print_with_space(it.visibility(cx.tcx()), it.item_id, cx),
                 it.name.unwrap(),
             );
         });
@@ -1671,7 +1671,12 @@ fn render_union(
     cx: &Context<'_>,
 ) {
     let tcx = cx.tcx();
-    write!(w, "{}union {}", it.visibility(tcx).print_with_space(it.item_id, cx), it.name.unwrap(),);
+    write!(
+        w,
+        "{}union {}",
+        visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
+        it.name.unwrap(),
+    );
 
     let where_displayed = g
         .map(|g| {
@@ -1698,7 +1703,7 @@ fn render_union(
             write!(
                 w,
                 "    {}{}: {},\n{}",
-                field.visibility(tcx).print_with_space(field.item_id, cx),
+                visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
                 field.name.unwrap(),
                 ty.print(cx),
                 tab
@@ -1729,7 +1734,7 @@ fn render_struct(
     write!(
         w,
         "{}{}{}",
-        it.visibility(tcx).print_with_space(it.item_id, cx),
+        visibility_print_with_space(it.visibility(tcx), it.item_id, cx),
         if structhead { "struct " } else { "" },
         it.name.unwrap()
     );
@@ -1759,7 +1764,7 @@ fn render_struct(
                         w,
                         "\n{}    {}{}: {},",
                         tab,
-                        field.visibility(tcx).print_with_space(field.item_id, cx),
+                        visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
                         field.name.unwrap(),
                         ty.print(cx),
                     );
@@ -1791,7 +1796,7 @@ fn render_struct(
                         write!(
                             w,
                             "{}{}",
-                            field.visibility(tcx).print_with_space(field.item_id, cx),
+                            visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
                             ty.print(cx),
                         )
                     }
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 4962eb8f8e176..62ae9519e4b05 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -100,13 +100,12 @@ impl JsonRenderer<'_> {
         }
     }
 
-    fn convert_visibility(&self, v: clean::Visibility) -> Visibility {
-        use clean::Visibility::*;
+    fn convert_visibility(&self, v: Option<ty::Visibility<DefId>>) -> Visibility {
         match v {
-            Public => Visibility::Public,
-            Inherited => Visibility::Default,
-            Restricted(did) if did.is_crate_root() => Visibility::Crate,
-            Restricted(did) => Visibility::Restricted {
+            None => Visibility::Default,
+            Some(ty::Visibility::Public) => Visibility::Public,
+            Some(ty::Visibility::Restricted(did)) if did.is_crate_root() => Visibility::Crate,
+            Some(ty::Visibility::Restricted(did)) => Visibility::Restricted {
                 parent: from_item_id(did.into(), self.tcx),
                 path: self.tcx.def_path(did).to_string_no_crate_verbose(),
             },
diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs
index b2047360ccd9a..995fb5dcc1c86 100644
--- a/src/librustdoc/passes/stripper.rs
+++ b/src/librustdoc/passes/stripper.rs
@@ -1,6 +1,6 @@
 //! A collection of utility functions for the `strip_*` passes.
 use rustc_hir::def_id::DefId;
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{TyCtxt, Visibility};
 use rustc_span::symbol::sym;
 use std::mem;
 
@@ -81,13 +81,13 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
             }
 
             clean::StructFieldItem(..) => {
-                if !i.visibility(self.tcx).is_public() {
+                if i.visibility(self.tcx) != Some(Visibility::Public) {
                     return Some(strip_item(i));
                 }
             }
 
             clean::ModuleItem(..) => {
-                if i.item_id.is_local() && !i.visibility(self.tcx).is_public() {
+                if i.item_id.is_local() && i.visibility(self.tcx) != Some(Visibility::Public) {
                     debug!("Stripper: stripping module {:?}", i.name);
                     let old = mem::replace(&mut self.update_retained, false);
                     let ret = strip_item(self.fold_item_recur(i));
@@ -246,7 +246,7 @@ impl<'tcx> DocFolder for ImportStripper<'tcx> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         match *i.kind {
             clean::ExternCrateItem { .. } | clean::ImportItem(..)
-                if !i.visibility(self.tcx).is_public() =>
+                if i.visibility(self.tcx) != Some(Visibility::Public) =>
             {
                 None
             }