1
Fork 0

Rollup merge of #92340 - camelid:search-index-cleanup, r=GuillaumeGomez

rustdoc: Start cleaning up search index generation

I'm trying to simplify and clean up the code, partly to make #90779 easier.

r? `@GuillaumeGomez`
This commit is contained in:
Matthias Krüger 2021-12-29 10:17:11 +01:00 committed by GitHub
commit 0e4119488d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 65 additions and 50 deletions

View file

@ -39,7 +39,6 @@ use crate::clean::Clean;
use crate::core::DocContext; use crate::core::DocContext;
use crate::formats::cache::Cache; use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::html::render::cache::ExternalLocation;
use crate::html::render::Context; use crate::html::render::Context;
use crate::passes::collect_intra_doc_links::UrlFragment; use crate::passes::collect_intra_doc_links::UrlFragment;
@ -339,6 +338,16 @@ impl ExternalCrate {
} }
} }
/// Indicates where an external crate can be found.
crate enum ExternalLocation {
/// Remote URL root of the external crate
Remote(String),
/// This external crate can be found in the local doc/ folder
Local,
/// The external crate could not be found.
Unknown,
}
/// Anything with a source location and set of attributes and, optionally, a /// Anything with a source location and set of attributes and, optionally, a
/// name. That is, anything that can be documented. This doesn't correspond /// name. That is, anything that can be documented. This doesn't correspond
/// directly to the AST's concept of an item; it's a strict superset. /// directly to the AST's concept of an item; it's a strict superset.

View file

@ -6,13 +6,13 @@ use rustc_middle::middle::privacy::AccessLevels;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use crate::clean::{self, ExternalCrate, ItemId, PrimitiveType}; use crate::clean::{self, types::ExternalLocation, ExternalCrate, ItemId, PrimitiveType};
use crate::core::DocContext; use crate::core::DocContext;
use crate::fold::DocFolder; use crate::fold::DocFolder;
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::formats::Impl; use crate::formats::Impl;
use crate::html::markdown::short_markdown_summary; use crate::html::markdown::short_markdown_summary;
use crate::html::render::cache::{get_index_search_type, ExternalLocation}; use crate::html::render::search_index::get_function_type_for_search;
use crate::html::render::IndexItem; use crate::html::render::IndexItem;
/// This cache is used to store information about the [`clean::Crate`] being /// This cache is used to store information about the [`clean::Crate`] being
@ -303,7 +303,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
desc, desc,
parent, parent,
parent_idx: None, parent_idx: None,
search_type: get_index_search_type(&item, self.tcx, self.cache), search_type: get_function_type_for_search(&item, self.tcx),
aliases: item.attrs.get_doc_aliases(), aliases: item.attrs.get_doc_aliases(),
}); });
} }

View file

@ -21,10 +21,12 @@ use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::CRATE_DEF_INDEX; use rustc_span::def_id::CRATE_DEF_INDEX;
use rustc_target::spec::abi::Abi; use rustc_target::spec::abi::Abi;
use crate::clean::{self, utils::find_nearest_parent_module, ExternalCrate, ItemId, PrimitiveType}; use crate::clean::{
self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId,
PrimitiveType,
};
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::html::escape::Escape; use crate::html::escape::Escape;
use crate::html::render::cache::ExternalLocation;
use crate::html::render::Context; use crate::html::render::Context;
use super::url_parts_builder::UrlPartsBuilder; use super::url_parts_builder::UrlPartsBuilder;

View file

@ -13,8 +13,8 @@ use rustc_span::edition::Edition;
use rustc_span::source_map::FileName; use rustc_span::source_map::FileName;
use rustc_span::symbol::sym; use rustc_span::symbol::sym;
use super::cache::{build_index, ExternalLocation};
use super::print_item::{full_path, item_path, print_item}; use super::print_item::{full_path, item_path, print_item};
use super::search_index::build_index;
use super::templates; use super::templates;
use super::write_shared::write_shared; use super::write_shared::write_shared;
use super::{ use super::{
@ -22,7 +22,7 @@ use super::{
BASIC_KEYWORDS, BASIC_KEYWORDS,
}; };
use crate::clean::{self, ExternalCrate}; use crate::clean::{self, types::ExternalLocation, ExternalCrate};
use crate::config::RenderOptions; use crate::config::RenderOptions;
use crate::docfs::{DocFS, PathError}; use crate::docfs::{DocFS, PathError};
use crate::error::Error; use crate::error::Error;

View file

@ -23,7 +23,7 @@
//! These threads are not parallelized (they haven't been a bottleneck yet), and //! These threads are not parallelized (they haven't been a bottleneck yet), and
//! both occur before the crate is rendered. //! both occur before the crate is rendered.
crate mod cache; crate mod search_index;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;

View file

@ -7,22 +7,12 @@ use rustc_span::symbol::Symbol;
use serde::ser::{Serialize, SerializeStruct, Serializer}; use serde::ser::{Serialize, SerializeStruct, Serializer};
use crate::clean; use crate::clean;
use crate::clean::types::{FnDecl, FnRetTy, GenericBound, Generics, Type, WherePredicate}; use crate::clean::types::{FnRetTy, Function, GenericBound, Generics, Type, WherePredicate};
use crate::formats::cache::Cache; use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::html::markdown::short_markdown_summary; use crate::html::markdown::short_markdown_summary;
use crate::html::render::{IndexItem, IndexItemFunctionType, RenderType, TypeWithKind}; use crate::html::render::{IndexItem, IndexItemFunctionType, RenderType, TypeWithKind};
/// Indicates where an external crate can be found.
crate enum ExternalLocation {
/// Remote URL root of the external crate
Remote(String),
/// This external crate can be found in the local doc/ folder
Local,
/// The external crate could not be found.
Unknown,
}
/// Builds the search index from the collected metadata /// Builds the search index from the collected metadata
crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<'tcx>) -> String { crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<'tcx>) -> String {
let mut defid_to_pathid = FxHashMap::default(); let mut defid_to_pathid = FxHashMap::default();
@ -42,7 +32,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
desc, desc,
parent: Some(did), parent: Some(did),
parent_idx: None, parent_idx: None,
search_type: get_index_search_type(item, tcx, cache), search_type: get_function_type_for_search(item, tcx),
aliases: item.attrs.get_doc_aliases(), aliases: item.attrs.get_doc_aliases(),
}); });
} }
@ -191,15 +181,14 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
) )
} }
crate fn get_index_search_type<'tcx>( crate fn get_function_type_for_search<'tcx>(
item: &clean::Item, item: &clean::Item,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
cache: &Cache,
) -> Option<IndexItemFunctionType> { ) -> Option<IndexItemFunctionType> {
let (mut inputs, mut output) = match *item.kind { let (mut inputs, mut output) = match *item.kind {
clean::FunctionItem(ref f) => get_all_types(&f.generics, &f.decl, tcx, cache), clean::FunctionItem(ref f) => get_fn_inputs_and_outputs(f, tcx),
clean::MethodItem(ref m, _) => get_all_types(&m.generics, &m.decl, tcx, cache), clean::MethodItem(ref m, _) => get_fn_inputs_and_outputs(m, tcx),
clean::TyMethodItem(ref m) => get_all_types(&m.generics, &m.decl, tcx, cache), clean::TyMethodItem(ref m) => get_fn_inputs_and_outputs(m, tcx),
_ => return None, _ => return None,
}; };
@ -211,12 +200,12 @@ crate fn get_index_search_type<'tcx>(
fn get_index_type(clean_type: &clean::Type, generics: Vec<TypeWithKind>) -> RenderType { fn get_index_type(clean_type: &clean::Type, generics: Vec<TypeWithKind>) -> RenderType {
RenderType { RenderType {
name: get_index_type_name(clean_type, true).map(|s| s.as_str().to_ascii_lowercase()), name: get_index_type_name(clean_type).map(|s| s.as_str().to_ascii_lowercase()),
generics: if generics.is_empty() { None } else { Some(generics) }, generics: if generics.is_empty() { None } else { Some(generics) },
} }
} }
fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option<Symbol> { fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
match *clean_type { match *clean_type {
clean::Type::Path { ref path, .. } => { clean::Type::Path { ref path, .. } => {
let path_segment = path.segments.last().unwrap(); let path_segment = path.segments.last().unwrap();
@ -226,11 +215,10 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
let path = &bounds[0].trait_; let path = &bounds[0].trait_;
Some(path.segments.last().unwrap().name) Some(path.segments.last().unwrap().name)
} }
clean::Generic(s) if accept_generic => Some(s), clean::Generic(s) => Some(s),
clean::Primitive(ref p) => Some(p.as_sym()), clean::Primitive(ref p) => Some(p.as_sym()),
clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_, accept_generic), clean::BorrowedRef { ref type_, .. } => get_index_type_name(type_),
clean::Generic(_) clean::BareFunction(_)
| clean::BareFunction(_)
| clean::Tuple(_) | clean::Tuple(_)
| clean::Slice(_) | clean::Slice(_)
| clean::Array(_, _) | clean::Array(_, _)
@ -248,20 +236,19 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
/// ///
/// Important note: It goes through generics recursively. So if you have /// Important note: It goes through generics recursively. So if you have
/// `T: Option<Result<(), ()>>`, it'll go into `Option` and then into `Result`. /// `T: Option<Result<(), ()>>`, it'll go into `Option` and then into `Result`.
crate fn get_real_types<'tcx>( #[instrument(level = "trace", skip(tcx, res))]
fn add_generics_and_bounds_as_types<'tcx>(
generics: &Generics, generics: &Generics,
arg: &Type, arg: &Type,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
recurse: usize, recurse: usize,
res: &mut Vec<TypeWithKind>, res: &mut Vec<TypeWithKind>,
cache: &Cache,
) { ) {
fn insert_ty( fn insert_ty(
res: &mut Vec<TypeWithKind>, res: &mut Vec<TypeWithKind>,
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
ty: Type, ty: Type,
mut generics: Vec<TypeWithKind>, mut generics: Vec<TypeWithKind>,
_cache: &Cache,
) { ) {
let is_full_generic = ty.is_full_generic(); let is_full_generic = ty.is_full_generic();
@ -330,6 +317,7 @@ crate fn get_real_types<'tcx>(
if recurse >= 10 { if recurse >= 10 {
// FIXME: remove this whole recurse thing when the recursion bug is fixed // FIXME: remove this whole recurse thing when the recursion bug is fixed
// See #59502 for the original issue.
return; return;
} }
@ -350,13 +338,12 @@ crate fn get_real_types<'tcx>(
for param_def in poly_trait.generic_params.iter() { for param_def in poly_trait.generic_params.iter() {
match &param_def.kind { match &param_def.kind {
clean::GenericParamDefKind::Type { default: Some(ty), .. } => { clean::GenericParamDefKind::Type { default: Some(ty), .. } => {
get_real_types( add_generics_and_bounds_as_types(
generics, generics,
ty, ty,
tcx, tcx,
recurse + 1, recurse + 1,
&mut ty_generics, &mut ty_generics,
cache,
) )
} }
_ => {} _ => {}
@ -364,7 +351,7 @@ crate fn get_real_types<'tcx>(
} }
} }
} }
insert_ty(res, tcx, arg.clone(), ty_generics, cache); insert_ty(res, tcx, arg.clone(), ty_generics);
} }
// Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`... // Otherwise we check if the trait bounds are "inlined" like `T: Option<u32>`...
if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) { if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
@ -372,10 +359,16 @@ crate fn get_real_types<'tcx>(
for bound in bound.get_bounds().unwrap_or(&[]) { for bound in bound.get_bounds().unwrap_or(&[]) {
if let Some(path) = bound.get_trait_path() { if let Some(path) = bound.get_trait_path() {
let ty = Type::Path { path }; let ty = Type::Path { path };
get_real_types(generics, &ty, tcx, recurse + 1, &mut ty_generics, cache); add_generics_and_bounds_as_types(
generics,
&ty,
tcx,
recurse + 1,
&mut ty_generics,
);
} }
} }
insert_ty(res, tcx, arg.clone(), ty_generics, cache); insert_ty(res, tcx, arg.clone(), ty_generics);
} }
} else { } else {
// This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're // This is not a type parameter. So for example if we have `T, U: Option<T>`, and we're
@ -386,10 +379,10 @@ crate fn get_real_types<'tcx>(
let mut ty_generics = Vec::new(); let mut ty_generics = Vec::new();
if let Some(arg_generics) = arg.generics() { if let Some(arg_generics) = arg.generics() {
for gen in arg_generics.iter() { for gen in arg_generics.iter() {
get_real_types(generics, gen, tcx, recurse + 1, &mut ty_generics, cache); add_generics_and_bounds_as_types(generics, gen, tcx, recurse + 1, &mut ty_generics);
} }
} }
insert_ty(res, tcx, arg.clone(), ty_generics, cache); insert_ty(res, tcx, arg.clone(), ty_generics);
} }
} }
@ -397,19 +390,20 @@ crate fn get_real_types<'tcx>(
/// ///
/// i.e. `fn foo<A: Display, B: Option<A>>(x: u32, y: B)` will return /// i.e. `fn foo<A: Display, B: Option<A>>(x: u32, y: B)` will return
/// `[u32, Display, Option]`. /// `[u32, Display, Option]`.
crate fn get_all_types<'tcx>( fn get_fn_inputs_and_outputs<'tcx>(
generics: &Generics, func: &Function,
decl: &FnDecl,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
cache: &Cache,
) -> (Vec<TypeWithKind>, Vec<TypeWithKind>) { ) -> (Vec<TypeWithKind>, Vec<TypeWithKind>) {
let decl = &func.decl;
let generics = &func.generics;
let mut all_types = Vec::new(); let mut all_types = Vec::new();
for arg in decl.inputs.values.iter() { for arg in decl.inputs.values.iter() {
if arg.type_.is_self_type() { if arg.type_.is_self_type() {
continue; continue;
} }
let mut args = Vec::new(); let mut args = Vec::new();
get_real_types(generics, &arg.type_, tcx, 0, &mut args, cache); add_generics_and_bounds_as_types(generics, &arg.type_, tcx, 0, &mut args);
if !args.is_empty() { if !args.is_empty() {
all_types.extend(args); all_types.extend(args);
} else { } else {
@ -423,7 +417,7 @@ crate fn get_all_types<'tcx>(
let mut ret_types = Vec::new(); let mut ret_types = Vec::new();
match decl.output { match decl.output {
FnRetTy::Return(ref return_type) => { FnRetTy::Return(ref return_type) => {
get_real_types(generics, return_type, tcx, 0, &mut ret_types, cache); add_generics_and_bounds_as_types(generics, return_type, tcx, 0, &mut ret_types);
if ret_types.is_empty() { if ret_types.is_empty() {
if let Some(kind) = if let Some(kind) =
return_type.def_id_no_primitives().map(|did| tcx.def_kind(did).into()) return_type.def_id_no_primitives().map(|did| tcx.def_kind(did).into())

View file

@ -19,12 +19,11 @@ use rustc_session::Session;
use rustdoc_json_types as types; use rustdoc_json_types as types;
use crate::clean; use crate::clean;
use crate::clean::ExternalCrate; use crate::clean::types::{ExternalCrate, ExternalLocation};
use crate::config::RenderOptions; use crate::config::RenderOptions;
use crate::error::Error; use crate::error::Error;
use crate::formats::cache::Cache; use crate::formats::cache::Cache;
use crate::formats::FormatRenderer; use crate::formats::FormatRenderer;
use crate::html::render::cache::ExternalLocation;
use crate::json::conversions::{from_item_id, IntoWithTcx}; use crate::json::conversions::{from_item_id, IntoWithTcx};
#[derive(Clone)] #[derive(Clone)]

View file

@ -0,0 +1,11 @@
// check-pass
// Minimization of issue #59502
trait MyTrait<T> {
type Output;
}
pub fn pow<T: MyTrait<T, Output = T>>(arg: T) -> T {
arg
}