From 04a884726a5a332aefd0af96c8d702b0830e5375 Mon Sep 17 00:00:00 2001
From: Oliver Middleton <olliemail27@gmail.com>
Date: Tue, 23 Jan 2018 01:04:24 +0000
Subject: [PATCH] rustdoc: Show when traits are auto traits

---
 src/librustdoc/clean/inline.rs            |  2 ++
 src/librustdoc/clean/mod.rs               | 11 +++++++++++
 src/librustdoc/doctree.rs                 |  1 +
 src/librustdoc/html/render.rs             |  3 ++-
 src/librustdoc/visit_ast.rs               |  3 ++-
 src/test/rustdoc/auto-traits.rs           | 23 +++++++++++++++++++++++
 src/test/rustdoc/auxiliary/auto-traits.rs | 13 +++++++++++++
 7 files changed, 54 insertions(+), 2 deletions(-)
 create mode 100644 src/test/rustdoc/auto-traits.rs
 create mode 100644 src/test/rustdoc/auxiliary/auto-traits.rs

diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index b8c34d78d305e..3cdc558080aa2 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -146,12 +146,14 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
     let generics = filter_non_trait_generics(did, generics);
     let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
     let is_spotlight = load_attrs(cx, did).has_doc_flag("spotlight");
+    let is_auto = cx.tcx.trait_is_auto(did);
     clean::Trait {
         unsafety: cx.tcx.trait_def(did).unsafety,
         generics,
         items: trait_items,
         bounds: supertrait_bounds,
         is_spotlight,
+        is_auto,
     }
 }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index cc75664cacbcc..c43aec79447a0 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1523,6 +1523,7 @@ pub struct Trait {
     pub generics: Generics,
     pub bounds: Vec<TyParamBound>,
     pub is_spotlight: bool,
+    pub is_auto: bool,
 }
 
 impl Clean<Item> for doctree::Trait {
@@ -1543,11 +1544,21 @@ impl Clean<Item> for doctree::Trait {
                 generics: self.generics.clean(cx),
                 bounds: self.bounds.clean(cx),
                 is_spotlight: is_spotlight,
+                is_auto: self.is_auto.clean(cx),
             }),
         }
     }
 }
 
+impl Clean<bool> for hir::IsAuto {
+    fn clean(&self, _: &DocContext) -> bool {
+        match *self {
+            hir::IsAuto::Yes => true,
+            hir::IsAuto::No => false,
+        }
+    }
+}
+
 impl Clean<Type> for hir::TraitRef {
     fn clean(&self, cx: &DocContext) -> Type {
         resolve_type(cx, self.path.clean(cx), self.ref_id)
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index 776ec7f409c44..430236f30c4ef 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -196,6 +196,7 @@ pub struct Constant {
 }
 
 pub struct Trait {
+    pub is_auto: hir::IsAuto,
     pub unsafety: hir::Unsafety,
     pub name: Name,
     pub items: hir::HirVec<hir::TraitItem>,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index cfa09ea30a8be..fae6f9ec6a3c0 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -2339,9 +2339,10 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
     // Output the trait definition
     write!(w, "<pre class='rust trait'>")?;
     render_attributes(w, it)?;
-    write!(w, "{}{}trait {}{}{}",
+    write!(w, "{}{}{}trait {}{}{}",
            VisSpace(&it.visibility),
            UnsafetySpace(t.unsafety),
+           if t.is_auto { "auto " } else { "" },
            it.name.as_ref().unwrap(),
            t.generics,
            bounds)?;
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 1cb52d735bb18..ed69bce11a0dd 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -494,11 +494,12 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                 };
                 om.constants.push(s);
             },
-            hir::ItemTrait(_, unsafety, ref gen, ref b, ref item_ids) => {
+            hir::ItemTrait(is_auto, unsafety, ref gen, ref b, ref item_ids) => {
                 let items = item_ids.iter()
                                     .map(|ti| self.cx.tcx.hir.trait_item(ti.id).clone())
                                     .collect();
                 let t = Trait {
+                    is_auto,
                     unsafety,
                     name,
                     items,
diff --git a/src/test/rustdoc/auto-traits.rs b/src/test/rustdoc/auto-traits.rs
new file mode 100644
index 0000000000000..1753c0ebf7353
--- /dev/null
+++ b/src/test/rustdoc/auto-traits.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:auto-traits.rs
+
+#![feature(optin_builtin_traits)]
+
+#![crate_name = "foo"]
+
+extern crate auto_traits;
+
+// @has 'foo/trait.Foo.html' '//pre' 'pub unsafe auto trait Foo'
+pub unsafe auto trait Foo {}
+
+// @has 'foo/trait.Bar.html' '//pre' 'pub unsafe auto trait Bar'
+pub use auto_traits::Bar;
diff --git a/src/test/rustdoc/auxiliary/auto-traits.rs b/src/test/rustdoc/auxiliary/auto-traits.rs
new file mode 100644
index 0000000000000..70299334b4609
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/auto-traits.rs
@@ -0,0 +1,13 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(optin_builtin_traits)]
+
+pub unsafe auto trait Bar {}