diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2021-01-28 16:23:41 +0100 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2021-02-05 17:23:54 +0100 |
| commit | 8e0d1cefd3963803693dc0940f7c1b32fef1b3d6 (patch) | |
| tree | 565529b6c3301f387579a113071a0991dc267573 /src | |
| parent | 4810910b0b2be1f28a2ed666ad1a3825b00bb933 (diff) | |
| download | rust-8e0d1cefd3963803693dc0940f7c1b32fef1b3d6.tar.gz rust-8e0d1cefd3963803693dc0940f7c1b32fef1b3d6.zip | |
Improve html::render::cache::get_real_types code
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustdoc/clean/types.rs | 4 | ||||
| -rw-r--r-- | src/librustdoc/html/render/cache.rs | 128 |
2 files changed, 127 insertions, 5 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index efa7fcc6838..ca8ee8ac82d 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1408,14 +1408,14 @@ impl Type { } } - crate fn generics(&self) -> Option<Vec<Type>> { + crate fn generics(&self) -> Option<Vec<&Type>> { match *self { ResolvedPath { ref path, .. } => path.segments.last().and_then(|seg| { if let GenericArgs::AngleBracketed { ref args, .. } = seg.args { Some( args.iter() .filter_map(|arg| match arg { - GenericArg::Type(ty) => Some(ty.clone()), + GenericArg::Type(ty) => Some(ty), _ => None, }) .collect(), diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index e47692063bd..821f1cc71a3 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -70,8 +70,6 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< let mut crate_items = Vec::with_capacity(cache.search_index.len()); let mut crate_paths = vec![]; - // For now we don't get the primitive types in the search index. - let empty_cache = Cache::default(); // Attach all orphan items to the type's definition if the type // has since been learned. for &(did, ref item) in &cache.orphan_impl_items { @@ -83,7 +81,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< desc: item.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)), parent: Some(did), parent_idx: None, - search_type: get_index_search_type(&item, cache), + search_type: get_index_search_type(&item, cache, tcx), }); for alias in item.attrs.get_doc_aliases() { cache @@ -248,3 +246,127 @@ fn get_generics(clean_type: &clean::Type, cache: &Cache) -> Option<Vec<Generic>> if r.is_empty() { None } else { Some(r) } }) } + +/// The point of this function is to replace bounds with types. +/// +/// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option<T>` will return +/// `[Display, Option]` (we just returns the list of the types, we don't care about the +/// wrapped types in here). +crate fn get_real_types<'tcx>( + generics: &Generics, + arg: &Type, + tcx: TyCtxt<'tcx>, + recurse: i32, + cache: &Cache, + res: &mut FxHashSet<(Type, TypeKind)>, +) -> usize { + fn insert(res: &mut FxHashSet<(Type, TypeKind)>, tcx: TyCtxt<'_>, ty: Type) -> usize { + if let Some(kind) = ty.def_id().map(|did| tcx.def_kind(did).into()) { + res.insert((ty, kind)); + 1 + } else if ty.is_primitive() { + // This is a primitive, let's store it as such. + res.insert((ty, TypeKind::Primitive)); + 1 + } else { + 0 + } + } + + if recurse >= 10 { + // FIXME: remove this whole recurse thing when the recursion bug is fixed + return 0; + } + let mut nb_added = 0; + + if arg.is_full_generic() { + let arg_s = Symbol::intern(&arg.print(cache).to_string()); + if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g { + WherePredicate::BoundPredicate { ty, .. } => ty.def_id() == arg.def_id(), + _ => false, + }) { + let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]); + for bound in bounds.iter() { + if let GenericBound::TraitBound(poly_trait, _) = bound { + for x in poly_trait.generic_params.iter() { + if !x.is_type() { + continue; + } + if let Some(ty) = x.get_type() { + let adds = get_real_types(generics, &ty, tcx, recurse + 1, cache, res); + nb_added += adds; + if adds == 0 && !ty.is_full_generic() { + nb_added += insert(res, tcx, ty); + } + } + } + } + } + } + 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() { + let adds = get_real_types(generics, &ty, tcx, recurse + 1, cache, res); + nb_added += adds; + if adds == 0 && !ty.is_full_generic() { + nb_added += insert(res, tcx, ty); + } + } + } + } + } else { + nb_added += insert(res, tcx, arg.clone()); + if let Some(gens) = arg.generics() { + for gen in gens.iter() { + if gen.is_full_generic() { + nb_added += get_real_types(generics, gen, tcx, recurse + 1, cache, res); + } else { + nb_added += insert(res, tcx, (*gen).clone()); + } + } + } + } + nb_added +} + +/// Return the full list of types when bounds have been resolved. +/// +/// i.e. `fn foo<A: Display, B: Option<A>>(x: u32, y: B)` will return +/// `[u32, Display, Option]`. +crate fn get_all_types<'tcx>( + generics: &Generics, + decl: &FnDecl, + tcx: TyCtxt<'tcx>, + cache: &Cache, +) -> (Vec<(Type, TypeKind)>, Vec<(Type, TypeKind)>) { + let mut all_types = FxHashSet::default(); + for arg in decl.inputs.values.iter() { + if arg.type_.is_self_type() { + continue; + } + let mut args = FxHashSet::default(); + get_real_types(generics, &arg.type_, tcx, 0, cache, &mut args); + if !args.is_empty() { + all_types.extend(args); + } else { + if let Some(kind) = arg.type_.def_id().map(|did| tcx.def_kind(did).into()) { + all_types.insert((arg.type_.clone(), kind)); + } + } + } + + let ret_types = match decl.output { + FnRetTy::Return(ref return_type) => { + let mut ret = FxHashSet::default(); + get_real_types(generics, &return_type, tcx, 0, cache, &mut ret); + if ret.is_empty() { + if let Some(kind) = return_type.def_id().map(|did| tcx.def_kind(did).into()) { + ret.insert((return_type.clone(), kind)); + } + } + ret.into_iter().collect() + } + _ => Vec::new(), + }; + (all_types.into_iter().collect(), ret_types) +} |
