]> git.lizzy.rs Git - rust.git/commitdiff
rustdoc: don't mark Box<T> as Iterator, Read, etc
authorJacob Hoffman-Andrews <github@hoffman-andrews.com>
Sun, 23 Oct 2022 09:47:20 +0000 (02:47 -0700)
committerJacob Hoffman-Andrews <github@hoffman-andrews.com>
Mon, 24 Oct 2022 05:14:10 +0000 (22:14 -0700)
Because Box<T> has pass-through implementations, rustdoc was giving it the
"Notable Traits" treatment for Iterator, Read, Write, and Future, even when the
type of T was unspecified.

Pin had the same problem, but just for Future.

src/librustdoc/html/render/mod.rs
src/test/rustdoc/doc-notable_trait_box_is_not_an_iterator.rs [new file with mode: 0644]

index cd56d73e7d47b4e3151cbe842e600dd1f61ef2cb..b2fac7228272a0055d30deca512059d853e4568b 100644 (file)
@@ -1276,6 +1276,15 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String {
 
     if let Some((did, ty)) = decl.output.as_return().and_then(|t| Some((t.def_id(cx.cache())?, t)))
     {
+        // Box has pass-through impls for Read, Write, Iterator, and Future when the
+        // boxed type implements one of those. We don't want to treat every Box return
+        // as being notably an Iterator (etc), though, so we exempt it. Pin has the same
+        // issue, with a pass-through impl for Future.
+        if Some(did) == cx.tcx().lang_items().owned_box()
+            || Some(did) == cx.tcx().lang_items().pin_type()
+        {
+            return "".to_string();
+        }
         if let Some(impls) = cx.cache().impls.get(&did) {
             for i in impls {
                 let impl_ = i.inner_impl();
diff --git a/src/test/rustdoc/doc-notable_trait_box_is_not_an_iterator.rs b/src/test/rustdoc/doc-notable_trait_box_is_not_an_iterator.rs
new file mode 100644 (file)
index 0000000..3fb00c7
--- /dev/null
@@ -0,0 +1,38 @@
+#![feature(doc_notable_trait)]
+#![feature(lang_items)]
+#![feature(no_core)]
+#![no_core]
+#[lang = "owned_box"]
+pub struct Box<T>;
+
+impl<T> Box<T> {
+    pub fn new(x: T) -> Box<T> {
+        Box
+    }
+}
+
+#[doc(notable_trait)]
+pub trait FakeIterator {}
+
+impl<I: FakeIterator> FakeIterator for Box<I> {}
+
+#[lang = "pin"]
+pub struct Pin<T>;
+
+impl<T> Pin<T> {
+    pub fn new(x: T) -> Pin<T> {
+        Pin
+    }
+}
+
+impl<I: FakeIterator> FakeIterator for Pin<I> {}
+
+// @!has doc_notable_trait_box_is_not_an_iterator/fn.foo.html '//*' 'Notable'
+pub fn foo<T>(x: T) -> Box<T> {
+    Box::new(x)
+}
+
+// @!has doc_notable_trait_box_is_not_an_iterator/fn.bar.html '//*' 'Notable'
+pub fn bar<T>(x: T) -> Pin<T> {
+    Pin::new(x)
+}