about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2017-12-17 14:08:09 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2017-12-18 10:44:26 +0100
commit0df39bfff7840800454d6704fe4eee646d1f0ec7 (patch)
tree557b9d40e8721ac0c918823950932d8d90033b84
parentbdae618418abc58a1da5e565f2b124cdfebb5682 (diff)
downloadrust-0df39bfff7840800454d6704fe4eee646d1f0ec7.tar.gz
rust-0df39bfff7840800454d6704fe4eee646d1f0ec7.zip
Fix ?Sized where bound not being displayed at the correct place
-rw-r--r--src/librustdoc/clean/inline.rs3
-rw-r--r--src/librustdoc/clean/mod.rs26
-rw-r--r--src/librustdoc/clean/simplify.rs1
-rw-r--r--src/test/rustdoc/where-sized.rs16
4 files changed, 41 insertions, 5 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 60592cc186e..914365b003e 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -448,8 +448,7 @@ fn build_static(cx: &DocContext, did: DefId, mutable: bool) -> clean::Static {
 ///
 /// The inverse of this filtering logic can be found in the `Clean`
 /// implementation for `AssociatedType`
-fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics)
-                             -> clean::Generics {
+fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean::Generics {
     for pred in &mut g.where_predicates {
         match *pred {
             clean::WherePredicate::BoundPredicate {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 91908de98a6..fe7dfc4477f 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1190,16 +1190,36 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
 pub struct Generics {
     pub lifetimes: Vec<Lifetime>,
     pub type_params: Vec<TyParam>,
-    pub where_predicates: Vec<WherePredicate>
+    pub where_predicates: Vec<WherePredicate>,
 }
 
 impl Clean<Generics> for hir::Generics {
     fn clean(&self, cx: &DocContext) -> Generics {
-        Generics {
+        let mut g = Generics {
             lifetimes: self.lifetimes.clean(cx),
             type_params: self.ty_params.clean(cx),
             where_predicates: self.where_clause.predicates.clean(cx)
+        };
+
+        // Some duplicates are generated for ?Sized bounds between type params and where
+        // predicates. The point in here is to move the bounds definitions from type params
+        // to where predicates when such cases occur.
+        for where_pred in &mut g.where_predicates {
+            match *where_pred {
+                WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
+                    if bounds.is_empty() {
+                        for type_params in &mut g.type_params {
+                            if &type_params.name == name {
+                                mem::swap(bounds, &mut type_params.bounds);
+                                break
+                            }
+                        }
+                    }
+                }
+                _ => continue,
+            }
         }
+        g
     }
 }
 
@@ -1225,7 +1245,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
         let mut where_predicates = preds.predicates.to_vec().clean(cx);
 
         // Type parameters and have a Sized bound by default unless removed with
-        // ?Sized.  Scan through the predicates and mark any type parameter with
+        // ?Sized. Scan through the predicates and mark any type parameter with
         // a Sized bound, removing the bounds as we find them.
         //
         // Note that associated types also have a sized bound by default, but we
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index dd36b28bb39..63ebb16e5e0 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -38,6 +38,7 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec<WP>) -> Vec<WP> {
     let mut lifetimes = Vec::new();
     let mut equalities = Vec::new();
     let mut tybounds = Vec::new();
+
     for clause in clauses {
         match clause {
             WP::BoundPredicate { ty, bounds } => {
diff --git a/src/test/rustdoc/where-sized.rs b/src/test/rustdoc/where-sized.rs
new file mode 100644
index 00000000000..c175c839c0f
--- /dev/null
+++ b/src/test/rustdoc/where-sized.rs
@@ -0,0 +1,16 @@
+// Copyright 2017 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.
+
+#![crate_name = "foo"]
+
+// @has foo/fn.foo.html
+// @has - '//*[@class="rust fn"]' 'pub fn foo<X, Y: ?Sized>(_: &X)'
+// @has - '//*[@class="rust fn"]' 'where X: ?Sized,'
+pub fn foo<X, Y: ?Sized>(_: &X) where X: ?Sized {}