about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNoah Lev <camelidcamel@gmail.com>2021-08-23 21:01:56 -0700
committerNoah Lev <camelidcamel@gmail.com>2021-09-30 13:52:57 -0700
commit4c6385ff935d8121c5cc4c44b62a2b0ae0118a35 (patch)
treee532b6c07b718f9be1e9407935ee494d567abb81
parentd91946b3f4ea04bc205b5796fc4af0f13069d204 (diff)
downloadrust-4c6385ff935d8121c5cc4c44b62a2b0ae0118a35.tar.gz
rust-4c6385ff935d8121c5cc4c44b62a2b0ae0118a35.zip
Make `Impl.trait_` a `Path`, not a `Type`
It should only ever be a `ResolvedPath`, so this (a) enforces that, and
(b) reduces the size of `Impl`.

I had to update a test because the order of the rendered auto trait impl
bounds changed. I think the order changed because rustdoc sorts auto
trait bounds using their `Debug` output.
-rw-r--r--src/librustdoc/clean/auto_trait.rs2
-rw-r--r--src/librustdoc/clean/blanket_impl.rs4
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs8
-rw-r--r--src/librustdoc/clean/types.rs56
-rw-r--r--src/librustdoc/formats/mod.rs2
-rw-r--r--src/librustdoc/html/format.rs9
-rw-r--r--src/librustdoc/html/render/mod.rs4
-rw-r--r--src/librustdoc/json/conversions.rs7
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs4
10 files changed, 73 insertions, 25 deletions
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 1436e51f318..c83a191baf5 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -118,7 +118,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 span: Span::dummy(),
                 unsafety: hir::Unsafety::Normal,
                 generics: new_generics,
-                trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
+                trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap().expect_path()),
                 for_: ty.clean(self.cx),
                 items: Vec::new(),
                 negative_polarity,
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 8135d4a2085..4385c1adc09 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -114,7 +114,9 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                             .clean(self.cx),
                         // FIXME(eddyb) compute both `trait_` and `for_` from
                         // the post-inference `trait_ref`, as it's more accurate.
-                        trait_: Some(trait_ref.clean(self.cx).get_trait_type().unwrap()),
+                        trait_: Some(
+                            trait_ref.clean(self.cx).get_trait_type().unwrap().expect_path(),
+                        ),
                         for_: ty.clean(self.cx),
                         items: self
                             .cx
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index daff902aaa5..7a08e54d4b1 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -483,7 +483,7 @@ crate fn build_impl(
             span: clean::types::rustc_span(did, cx.tcx),
             unsafety: hir::Unsafety::Normal,
             generics,
-            trait_,
+            trait_: trait_.map(|t| t.expect_path()),
             for_,
             items: trait_items,
             negative_polarity: polarity.clean(cx),
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index a7960807f4c..21389fa38a8 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -903,6 +903,12 @@ impl Clean<Type> for hir::TraitRef<'_> {
     }
 }
 
+impl Clean<Path> for hir::TraitRef<'_> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Path {
+        self.path.clean(cx)
+    }
+}
+
 impl Clean<PolyTrait> for hir::PolyTraitRef<'_> {
     fn clean(&self, cx: &mut DocContext<'_>) -> PolyTrait {
         PolyTrait {
@@ -1902,7 +1908,7 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>
         DefKind::TyAlias => Some(tcx.type_of(did).clean(cx)),
         _ => None,
     });
-    let mut make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| {
+    let mut make_item = |trait_: Option<Path>, for_: Type, items: Vec<Item>| {
         let kind = ImplItem(Impl {
             span: types::rustc_span(tcx.hir().local_def_id(hir_id).to_def_id(), tcx),
             unsafety: impl_.unsafety,
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 7b0d331045c..a5f71c4a849 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1473,6 +1473,15 @@ impl Type {
         }
     }
 
+    // FIXME: temporary
+    #[track_caller]
+    crate fn expect_path(self) -> Path {
+        match self {
+            ResolvedPath { path, .. } => path,
+            _ => panic!("not a ResolvedPath: {:?}", self),
+        }
+    }
+
     crate fn is_self_type(&self) -> bool {
         match *self {
             Generic(name) => name == kw::SelfUpper,
@@ -1481,21 +1490,8 @@ impl Type {
     }
 
     crate fn generics(&self) -> Option<Vec<&Type>> {
-        match *self {
-            ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| {
-                if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
-                    Some(
-                        args.iter()
-                            .filter_map(|arg| match arg {
-                                GenericArg::Type(ty) => Some(ty),
-                                _ => None,
-                            })
-                            .collect(),
-                    )
-                } else {
-                    None
-                }
-            }),
+        match self {
+            ResolvedPath { path, .. } => path.generics(),
             _ => None,
         }
     }
@@ -1993,6 +1989,34 @@ impl Path {
             _ => false,
         }
     }
+
+    crate fn generics(&self) -> Option<Vec<&Type>> {
+        self.segments.last().and_then(|seg| {
+            if let GenericArgs::AngleBracketed { ref args, .. } = seg.args {
+                Some(
+                    args.iter()
+                        .filter_map(|arg| match arg {
+                            GenericArg::Type(ty) => Some(ty),
+                            _ => None,
+                        })
+                        .collect(),
+                )
+            } else {
+                None
+            }
+        })
+    }
+}
+
+// FIXME: this is temporary
+impl GetDefId for Path {
+    fn def_id(&self) -> Option<DefId> {
+        Some(self.res.def_id())
+    }
+
+    fn def_id_full(&self, _: &Cache) -> Option<DefId> {
+        self.def_id()
+    }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -2136,7 +2160,7 @@ crate struct Impl {
     crate span: Span,
     crate unsafety: hir::Unsafety,
     crate generics: Generics,
-    crate trait_: Option<Type>,
+    crate trait_: Option<Path>,
     crate for_: Type,
     crate items: Vec<Item>,
     crate negative_polarity: bool,
diff --git a/src/librustdoc/formats/mod.rs b/src/librustdoc/formats/mod.rs
index 6060b0560cf..86e867d4006 100644
--- a/src/librustdoc/formats/mod.rs
+++ b/src/librustdoc/formats/mod.rs
@@ -14,7 +14,7 @@ use crate::formats::cache::Cache;
 /// impl.
 crate enum AssocItemRender<'a> {
     All,
-    DerefFor { trait_: &'a clean::Type, type_: &'a clean::Type, deref_mut_: bool },
+    DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
 }
 
 /// For different handling of associated items from the Deref target of a type rather than the type
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index bcd78b2adc0..4338ed7160c 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -979,6 +979,15 @@ impl clean::Type {
     }
 }
 
+impl clean::Path {
+    crate fn print<'b, 'a: 'b, 'tcx: 'a>(
+        &'a self,
+        cx: &'a Context<'tcx>,
+    ) -> impl fmt::Display + 'b + Captures<'tcx> {
+        display_fn(move |f| resolved_path(f, self.res.def_id(), self, false, false, cx))
+    }
+}
+
 impl clean::Impl {
     crate fn print<'a, 'tcx: 'a>(
         &'a self,
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 1f27357f6c6..83cd2af169a 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2056,10 +2056,10 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea
 
 fn get_id_for_impl_on_foreign_type(
     for_: &clean::Type,
-    trait_: &clean::Type,
+    trait_: &clean::Path,
     cx: &Context<'_>,
 ) -> String {
-    small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx),))
+    small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx)))
 }
 
 fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index ea81b041c3b..df9a07499ac 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -507,6 +507,11 @@ impl FromWithTcx<clean::Impl> for Impl {
             blanket_impl,
             span: _span,
         } = impl_;
+        // FIXME: should `trait_` be a Path in JSON?
+        let trait_ = trait_.map(|path| {
+            let did = path.res.def_id();
+            clean::ResolvedPath { path, did }.into_tcx(tcx)
+        });
         Impl {
             is_unsafe: unsafety == rustc_hir::Unsafety::Unsafe,
             generics: generics.into_tcx(tcx),
@@ -514,7 +519,7 @@ impl FromWithTcx<clean::Impl> for Impl {
                 .into_iter()
                 .map(|x| x.to_string())
                 .collect(),
-            trait_: trait_.map(|x| x.into_tcx(tcx)),
+            trait_,
             for_: for_.into_tcx(tcx),
             items: ids(items),
             negative: negative_polarity,
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index eefe50caa34..e8aa37c8868 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -78,7 +78,9 @@ crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
     new_items.retain(|it| {
         if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
             cleaner.keep_impl(for_)
-                || trait_.as_ref().map_or(false, |t| cleaner.keep_impl(t))
+                || trait_
+                    .as_ref()
+                    .map_or(false, |t| cleaner.keep_impl_with_def_id(t.res.def_id().into()))
                 || blanket_impl.is_some()
         } else {
             true