about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2019-03-07 22:47:43 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2019-03-21 22:49:43 +0100
commit6bce61cd4b20ae0661a1a7bd656cebc999b5a2ee (patch)
tree0f17e0fabef829de87504d1524207f589d6b9eed
parentaefe75095adf8a5c6714a5c89b3899d4f9570514 (diff)
downloadrust-6bce61cd4b20ae0661a1a7bd656cebc999b5a2ee.tar.gz
rust-6bce61cd4b20ae0661a1a7bd656cebc999b5a2ee.zip
Fix invalid returned types generation
-rw-r--r--src/librustdoc/clean/mod.rs80
-rw-r--r--src/librustdoc/html/render.rs26
-rw-r--r--src/librustdoc/html/static/main.js3
3 files changed, 63 insertions, 46 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 415d0318407..c41d02fbfbb 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1755,55 +1755,59 @@ fn get_real_types(
     generics: &Generics,
     arg: &Type,
     cx: &DocContext<'_, '_, '_>,
-) -> Option<Vec<Type>> {
+) -> Vec<Type> {
+    let arg_s = arg.to_string();
     let mut res = Vec::new();
-    if let Some(where_pred) = generics.where_predicates.iter().find(|g| {
-        match g {
-            &WherePredicate::BoundPredicate { ref ty, .. } => ty.def_id() == arg.def_id(),
-            _ => false,
-        }
-    }) {
-        let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);
-        for bound in bounds.iter() {
-            match *bound {
-                GenericBound::TraitBound(ref poly_trait, _) => {
-                    for x in poly_trait.generic_params.iter() {
-                        if !x.is_type() {
-                            continue
-                        }
-                        if let Some(ty) = x.get_type(cx) {
-                            if let Some(mut adds) = get_real_types(generics, &ty, cx) {
-                                res.append(&mut adds);
-                            } else if !ty.is_full_generic() {
-                                res.push(ty);
+    if arg.is_full_generic() {
+        if let Some(where_pred) = generics.where_predicates.iter().find(|g| {
+            match g {
+                &WherePredicate::BoundPredicate { ref ty, .. } => ty.def_id() == arg.def_id(),
+                _ => false,
+            }
+        }) {
+            let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);
+            for bound in bounds.iter() {
+                match *bound {
+                    GenericBound::TraitBound(ref poly_trait, _) => {
+                        for x in poly_trait.generic_params.iter() {
+                            if !x.is_type() {
+                                continue
+                            }
+                            if let Some(ty) = x.get_type(cx) {
+                                let mut adds = get_real_types(generics, &ty, cx);
+                                if !adds.is_empty() {
+                                    res.append(&mut adds);
+                                } else if !ty.is_full_generic() {
+                                    res.push(ty);
+                                }
                             }
                         }
                     }
+                    _ => {}
                 }
-                _ => {}
             }
         }
-    } else {
-        let arg_s = arg.to_string();
         if let Some(bound) = generics.params.iter().find(|g| {
             g.is_type() && g.name == arg_s
         }) {
             for bound in bound.get_bounds().unwrap_or_else(|| &[]) {
                 if let Some(ty) = bound.get_trait_type() {
-                    if let Some(mut adds) = get_real_types(generics, &ty, cx) {
+                    let mut adds = get_real_types(generics, &ty, cx);
+                    if !adds.is_empty() {
                         res.append(&mut adds);
-                    } else {
-                        if !ty.is_full_generic() {
-                            res.push(ty.clone());
-                        }
+                    } else if !ty.is_full_generic() {
+                        res.push(ty.clone());
                     }
                 }
             }
-        } else if let Some(gens) = arg.generics() {
-            res.push(arg.clone());
+        }
+    } else {
+        res.push(arg.clone());
+        if let Some(gens) = arg.generics() {
             for gen in gens.iter() {
                 if gen.is_full_generic() {
-                    if let Some(mut adds) = get_real_types(generics, gen, cx) {
+                    let mut adds = get_real_types(generics, gen, cx);
+                    if !adds.is_empty() {
                         res.append(&mut adds);
                     }
                 } else {
@@ -1812,10 +1816,7 @@ fn get_real_types(
             }
         }
     }
-    if res.is_empty() && !arg.is_full_generic() {
-        res.push(arg.clone());
-    }
-    Some(res)
+    res
 }
 
 pub fn get_all_types(
@@ -1828,7 +1829,8 @@ pub fn get_all_types(
         if arg.type_.is_self_type() {
             continue;
         }
-        if let Some(mut args) = get_real_types(generics, &arg.type_, cx) {
+        let mut args = get_real_types(generics, &arg.type_, cx);
+        if !args.is_empty() {
             all_types.append(&mut args);
         } else {
             all_types.push(arg.type_.clone());
@@ -1840,10 +1842,8 @@ pub fn get_all_types(
 
     let mut ret_types = match decl.output {
         FunctionRetTy::Return(ref return_type) => {
-            let mut ret = Vec::new();
-            if let Some(mut args) = get_real_types(generics, &return_type, cx) {
-                ret.append(&mut args);
-            } else {
+            let mut ret = get_real_types(generics, &return_type, cx);
+            if ret.is_empty() {
                 ret.push(return_type.clone());
             }
             ret
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index ec93bbbf9be..930f3fd3c5c 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -455,19 +455,27 @@ impl ToJson for Type {
 #[derive(Debug)]
 struct IndexItemFunctionType {
     inputs: Vec<Type>,
-    output: Vec<Type>,
+    output: Option<Vec<Type>>,
 }
 
 impl ToJson for IndexItemFunctionType {
     fn to_json(&self) -> Json {
         // If we couldn't figure out a type, just write `null`.
-        if self.inputs.iter().chain(self.output.iter()).any(|ref i| i.name.is_none()) {
+        let mut iter = self.inputs.iter();
+        if match self.output {
+            Some(ref output) => iter.chain(output.iter()).any(|ref i| i.name.is_none()),
+            None => iter.any(|ref i| i.name.is_none()),
+        } {
             Json::Null
         } else {
             let mut data = Vec::with_capacity(2);
             data.push(self.inputs.to_json());
-            if !self.output.is_empty() {
-                data.push(self.output.to_json());
+            if let Some(ref output) = self.output {
+                if output.len() > 1 {
+                    data.push(output.to_json());
+                } else {
+                    data.push(output[0].to_json());
+                }
             }
             Json::Array(data)
         }
@@ -5034,11 +5042,17 @@ fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {
 
     let inputs = all_types.iter().map(|arg| {
         get_index_type(&arg)
-    }).collect();
+    }).filter(|a| a.name.is_some()).collect();
     let output = ret_types.iter().map(|arg| {
         get_index_type(&arg)
-    }).collect();
+    }).filter(|a| a.name.is_some()).collect::<Vec<_>>();
+    let output = if output.is_empty() {
+        None
+    } else {
+        Some(output)
+    };
 
+    println!("===> {:?}", output);
     Some(IndexItemFunctionType { inputs, output })
 }
 
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index c9880f4c411..94247b2fa45 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -756,6 +756,9 @@ if (!DOMTokenList.prototype.remove) {
 
                 if (obj && obj.type && obj.type.length > OUTPUT_DATA) {
                     var ret = obj.type[OUTPUT_DATA];
+                    //if (obj.name === "xo") {
+                    //    debugger;
+                    //}
                     if (!obj.type[OUTPUT_DATA].length) {
                         ret = [ret];
                     }