From 6bce61cd4b20ae0661a1a7bd656cebc999b5a2ee Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 7 Mar 2019 22:47:43 +0100 Subject: [PATCH] Fix invalid returned types generation --- src/librustdoc/clean/mod.rs | 80 +++++++++++++++--------------- src/librustdoc/html/render.rs | 26 +++++++--- src/librustdoc/html/static/main.js | 3 ++ 3 files changed, 63 insertions(+), 46 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 415d03184074..c41d02fbfbbc 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 { + 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 ec93bbbf9be6..930f3fd3c5c8 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, - output: Vec, + output: Option>, } 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 { 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::>(); + 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 c9880f4c4117..94247b2fa456 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]; }