about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2024-08-10 16:23:55 +0200
committerGitHub <noreply@github.com>2024-08-10 16:23:55 +0200
commit893b9f3a5ad65e568556bb539be475640ddbf501 (patch)
tree8e08857c6b3d5bcb63b9d6f3811a80c7b6ae7720
parent50e9fd1a1d0c8a8c5e849fbe3bd69b1e6a6a9829 (diff)
parent5baf7c21cfb872a82714d0f59a78bd37b6db5236 (diff)
downloadrust-893b9f3a5ad65e568556bb539be475640ddbf501.tar.gz
rust-893b9f3a5ad65e568556bb539be475640ddbf501.zip
Rollup merge of #128923 - GuillaumeGomez:negative-impls-items, r=fmease
[rustdoc] Stop showing impl items for negative impls

Fixes https://github.com/rust-lang/rust/issues/128799.

As discussed with `@fmease,` they have a broader patch in progress, so this (small) PR will at least allow for them to have a regression test. :)

r? `@fmease`
-rw-r--r--src/librustdoc/clean/types.rs4
-rw-r--r--src/librustdoc/html/format.rs5
-rw-r--r--src/librustdoc/html/render/mod.rs37
-rw-r--r--tests/rustdoc/negative-impl-no-items.rs26
4 files changed, 53 insertions, 19 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 4850500a1bf..ff5c16f2b3e 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -2446,6 +2446,10 @@ impl Impl {
             .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.name).collect())
             .unwrap_or_default()
     }
+
+    pub(crate) fn is_negative_trait_impl(&self) -> bool {
+        matches!(self.polarity, ty::ImplPolarity::Negative)
+    }
 }
 
 #[derive(Clone, Debug)]
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index b5ab6a35fdb..6357cfee141 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -1285,9 +1285,8 @@ impl clean::Impl {
             f.write_str(" ")?;
 
             if let Some(ref ty) = self.trait_ {
-                match self.polarity {
-                    ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => {}
-                    ty::ImplPolarity::Negative => write!(f, "!")?,
+                if self.is_negative_trait_impl() {
+                    write!(f, "!")?;
                 }
                 ty.print(cx).fmt(f)?;
                 write!(f, " for ")?;
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 9074e40a536..7ce637d3ab4 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1780,20 +1780,23 @@ fn render_impl(
 
     let mut impl_items = Buffer::empty_from(w);
     let mut default_impl_items = Buffer::empty_from(w);
+    let impl_ = i.inner_impl();
 
-    for trait_item in &i.inner_impl().items {
-        doc_impl_item(
-            &mut default_impl_items,
-            &mut impl_items,
-            cx,
-            trait_item,
-            if trait_.is_some() { &i.impl_item } else { parent },
-            link,
-            render_mode,
-            false,
-            trait_,
-            rendering_params,
-        );
+    if !impl_.is_negative_trait_impl() {
+        for trait_item in &impl_.items {
+            doc_impl_item(
+                &mut default_impl_items,
+                &mut impl_items,
+                cx,
+                trait_item,
+                if trait_.is_some() { &i.impl_item } else { parent },
+                link,
+                render_mode,
+                false,
+                trait_,
+                rendering_params,
+            );
+        }
     }
 
     fn render_default_items(
@@ -1844,13 +1847,15 @@ fn render_impl(
     // We don't emit documentation for default items if they appear in the
     // Implementations on Foreign Types or Implementors sections.
     if rendering_params.show_default_items {
-        if let Some(t) = trait_ {
+        if let Some(t) = trait_
+            && !impl_.is_negative_trait_impl()
+        {
             render_default_items(
                 &mut default_impl_items,
                 &mut impl_items,
                 cx,
                 t,
-                i.inner_impl(),
+                impl_,
                 &i.impl_item,
                 render_mode,
                 rendering_params,
@@ -1882,7 +1887,7 @@ fn render_impl(
         }
 
         if let Some(ref dox) = i.impl_item.opt_doc_value() {
-            if trait_.is_none() && i.inner_impl().items.is_empty() {
+            if trait_.is_none() && impl_.items.is_empty() {
                 w.write_str(
                     "<div class=\"item-info\">\
                          <div class=\"stab empty-impl\">This impl block contains no items.</div>\
diff --git a/tests/rustdoc/negative-impl-no-items.rs b/tests/rustdoc/negative-impl-no-items.rs
new file mode 100644
index 00000000000..c628e542033
--- /dev/null
+++ b/tests/rustdoc/negative-impl-no-items.rs
@@ -0,0 +1,26 @@
+// This test ensures that negative impls don't have items listed inside them.
+
+#![feature(negative_impls)]
+#![crate_name = "foo"]
+
+pub struct Thing;
+
+//@ has 'foo/struct.Thing.html'
+// We check the full path to ensure there is no `<details>` element.
+//@ has - '//div[@id="trait-implementations-list"]/section[@id="impl-Iterator-for-Thing"]/h3' \
+// 'impl !Iterator for Thing'
+impl !Iterator for Thing {}
+
+// This struct will allow us to compare both paths.
+pub struct Witness;
+
+//@ has 'foo/struct.Witness.html'
+//@ has - '//div[@id="trait-implementations-list"]/details//section[@id="impl-Iterator-for-Witness"]/h3' \
+// 'impl Iterator for Witness'
+impl Iterator for Witness {
+    type Item = u8;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        None
+    }
+}