1pub(crate) mod encode;
2mod serde;
3
4use std::collections::BTreeSet;
5use std::collections::hash_map::Entry;
6use std::path::Path;
7use std::string::FromUtf8Error;
8use std::{io, iter};
9
10use ::serde::de::{self, Deserializer, Error as _};
11use ::serde::ser::{SerializeSeq, Serializer};
12use ::serde::{Deserialize, Serialize};
13use rustc_ast::join_path_syms;
14use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
15use rustc_data_structures::thin_vec::ThinVec;
16use rustc_hir::def_id::{CrateNum, DefIndex, LOCAL_CRATE};
17use rustc_hir::find_attr;
18use rustc_middle::ty::TyCtxt;
19use rustc_span::def_id::DefId;
20use rustc_span::sym;
21use rustc_span::symbol::{Symbol, kw};
22use stringdex::internals as stringdex_internals;
23use tracing::instrument;
24
25use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate};
26use crate::clean::{self, ExternalLocation, utils};
27use crate::config::ShouldMerge;
28use crate::error::Error;
29use crate::formats::cache::{Cache, OrphanImplItem};
30use crate::formats::item_type::ItemType;
31use crate::html::markdown::short_markdown_summary;
32use crate::html::render::{
33 self, IndexItem, IndexItemFunctionType, IndexItemInfo, RenderType, RenderTypeId,
34};
35
36#[derive(Clone, Debug, Default, Deserialize, Serialize)]
37pub(crate) struct SerializedSearchIndex {
38 names: Vec<String>,
40 path_data: Vec<Option<PathData>>,
41 entry_data: Vec<Option<EntryData>>,
42 descs: Vec<String>,
43 function_data: Vec<Option<IndexItemFunctionType>>,
44 alias_pointers: Vec<Option<usize>>,
45 type_data: Vec<Option<TypeData>>,
47 generic_inverted_index: Vec<Vec<Vec<u32>>>,
59 #[serde(skip)]
61 crate_paths_index: FxHashMap<(ItemType, Vec<Symbol>), usize>,
62}
63
64impl SerializedSearchIndex {
65 fn load(doc_root: &Path, resource_suffix: &str) -> Result<SerializedSearchIndex, Error> {
66 let mut names: Vec<String> = Vec::new();
67 let mut path_data: Vec<Option<PathData>> = Vec::new();
68 let mut entry_data: Vec<Option<EntryData>> = Vec::new();
69 let mut descs: Vec<String> = Vec::new();
70 let mut function_data: Vec<Option<IndexItemFunctionType>> = Vec::new();
71 let mut type_data: Vec<Option<TypeData>> = Vec::new();
72 let mut alias_pointers: Vec<Option<usize>> = Vec::new();
73
74 let mut generic_inverted_index: Vec<Vec<Vec<u32>>> = Vec::new();
75
76 match perform_read_strings(resource_suffix, doc_root, "name", &mut names) {
77 Ok(()) => {
78 perform_read_serde(resource_suffix, doc_root, "path", &mut path_data)?;
79 perform_read_serde(resource_suffix, doc_root, "entry", &mut entry_data)?;
80 perform_read_strings(resource_suffix, doc_root, "desc", &mut descs)?;
81 perform_read_serde(resource_suffix, doc_root, "function", &mut function_data)?;
82 perform_read_serde(resource_suffix, doc_root, "type", &mut type_data)?;
83 perform_read_serde(resource_suffix, doc_root, "alias", &mut alias_pointers)?;
84 perform_read_postings(
85 resource_suffix,
86 doc_root,
87 "generic_inverted_index",
88 &mut generic_inverted_index,
89 )?;
90 }
91 Err(_) => {
92 names.clear();
93 }
94 }
95 fn perform_read_strings(
96 resource_suffix: &str,
97 doc_root: &Path,
98 column_name: &str,
99 column: &mut Vec<String>,
100 ) -> Result<(), Error> {
101 let root_path = doc_root.join(format!("search.index/root{resource_suffix}.js"));
102 let column_path = doc_root.join(format!("search.index/{column_name}/"));
103
104 let mut consume = |_, cell: &[u8]| {
105 column.push(String::from_utf8(cell.to_vec())?);
106 Ok::<_, FromUtf8Error>(())
107 };
108
109 stringdex_internals::read_data_from_disk_column(
110 root_path,
111 column_name.as_bytes(),
112 column_path.clone(),
113 &mut consume,
114 )
115 .map_err(|error| Error {
116 file: column_path,
117 error: format!("failed to read column from disk: {error}"),
118 })
119 }
120 fn perform_read_serde(
121 resource_suffix: &str,
122 doc_root: &Path,
123 column_name: &str,
124 column: &mut Vec<Option<impl for<'de> Deserialize<'de> + 'static>>,
125 ) -> Result<(), Error> {
126 let root_path = doc_root.join(format!("search.index/root{resource_suffix}.js"));
127 let column_path = doc_root.join(format!("search.index/{column_name}/"));
128
129 let mut consume = |_, cell: &[u8]| {
130 if cell.is_empty() {
131 column.push(None);
132 } else {
133 column.push(Some(serde_json::from_slice(cell)?));
134 }
135 Ok::<_, serde_json::Error>(())
136 };
137
138 stringdex_internals::read_data_from_disk_column(
139 root_path,
140 column_name.as_bytes(),
141 column_path.clone(),
142 &mut consume,
143 )
144 .map_err(|error| Error {
145 file: column_path,
146 error: format!("failed to read column from disk: {error}"),
147 })
148 }
149 fn perform_read_postings(
150 resource_suffix: &str,
151 doc_root: &Path,
152 column_name: &str,
153 column: &mut Vec<Vec<Vec<u32>>>,
154 ) -> Result<(), Error> {
155 let root_path = doc_root.join(format!("search.index/root{resource_suffix}.js"));
156 let column_path = doc_root.join(format!("search.index/{column_name}/"));
157
158 fn consumer(
159 column: &mut Vec<Vec<Vec<u32>>>,
160 ) -> impl FnMut(u32, &[u8]) -> io::Result<()> {
161 |_, cell| {
162 let mut postings = Vec::new();
163 encode::read_postings_from_string(&mut postings, cell);
164 column.push(postings);
165 Ok(())
166 }
167 }
168
169 stringdex_internals::read_data_from_disk_column(
170 root_path,
171 column_name.as_bytes(),
172 column_path.clone(),
173 &mut consumer(column),
174 )
175 .map_err(|error| Error {
176 file: column_path,
177 error: format!("failed to read column from disk: {error}"),
178 })
179 }
180
181 assert_eq!(names.len(), path_data.len());
182 assert_eq!(path_data.len(), entry_data.len());
183 assert_eq!(entry_data.len(), descs.len());
184 assert_eq!(descs.len(), function_data.len());
185 assert_eq!(function_data.len(), type_data.len());
186 assert_eq!(type_data.len(), alias_pointers.len());
187
188 let mut crate_paths_index: FxHashMap<(ItemType, Vec<Symbol>), usize> = FxHashMap::default();
192 for (i, (name, path_data)) in names.iter().zip(path_data.iter()).enumerate() {
193 if let Some(path_data) = path_data {
194 let full_path = if path_data.module_path.is_empty() {
195 vec![Symbol::intern(name)]
196 } else {
197 let mut full_path = path_data.module_path.to_vec();
198 full_path.push(Symbol::intern(name));
199 full_path
200 };
201 crate_paths_index.insert((path_data.ty, full_path), i);
202 }
203 }
204
205 Ok(SerializedSearchIndex {
206 names,
207 path_data,
208 entry_data,
209 descs,
210 function_data,
211 type_data,
212 alias_pointers,
213 generic_inverted_index,
214 crate_paths_index,
215 })
216 }
217 fn push(
218 &mut self,
219 name: String,
220 path_data: Option<PathData>,
221 entry_data: Option<EntryData>,
222 desc: String,
223 function_data: Option<IndexItemFunctionType>,
224 type_data: Option<TypeData>,
225 alias_pointer: Option<usize>,
226 ) -> usize {
227 let index = self.names.len();
228 assert_eq!(self.names.len(), self.path_data.len());
229 if let Some(path_data) = &path_data
230 && let name = Symbol::intern(&name)
231 && let fqp = if path_data.module_path.is_empty() {
232 vec![name]
233 } else {
234 let mut v = path_data.module_path.clone();
235 v.push(name);
236 v
237 }
238 && let Some(&other_path) = self.crate_paths_index.get(&(path_data.ty, fqp))
239 && self.path_data.get(other_path).map_or(false, Option::is_some)
240 {
241 self.path_data.push(None);
242 } else {
243 self.path_data.push(path_data);
244 }
245 self.names.push(name);
246 assert_eq!(self.entry_data.len(), self.descs.len());
247 self.entry_data.push(entry_data);
248 assert_eq!(self.descs.len(), self.function_data.len());
249 self.descs.push(desc);
250 assert_eq!(self.function_data.len(), self.type_data.len());
251 self.function_data.push(function_data);
252 assert_eq!(self.type_data.len(), self.alias_pointers.len());
253 self.type_data.push(type_data);
254 self.alias_pointers.push(alias_pointer);
255 index
256 }
257 fn add_entry(&mut self, name: Symbol, entry_data: EntryData, desc: String) -> usize {
261 let fqp = if let Some(module_path_index) = entry_data.module_path {
262 self.path_data[module_path_index]
263 .as_ref()
264 .unwrap()
265 .module_path
266 .iter()
267 .copied()
268 .chain([Symbol::intern(&self.names[module_path_index]), name])
269 .collect()
270 } else {
271 vec![name]
272 };
273 if let Some(&other_path) = self.crate_paths_index.get(&(entry_data.ty, fqp))
279 && self.entry_data[other_path].is_none()
280 && self.descs[other_path].is_empty()
281 {
282 self.entry_data[other_path] = Some(entry_data);
283 self.descs[other_path] = desc;
284 other_path
285 } else {
286 self.push(name.as_str().to_string(), None, Some(entry_data), desc, None, None, None)
287 }
288 }
289 fn push_path(&mut self, name: String, path_data: PathData) -> usize {
290 self.push(name, Some(path_data), None, String::new(), None, None, None)
291 }
292 fn push_type(&mut self, name: String, path_data: PathData, type_data: TypeData) -> usize {
293 self.push(name, Some(path_data), None, String::new(), None, Some(type_data), None)
294 }
295 fn push_alias(&mut self, name: String, alias_pointer: usize) -> usize {
296 self.push(name, None, None, String::new(), None, None, Some(alias_pointer))
297 }
298
299 fn get_id_by_module_path(&mut self, path: &[Symbol]) -> usize {
300 let ty = if path.len() == 1 { ItemType::ExternCrate } else { ItemType::Module };
301 match self.crate_paths_index.entry((ty, path.to_vec())) {
302 Entry::Occupied(index) => *index.get(),
303 Entry::Vacant(slot) => {
304 slot.insert(self.path_data.len());
305 let (name, module_path) = path.split_last().unwrap();
306 self.push_path(
307 name.as_str().to_string(),
308 PathData { ty, module_path: module_path.to_vec(), exact_module_path: None },
309 )
310 }
311 }
312 }
313
314 pub(crate) fn union(mut self, other: &SerializedSearchIndex) -> SerializedSearchIndex {
315 let other_entryid_offset = self.names.len();
316 let mut map_other_pathid_to_self_pathid = Vec::new();
317 let mut skips = FxHashSet::default();
318
319 fn remap_entry_data(
320 other_entry_data: &EntryData,
321 map_other_pathid_to_self_pathid: &[usize],
322 ) -> EntryData {
323 EntryData {
324 parent: other_entry_data
325 .parent
326 .map(|parent| map_other_pathid_to_self_pathid[parent])
327 .clone(),
328 module_path: other_entry_data
329 .module_path
330 .map(|path| map_other_pathid_to_self_pathid[path])
331 .clone(),
332 exact_module_path: other_entry_data
333 .exact_module_path
334 .map(|exact_path| map_other_pathid_to_self_pathid[exact_path])
335 .clone(),
336 krate: map_other_pathid_to_self_pathid[other_entry_data.krate],
337 ..other_entry_data.clone()
338 }
339 }
340
341 for (other_pathid, other_path_data) in other.path_data.iter().enumerate() {
342 if let Some(other_path_data) = other_path_data {
343 let name = Symbol::intern(&other.names[other_pathid]);
344 let fqp =
345 other_path_data.module_path.iter().copied().chain(iter::once(name)).collect();
346 let self_pathid = other_entryid_offset + other_pathid;
347 let self_pathid = match self.crate_paths_index.entry((other_path_data.ty, fqp)) {
348 Entry::Vacant(slot) => {
349 slot.insert(self_pathid);
350 self_pathid
351 }
352 Entry::Occupied(existing_entryid) => {
353 skips.insert(other_pathid);
354 let self_pathid = *existing_entryid.get();
355 let new_type_data = match (
356 self.type_data[self_pathid].take(),
357 other.type_data[other_pathid].as_ref(),
358 ) {
359 (Some(self_type_data), None) => Some(self_type_data),
360 (None, Some(other_type_data)) => Some(TypeData {
361 search_unbox: other_type_data.search_unbox,
362 inverted_function_inputs_index: other_type_data
363 .inverted_function_inputs_index
364 .iter()
365 .cloned()
366 .map(|mut list: Vec<u32>| {
367 for fnid in &mut list {
368 assert!(
369 other.function_data
370 [usize::try_from(*fnid).unwrap()]
371 .is_some(),
372 );
373 *fnid += u32::try_from(other_entryid_offset).unwrap();
376 }
377 list
378 })
379 .collect(),
380 inverted_function_output_index: other_type_data
381 .inverted_function_output_index
382 .iter()
383 .cloned()
384 .map(|mut list: Vec<u32>| {
385 for fnid in &mut list {
386 assert!(
387 other.function_data
388 [usize::try_from(*fnid).unwrap()]
389 .is_some(),
390 );
391 *fnid += u32::try_from(other_entryid_offset).unwrap();
394 }
395 list
396 })
397 .collect(),
398 }),
399 (Some(mut self_type_data), Some(other_type_data)) => {
400 for (size, other_list) in other_type_data
401 .inverted_function_inputs_index
402 .iter()
403 .enumerate()
404 {
405 while self_type_data.inverted_function_inputs_index.len()
406 <= size
407 {
408 self_type_data
409 .inverted_function_inputs_index
410 .push(Vec::new());
411 }
412 self_type_data.inverted_function_inputs_index[size].extend(
413 other_list.iter().copied().map(|fnid| {
414 assert!(
415 other.function_data[usize::try_from(fnid).unwrap()]
416 .is_some(),
417 );
418 fnid + u32::try_from(other_entryid_offset).unwrap()
421 }),
422 )
423 }
424 for (size, other_list) in other_type_data
425 .inverted_function_output_index
426 .iter()
427 .enumerate()
428 {
429 while self_type_data.inverted_function_output_index.len()
430 <= size
431 {
432 self_type_data
433 .inverted_function_output_index
434 .push(Vec::new());
435 }
436 self_type_data.inverted_function_output_index[size].extend(
437 other_list.iter().copied().map(|fnid| {
438 assert!(
439 other.function_data[usize::try_from(fnid).unwrap()]
440 .is_some(),
441 );
442 fnid + u32::try_from(other_entryid_offset).unwrap()
445 }),
446 )
447 }
448 Some(self_type_data)
449 }
450 (None, None) => None,
451 };
452 self.type_data[self_pathid] = new_type_data;
453 self_pathid
454 }
455 };
456 map_other_pathid_to_self_pathid.push(self_pathid);
457 } else {
458 map_other_pathid_to_self_pathid.push(!0);
462 }
463 }
464 for other_entryid in 0..other.names.len() {
465 self.push(
466 other.names[other_entryid].clone(),
467 if skips.contains(&other_entryid) {
468 None
469 } else {
470 other.path_data[other_entryid].clone()
471 },
472 other.entry_data[other_entryid].as_ref().map(|other_entry_data| {
473 remap_entry_data(other_entry_data, &map_other_pathid_to_self_pathid)
474 }),
475 other.descs[other_entryid].clone(),
476 other.function_data[other_entryid].clone().map(|mut func| {
477 fn map_fn_sig_item(
478 map_other_pathid_to_self_pathid: &Vec<usize>,
479 ty: &mut RenderType,
480 ) {
481 match ty.id {
482 None => {}
483 Some(RenderTypeId::Index(generic)) if generic < 0 => {}
484 Some(RenderTypeId::Index(id)) => {
485 let id = usize::try_from(id).unwrap();
486 let id = map_other_pathid_to_self_pathid[id];
487 assert!(id != !0);
488 ty.id = Some(RenderTypeId::Index(isize::try_from(id).unwrap()));
489 }
490 _ => unreachable!(),
491 }
492 if let Some(generics) = &mut ty.generics {
493 for generic in generics {
494 map_fn_sig_item(map_other_pathid_to_self_pathid, generic);
495 }
496 }
497 if let Some(bindings) = &mut ty.bindings {
498 for (param, constraints) in bindings {
499 *param = match *param {
500 param @ RenderTypeId::Index(generic) if generic < 0 => param,
501 RenderTypeId::Index(id) => {
502 let id = usize::try_from(id).unwrap();
503 let id = map_other_pathid_to_self_pathid[id];
504 assert!(id != !0);
505 RenderTypeId::Index(isize::try_from(id).unwrap())
506 }
507 _ => unreachable!(),
508 };
509 for constraint in constraints {
510 map_fn_sig_item(map_other_pathid_to_self_pathid, constraint);
511 }
512 }
513 }
514 }
515 for input in &mut func.inputs {
516 map_fn_sig_item(&map_other_pathid_to_self_pathid, input);
517 }
518 for output in &mut func.output {
519 map_fn_sig_item(&map_other_pathid_to_self_pathid, output);
520 }
521 for clause in &mut func.where_clause {
522 for entry in clause {
523 map_fn_sig_item(&map_other_pathid_to_self_pathid, entry);
524 }
525 }
526 func
527 }),
528 if skips.contains(&other_entryid) {
529 None
530 } else {
531 other.type_data[other_entryid].as_ref().map(|type_data| TypeData {
532 inverted_function_inputs_index: type_data
533 .inverted_function_inputs_index
534 .iter()
535 .cloned()
536 .map(|mut list| {
537 for fnid in &mut list {
538 assert!(
539 other.function_data[usize::try_from(*fnid).unwrap()]
540 .is_some(),
541 );
542 *fnid += u32::try_from(other_entryid_offset).unwrap();
545 }
546 list
547 })
548 .collect(),
549 inverted_function_output_index: type_data
550 .inverted_function_output_index
551 .iter()
552 .cloned()
553 .map(|mut list| {
554 for fnid in &mut list {
555 assert!(
556 other.function_data[usize::try_from(*fnid).unwrap()]
557 .is_some(),
558 );
559 *fnid += u32::try_from(other_entryid_offset).unwrap();
562 }
563 list
564 })
565 .collect(),
566 search_unbox: type_data.search_unbox,
567 })
568 },
569 other.alias_pointers[other_entryid]
570 .map(|alias_pointer| alias_pointer + other_entryid_offset),
571 );
572 }
573 if other.generic_inverted_index.len() > self.generic_inverted_index.len() {
574 self.generic_inverted_index.resize(other.generic_inverted_index.len(), Vec::new());
575 }
576 for (other_generic_inverted_index, self_generic_inverted_index) in
577 iter::zip(&other.generic_inverted_index, &mut self.generic_inverted_index)
578 {
579 if other_generic_inverted_index.len() > self_generic_inverted_index.len() {
580 self_generic_inverted_index.resize(other_generic_inverted_index.len(), Vec::new());
581 }
582 for (other_list, self_list) in
583 iter::zip(other_generic_inverted_index, self_generic_inverted_index)
584 {
585 self_list.extend(
586 other_list
587 .iter()
588 .copied()
589 .map(|fnid| fnid + u32::try_from(other_entryid_offset).unwrap()),
590 );
591 }
592 }
593 self
594 }
595
596 pub(crate) fn sort(self) -> SerializedSearchIndex {
597 let mut idlist: Vec<usize> = (0..self.names.len()).collect();
598 idlist.sort_by_key(|&id| {
601 (
602 self.names[id].is_empty(),
603 self.names[id].len(),
604 &self.names[id],
605 self.entry_data[id].as_ref().map_or("", |entry| self.names[entry.krate].as_str()),
606 self.path_data[id].as_ref().map_or(&[][..], |entry| &entry.module_path[..]),
607 )
608 });
609 let map = FxHashMap::from_iter(
610 idlist.iter().enumerate().map(|(new_id, &old_id)| (old_id, new_id)),
611 );
612 let mut new = SerializedSearchIndex::default();
613 for &id in &idlist {
614 if self.names[id].is_empty() {
615 break;
616 }
617 new.push(
618 self.names[id].clone(),
619 self.path_data[id].clone(),
620 self.entry_data[id].as_ref().map(
621 |EntryData {
622 krate,
623 ty,
624 module_path,
625 exact_module_path,
626 parent,
627 trait_parent,
628 deprecated,
629 unstable,
630 associated_item_disambiguator_or_extern_crate_url:
631 associated_item_disambiguator,
632 }| EntryData {
633 krate: *map.get(krate).unwrap(),
634 ty: *ty,
635 module_path: module_path.and_then(|path_id| map.get(&path_id).copied()),
636 exact_module_path: exact_module_path
637 .and_then(|path_id| map.get(&path_id).copied()),
638 parent: parent.and_then(|path_id| map.get(&path_id).copied()),
639 trait_parent: trait_parent.and_then(|path_id| map.get(&path_id).copied()),
640 deprecated: *deprecated,
641 unstable: *unstable,
642 associated_item_disambiguator_or_extern_crate_url:
643 associated_item_disambiguator.clone(),
644 },
645 ),
646 self.descs[id].clone(),
647 self.function_data[id].clone().map(|mut func| {
648 fn map_fn_sig_item(map: &FxHashMap<usize, usize>, ty: &mut RenderType) {
649 match ty.id {
650 None => {}
651 Some(RenderTypeId::Index(generic)) if generic < 0 => {}
652 Some(RenderTypeId::Index(id)) => {
653 let id = usize::try_from(id).unwrap();
654 let id = *map.get(&id).unwrap();
655 assert!(id != !0);
656 ty.id = Some(RenderTypeId::Index(isize::try_from(id).unwrap()));
657 }
658 _ => unreachable!(),
659 }
660 if let Some(generics) = &mut ty.generics {
661 for generic in generics {
662 map_fn_sig_item(map, generic);
663 }
664 }
665 if let Some(bindings) = &mut ty.bindings {
666 for (param, constraints) in bindings {
667 *param = match *param {
668 param @ RenderTypeId::Index(generic) if generic < 0 => param,
669 RenderTypeId::Index(id) => {
670 let id = usize::try_from(id).unwrap();
671 let id = *map.get(&id).unwrap();
672 assert!(id != !0);
673 RenderTypeId::Index(isize::try_from(id).unwrap())
674 }
675 _ => unreachable!(),
676 };
677 for constraint in constraints {
678 map_fn_sig_item(map, constraint);
679 }
680 }
681 }
682 }
683 for input in &mut func.inputs {
684 map_fn_sig_item(&map, input);
685 }
686 for output in &mut func.output {
687 map_fn_sig_item(&map, output);
688 }
689 for clause in &mut func.where_clause {
690 for entry in clause {
691 map_fn_sig_item(&map, entry);
692 }
693 }
694 func
695 }),
696 self.type_data[id].as_ref().map(
697 |TypeData {
698 search_unbox,
699 inverted_function_inputs_index,
700 inverted_function_output_index,
701 }| {
702 let inverted_function_inputs_index: Vec<Vec<u32>> =
703 inverted_function_inputs_index
704 .iter()
705 .cloned()
706 .map(|mut list| {
707 for id in &mut list {
708 *id = u32::try_from(
709 *map.get(&usize::try_from(*id).unwrap()).unwrap(),
710 )
711 .unwrap();
712 }
713 list.sort();
714 list
715 })
716 .collect();
717 let inverted_function_output_index: Vec<Vec<u32>> =
718 inverted_function_output_index
719 .iter()
720 .cloned()
721 .map(|mut list| {
722 for id in &mut list {
723 *id = u32::try_from(
724 *map.get(&usize::try_from(*id).unwrap()).unwrap(),
725 )
726 .unwrap();
727 }
728 list.sort();
729 list
730 })
731 .collect();
732 TypeData {
733 search_unbox: *search_unbox,
734 inverted_function_inputs_index,
735 inverted_function_output_index,
736 }
737 },
738 ),
739 self.alias_pointers[id].and_then(|alias| {
740 if self.names[alias].is_empty() { None } else { map.get(&alias).copied() }
741 }),
742 );
743 }
744 new.generic_inverted_index = self
745 .generic_inverted_index
746 .into_iter()
747 .map(|mut postings| {
748 for list in postings.iter_mut() {
749 let mut new_list: Vec<u32> = list
750 .iter()
751 .copied()
752 .filter_map(|id| u32::try_from(*map.get(&usize::try_from(id).ok()?)?).ok())
753 .collect();
754 new_list.sort();
755 *list = new_list;
756 }
757 postings
758 })
759 .collect();
760 new
761 }
762
763 pub(crate) fn write_to(self, doc_root: &Path, resource_suffix: &str) -> Result<(), Error> {
764 let SerializedSearchIndex {
765 names,
766 path_data,
767 entry_data,
768 descs,
769 function_data,
770 type_data,
771 alias_pointers,
772 generic_inverted_index,
773 crate_paths_index: _,
774 } = self;
775 let mut serialized_root = Vec::new();
776 serialized_root.extend_from_slice(br#"rr_('{"normalizedName":{"I":""#);
777 let normalized_names = names
778 .iter()
779 .map(|name| {
780 if name.contains("_") {
781 name.replace("_", "").to_ascii_lowercase()
782 } else {
783 name.to_ascii_lowercase()
784 }
785 })
786 .collect::<Vec<String>>();
787 let names_search_tree = stringdex_internals::tree::encode_search_tree_ukkonen(
788 normalized_names.iter().map(|name| name.as_bytes()),
789 );
790 let dir_path = doc_root.join(format!("search.index/"));
791 let _ = std::fs::remove_dir_all(&dir_path); stringdex_internals::write_tree_to_disk(
793 &names_search_tree,
794 &dir_path,
795 &mut serialized_root,
796 )
797 .map_err(|error| Error {
798 file: dir_path,
799 error: format!("failed to write name tree to disk: {error}"),
800 })?;
801 std::mem::drop(names_search_tree);
802 serialized_root.extend_from_slice(br#"","#);
803 serialized_root.extend_from_slice(&perform_write_strings(
804 doc_root,
805 "normalizedName",
806 normalized_names.into_iter(),
807 )?);
808 serialized_root.extend_from_slice(br#"},"crateNames":{"#);
809 let mut crates: Vec<&[u8]> = entry_data
810 .iter()
811 .filter_map(|entry_data| Some(names[entry_data.as_ref()?.krate].as_bytes()))
812 .collect();
813 crates.sort();
814 crates.dedup();
815 serialized_root.extend_from_slice(&perform_write_strings(
816 doc_root,
817 "crateNames",
818 crates.into_iter(),
819 )?);
820 serialized_root.extend_from_slice(br#"},"name":{"#);
821 serialized_root.extend_from_slice(&perform_write_strings(doc_root, "name", names.iter())?);
822 serialized_root.extend_from_slice(br#"},"path":{"#);
823 serialized_root.extend_from_slice(&perform_write_serde(doc_root, "path", path_data)?);
824 serialized_root.extend_from_slice(br#"},"entry":{"#);
825 serialized_root.extend_from_slice(&perform_write_serde(doc_root, "entry", entry_data)?);
826 serialized_root.extend_from_slice(br#"},"desc":{"#);
827 serialized_root.extend_from_slice(&perform_write_strings(
828 doc_root,
829 "desc",
830 descs.into_iter(),
831 )?);
832 serialized_root.extend_from_slice(br#"},"function":{"#);
833 serialized_root.extend_from_slice(&perform_write_serde(
834 doc_root,
835 "function",
836 function_data,
837 )?);
838 serialized_root.extend_from_slice(br#"},"type":{"#);
839 serialized_root.extend_from_slice(&perform_write_serde(doc_root, "type", type_data)?);
840 serialized_root.extend_from_slice(br#"},"alias":{"#);
841 serialized_root.extend_from_slice(&perform_write_serde(doc_root, "alias", alias_pointers)?);
842 serialized_root.extend_from_slice(br#"},"generic_inverted_index":{"#);
843 serialized_root.extend_from_slice(&perform_write_postings(
844 doc_root,
845 "generic_inverted_index",
846 generic_inverted_index,
847 )?);
848 serialized_root.extend_from_slice(br#"}}')"#);
849 fn perform_write_strings(
850 doc_root: &Path,
851 dirname: &str,
852 mut column: impl Iterator<Item = impl AsRef<[u8]> + Clone> + ExactSizeIterator,
853 ) -> Result<Vec<u8>, Error> {
854 let dir_path = doc_root.join(format!("search.index/{dirname}"));
855 stringdex_internals::write_data_to_disk(&mut column, &dir_path).map_err(|error| Error {
856 file: dir_path,
857 error: format!("failed to write column to disk: {error}"),
858 })
859 }
860 fn perform_write_serde(
861 doc_root: &Path,
862 dirname: &str,
863 column: Vec<Option<impl Serialize>>,
864 ) -> Result<Vec<u8>, Error> {
865 perform_write_strings(
866 doc_root,
867 dirname,
868 column.into_iter().map(|value| {
869 if let Some(value) = value {
870 serde_json::to_vec(&value).unwrap()
871 } else {
872 Vec::new()
873 }
874 }),
875 )
876 }
877 fn perform_write_postings(
878 doc_root: &Path,
879 dirname: &str,
880 column: Vec<Vec<Vec<u32>>>,
881 ) -> Result<Vec<u8>, Error> {
882 perform_write_strings(
883 doc_root,
884 dirname,
885 column.into_iter().map(|postings| {
886 let mut buf = Vec::new();
887 encode::write_postings_to_string(&postings, &mut buf);
888 buf
889 }),
890 )
891 }
892 std::fs::write(
893 doc_root.join(format!("search.index/root{resource_suffix}.js")),
894 serialized_root,
895 )
896 .map_err(|error| Error {
897 file: doc_root.join(format!("search.index/root{resource_suffix}.js")),
898 error: format!("failed to write root to disk: {error}"),
899 })?;
900 Ok(())
901 }
902}
903
904#[derive(Clone, Debug)]
905struct EntryData {
906 krate: usize,
907 ty: ItemType,
908 module_path: Option<usize>,
909 exact_module_path: Option<usize>,
910 parent: Option<usize>,
911 trait_parent: Option<usize>,
912 deprecated: bool,
913 unstable: bool,
914 associated_item_disambiguator_or_extern_crate_url: Option<String>,
915}
916
917impl Serialize for EntryData {
918 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
919 where
920 S: Serializer,
921 {
922 let mut seq = serializer.serialize_seq(None)?;
923 seq.serialize_element(&self.krate)?;
924 seq.serialize_element(&self.ty)?;
925 seq.serialize_element(&self.module_path.map(|id| id + 1).unwrap_or(0))?;
926 seq.serialize_element(&self.exact_module_path.map(|id| id + 1).unwrap_or(0))?;
927 seq.serialize_element(&self.parent.map(|id| id + 1).unwrap_or(0))?;
928 seq.serialize_element(&self.trait_parent.map(|id| id + 1).unwrap_or(0))?;
929 seq.serialize_element(&if self.deprecated { 1 } else { 0 })?;
930 seq.serialize_element(&if self.unstable { 1 } else { 0 })?;
931 if let Some(disambig) = &self.associated_item_disambiguator_or_extern_crate_url {
932 seq.serialize_element(&disambig)?;
933 }
934 seq.end()
935 }
936}
937
938impl<'de> Deserialize<'de> for EntryData {
939 fn deserialize<D>(deserializer: D) -> Result<EntryData, D::Error>
940 where
941 D: Deserializer<'de>,
942 {
943 struct EntryDataVisitor;
944 impl<'de> de::Visitor<'de> for EntryDataVisitor {
945 type Value = EntryData;
946 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
947 write!(formatter, "path data")
948 }
949 fn visit_seq<A: de::SeqAccess<'de>>(self, mut v: A) -> Result<EntryData, A::Error> {
950 let krate: usize =
951 v.next_element()?.ok_or_else(|| A::Error::missing_field("krate"))?;
952 let ty: ItemType =
953 v.next_element()?.ok_or_else(|| A::Error::missing_field("ty"))?;
954 let module_path: SerializedOptional32 =
955 v.next_element()?.ok_or_else(|| A::Error::missing_field("module_path"))?;
956 let exact_module_path: SerializedOptional32 = v
957 .next_element()?
958 .ok_or_else(|| A::Error::missing_field("exact_module_path"))?;
959 let parent: SerializedOptional32 =
960 v.next_element()?.ok_or_else(|| A::Error::missing_field("parent"))?;
961 let trait_parent: SerializedOptional32 =
962 v.next_element()?.ok_or_else(|| A::Error::missing_field("trait_parent"))?;
963
964 let deprecated: u32 = v.next_element()?.unwrap_or(0);
965 let unstable: u32 = v.next_element()?.unwrap_or(0);
966 let associated_item_disambiguator: Option<String> = v.next_element()?;
967 Ok(EntryData {
968 krate,
969 ty,
970 module_path: Option::<i32>::from(module_path).map(|path| path as usize),
971 exact_module_path: Option::<i32>::from(exact_module_path)
972 .map(|path| path as usize),
973 parent: Option::<i32>::from(parent).map(|path| path as usize),
974 trait_parent: Option::<i32>::from(trait_parent).map(|path| path as usize),
975 deprecated: deprecated != 0,
976 unstable: unstable != 0,
977 associated_item_disambiguator_or_extern_crate_url:
978 associated_item_disambiguator,
979 })
980 }
981 }
982 deserializer.deserialize_any(EntryDataVisitor)
983 }
984}
985
986#[derive(Clone, Debug)]
987struct PathData {
988 ty: ItemType,
989 module_path: Vec<Symbol>,
990 exact_module_path: Option<Vec<Symbol>>,
991}
992
993impl Serialize for PathData {
994 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
995 where
996 S: Serializer,
997 {
998 let mut seq = serializer.serialize_seq(None)?;
999 seq.serialize_element(&self.ty)?;
1000 seq.serialize_element(&if self.module_path.is_empty() {
1001 String::new()
1002 } else {
1003 join_path_syms(&self.module_path)
1004 })?;
1005 if let Some(ref path) = self.exact_module_path {
1006 seq.serialize_element(&if path.is_empty() {
1007 String::new()
1008 } else {
1009 join_path_syms(path)
1010 })?;
1011 }
1012 seq.end()
1013 }
1014}
1015
1016impl<'de> Deserialize<'de> for PathData {
1017 fn deserialize<D>(deserializer: D) -> Result<PathData, D::Error>
1018 where
1019 D: Deserializer<'de>,
1020 {
1021 struct PathDataVisitor;
1022 impl<'de> de::Visitor<'de> for PathDataVisitor {
1023 type Value = PathData;
1024 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1025 write!(formatter, "path data")
1026 }
1027 fn visit_seq<A: de::SeqAccess<'de>>(self, mut v: A) -> Result<PathData, A::Error> {
1028 let ty: ItemType =
1029 v.next_element()?.ok_or_else(|| A::Error::missing_field("ty"))?;
1030 let module_path: String =
1031 v.next_element()?.ok_or_else(|| A::Error::missing_field("module_path"))?;
1032 let exact_module_path: Option<String> =
1033 v.next_element()?.and_then(SerializedOptionalString::into);
1034 Ok(PathData {
1035 ty,
1036 module_path: if module_path.is_empty() {
1037 vec![]
1038 } else {
1039 module_path.split("::").map(Symbol::intern).collect()
1040 },
1041 exact_module_path: exact_module_path.map(|path| {
1042 if path.is_empty() {
1043 vec![]
1044 } else {
1045 path.split("::").map(Symbol::intern).collect()
1046 }
1047 }),
1048 })
1049 }
1050 }
1051 deserializer.deserialize_any(PathDataVisitor)
1052 }
1053}
1054
1055#[derive(Clone, Debug)]
1056struct TypeData {
1057 search_unbox: bool,
1068 inverted_function_inputs_index: Vec<Vec<u32>>,
1079 inverted_function_output_index: Vec<Vec<u32>>,
1082}
1083
1084impl Serialize for TypeData {
1085 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1086 where
1087 S: Serializer,
1088 {
1089 let mut seq = serializer.serialize_seq(None)?;
1090 let mut buf = Vec::new();
1091 encode::write_postings_to_string(&self.inverted_function_inputs_index, &mut buf);
1092 let mut serialized_result = Vec::new();
1093 stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result).unwrap();
1094 seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?;
1095 buf.clear();
1096 serialized_result.clear();
1097 encode::write_postings_to_string(&self.inverted_function_output_index, &mut buf);
1098 stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result).unwrap();
1099 seq.serialize_element(&str::from_utf8(&serialized_result).unwrap())?;
1100 if self.search_unbox {
1101 seq.serialize_element(&1)?;
1102 }
1103 seq.end()
1104 }
1105}
1106
1107impl<'de> Deserialize<'de> for TypeData {
1108 fn deserialize<D>(deserializer: D) -> Result<TypeData, D::Error>
1109 where
1110 D: Deserializer<'de>,
1111 {
1112 struct TypeDataVisitor;
1113 impl<'de> de::Visitor<'de> for TypeDataVisitor {
1114 type Value = TypeData;
1115 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1116 write!(formatter, "type data")
1117 }
1118 fn visit_none<E>(self) -> Result<TypeData, E> {
1119 Ok(TypeData {
1120 inverted_function_inputs_index: vec![],
1121 inverted_function_output_index: vec![],
1122 search_unbox: false,
1123 })
1124 }
1125 fn visit_seq<A: de::SeqAccess<'de>>(self, mut v: A) -> Result<TypeData, A::Error> {
1126 let inverted_function_inputs_index: String =
1127 v.next_element()?.unwrap_or(String::new());
1128 let inverted_function_output_index: String =
1129 v.next_element()?.unwrap_or(String::new());
1130 let search_unbox: u32 = v.next_element()?.unwrap_or(0);
1131 let mut idx: Vec<u8> = Vec::new();
1132 stringdex_internals::decode::read_base64_from_bytes(
1133 inverted_function_inputs_index.as_bytes(),
1134 &mut idx,
1135 )
1136 .unwrap();
1137 let mut inverted_function_inputs_index = Vec::new();
1138 encode::read_postings_from_string(&mut inverted_function_inputs_index, &idx);
1139 idx.clear();
1140 stringdex_internals::decode::read_base64_from_bytes(
1141 inverted_function_output_index.as_bytes(),
1142 &mut idx,
1143 )
1144 .unwrap();
1145 let mut inverted_function_output_index = Vec::new();
1146 encode::read_postings_from_string(&mut inverted_function_output_index, &idx);
1147 Ok(TypeData {
1148 inverted_function_inputs_index,
1149 inverted_function_output_index,
1150 search_unbox: search_unbox == 1,
1151 })
1152 }
1153 }
1154 deserializer.deserialize_any(TypeDataVisitor)
1155 }
1156}
1157
1158enum SerializedOptionalString {
1159 None,
1160 Some(String),
1161}
1162
1163impl From<SerializedOptionalString> for Option<String> {
1164 fn from(me: SerializedOptionalString) -> Option<String> {
1165 match me {
1166 SerializedOptionalString::Some(string) => Some(string),
1167 SerializedOptionalString::None => None,
1168 }
1169 }
1170}
1171
1172impl Serialize for SerializedOptionalString {
1173 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1174 where
1175 S: Serializer,
1176 {
1177 match self {
1178 SerializedOptionalString::Some(string) => string.serialize(serializer),
1179 SerializedOptionalString::None => 0.serialize(serializer),
1180 }
1181 }
1182}
1183impl<'de> Deserialize<'de> for SerializedOptionalString {
1184 fn deserialize<D>(deserializer: D) -> Result<SerializedOptionalString, D::Error>
1185 where
1186 D: Deserializer<'de>,
1187 {
1188 struct SerializedOptionalStringVisitor;
1189 impl<'de> de::Visitor<'de> for SerializedOptionalStringVisitor {
1190 type Value = SerializedOptionalString;
1191 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1192 write!(formatter, "0 or string")
1193 }
1194 fn visit_u64<E: de::Error>(self, v: u64) -> Result<SerializedOptionalString, E> {
1195 if v != 0 {
1196 return Err(E::missing_field("not 0"));
1197 }
1198 Ok(SerializedOptionalString::None)
1199 }
1200 fn visit_string<E: de::Error>(self, v: String) -> Result<SerializedOptionalString, E> {
1201 Ok(SerializedOptionalString::Some(v))
1202 }
1203 fn visit_str<E: de::Error>(self, v: &str) -> Result<SerializedOptionalString, E> {
1204 Ok(SerializedOptionalString::Some(v.to_string()))
1205 }
1206 }
1207 deserializer.deserialize_any(SerializedOptionalStringVisitor)
1208 }
1209}
1210
1211enum SerializedOptional32 {
1212 None,
1213 Some(i32),
1214}
1215
1216impl From<SerializedOptional32> for Option<i32> {
1217 fn from(me: SerializedOptional32) -> Option<i32> {
1218 match me {
1219 SerializedOptional32::Some(number) => Some(number),
1220 SerializedOptional32::None => None,
1221 }
1222 }
1223}
1224
1225impl Serialize for SerializedOptional32 {
1226 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1227 where
1228 S: Serializer,
1229 {
1230 match self {
1231 &SerializedOptional32::Some(number) if number < 0 => number.serialize(serializer),
1232 &SerializedOptional32::Some(number) => (number + 1).serialize(serializer),
1233 &SerializedOptional32::None => 0.serialize(serializer),
1234 }
1235 }
1236}
1237impl<'de> Deserialize<'de> for SerializedOptional32 {
1238 fn deserialize<D>(deserializer: D) -> Result<SerializedOptional32, D::Error>
1239 where
1240 D: Deserializer<'de>,
1241 {
1242 struct SerializedOptional32Visitor;
1243 impl<'de> de::Visitor<'de> for SerializedOptional32Visitor {
1244 type Value = SerializedOptional32;
1245 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1246 write!(formatter, "integer")
1247 }
1248 fn visit_i64<E: de::Error>(self, v: i64) -> Result<SerializedOptional32, E> {
1249 Ok(match v {
1250 0 => SerializedOptional32::None,
1251 v if v < 0 => SerializedOptional32::Some(v as i32),
1252 v => SerializedOptional32::Some(v as i32 - 1),
1253 })
1254 }
1255 fn visit_u64<E: de::Error>(self, v: u64) -> Result<SerializedOptional32, E> {
1256 Ok(match v {
1257 0 => SerializedOptional32::None,
1258 v => SerializedOptional32::Some(v as i32 - 1),
1259 })
1260 }
1261 }
1262 deserializer.deserialize_any(SerializedOptional32Visitor)
1263 }
1264}
1265
1266pub(crate) fn build_index(
1268 krate: &clean::Crate,
1269 cache: &mut Cache,
1270 tcx: TyCtxt<'_>,
1271 doc_root: &Path,
1272 resource_suffix: &str,
1273 should_merge: &ShouldMerge,
1274) -> Result<SerializedSearchIndex, Error> {
1275 let mut search_index = std::mem::take(&mut cache.search_index);
1276
1277 for &OrphanImplItem { impl_id, parent, trait_parent, ref item, ref impl_generics } in
1280 &cache.orphan_impl_items
1281 {
1282 if let Some((fqp, _)) = cache.paths.get(&parent) {
1283 let info = IndexItemInfo::new(
1284 tcx,
1285 cache,
1286 item,
1287 Some(parent),
1288 impl_generics.as_ref(),
1289 item.type_(),
1290 );
1291 search_index.push(IndexItem {
1292 defid: item.item_id.as_def_id(),
1293 name: item.name.unwrap(),
1294 module_path: fqp[..fqp.len() - 1].to_vec(),
1295 parent: Some(parent),
1296 parent_idx: None,
1297 trait_parent,
1298 trait_parent_idx: None,
1299 exact_module_path: None,
1300 impl_id,
1301 info,
1302 });
1303 }
1304 }
1305
1306 search_index.sort_unstable_by(|k1, k2| {
1308 fn key(i: &IndexItem) -> (&[Symbol], &str, ItemType, Option<(DefIndex, CrateNum)>) {
1311 (&i.module_path, i.name.as_str(), i.info.ty, i.parent.map(|id| (id.index, id.krate)))
1312 }
1313 Ord::cmp(&key(k1), &key(k2))
1314 });
1315
1316 let mut serialized_index = if should_merge.read_rendered_cci {
1321 SerializedSearchIndex::load(doc_root, resource_suffix)?
1322 } else {
1323 SerializedSearchIndex::default()
1324 };
1325
1326 let crate_name = krate.name(tcx);
1328 let crate_doc =
1329 short_markdown_summary(&krate.module.doc_value(), &krate.module.link_names(cache));
1330 let crate_idx = {
1331 let crate_path = (ItemType::ExternCrate, vec![crate_name]);
1332 match serialized_index.crate_paths_index.entry(crate_path) {
1333 Entry::Occupied(index) => {
1334 let index = *index.get();
1335 serialized_index.descs[index] = crate_doc;
1336 for type_data in serialized_index.type_data.iter_mut() {
1337 if let Some(TypeData {
1338 inverted_function_inputs_index,
1339 inverted_function_output_index,
1340 ..
1341 }) = type_data
1342 {
1343 for list in inverted_function_inputs_index
1344 .iter_mut()
1345 .chain(inverted_function_output_index.iter_mut())
1346 {
1347 list.retain(|fnid| {
1348 serialized_index.entry_data[usize::try_from(*fnid).unwrap()]
1349 .as_ref()
1350 .unwrap()
1351 .krate
1352 != index
1353 });
1354 }
1355 }
1356 }
1357 for i in (index + 1)..serialized_index.entry_data.len() {
1358 if let Some(EntryData { krate, .. }) = serialized_index.entry_data[i]
1360 && krate == index
1361 {
1362 serialized_index.entry_data[i] = None;
1363 serialized_index.descs[i] = String::new();
1364 serialized_index.function_data[i] = None;
1365 if serialized_index.path_data[i].is_none() {
1366 serialized_index.names[i] = String::new();
1367 }
1368 }
1369 if let Some(alias_pointer) = serialized_index.alias_pointers[i]
1370 && serialized_index.entry_data[alias_pointer].is_none()
1371 {
1372 serialized_index.alias_pointers[i] = None;
1373 if serialized_index.path_data[i].is_none()
1374 && serialized_index.entry_data[i].is_none()
1375 {
1376 serialized_index.names[i] = String::new();
1377 }
1378 }
1379 }
1380 index
1381 }
1382 Entry::Vacant(slot) => {
1383 let krate = serialized_index.names.len();
1384 slot.insert(krate);
1385 serialized_index.push(
1386 crate_name.as_str().to_string(),
1387 Some(PathData {
1388 ty: ItemType::ExternCrate,
1389 module_path: vec![],
1390 exact_module_path: None,
1391 }),
1392 Some(EntryData {
1393 krate,
1394 ty: ItemType::ExternCrate,
1395 module_path: None,
1396 exact_module_path: None,
1397 parent: None,
1398 trait_parent: None,
1399 deprecated: false,
1400 unstable: false,
1401 associated_item_disambiguator_or_extern_crate_url: None,
1402 }),
1403 crate_doc,
1404 None,
1405 None,
1406 None,
1407 );
1408 krate
1409 }
1410 }
1411 };
1412
1413 let crate_items: Vec<&mut IndexItem> = search_index
1415 .iter_mut()
1416 .map(|item| {
1417 let mut defid_to_rowid = |defid, check_external: bool| {
1418 cache
1419 .paths
1420 .get(&defid)
1421 .or_else(|| check_external.then(|| cache.external_paths.get(&defid)).flatten())
1422 .map(|&(ref fqp, ty)| {
1423 let pathid = serialized_index.names.len();
1424 match serialized_index.crate_paths_index.entry((ty, fqp.clone())) {
1425 Entry::Occupied(entry) => *entry.get(),
1426 Entry::Vacant(entry) => {
1427 entry.insert(pathid);
1428 let (name, path) = fqp.split_last().unwrap();
1429 serialized_index.push_path(
1430 name.as_str().to_string(),
1431 PathData {
1432 ty,
1433 module_path: path.to_vec(),
1434 exact_module_path: if let Some(exact_path) =
1435 cache.exact_paths.get(&defid)
1436 && let Some((name2, exact_path)) =
1437 exact_path.split_last()
1438 && name == name2
1439 {
1440 Some(exact_path.to_vec())
1441 } else {
1442 None
1443 },
1444 },
1445 );
1446 usize::try_from(pathid).unwrap()
1447 }
1448 }
1449 })
1450 };
1451 item.parent_idx = item.parent.and_then(|p| defid_to_rowid(p, false));
1452 item.trait_parent_idx = item.trait_parent.and_then(|p| defid_to_rowid(p, true));
1453
1454 if let Some(defid) = item.defid
1455 && item.parent_idx.is_none()
1456 {
1457 let exact_fqp = cache
1461 .exact_paths
1462 .get(&defid)
1463 .or_else(|| cache.external_paths.get(&defid).map(|(fqp, _)| fqp));
1464 item.exact_module_path = exact_fqp.and_then(|fqp| {
1465 if fqp.last() != Some(&item.name) {
1472 return None;
1473 }
1474 let path = if item.info.ty == ItemType::Macro
1475 && find_attr!(tcx, defid, MacroExport { .. })
1476 {
1477 vec![tcx.crate_name(defid.krate)]
1479 } else {
1480 if fqp.len() < 2 {
1481 return None;
1482 }
1483 fqp[..fqp.len() - 1].to_vec()
1484 };
1485 if path == item.module_path {
1486 return None;
1487 }
1488 Some(path)
1489 });
1490 } else if let Some(parent_idx) = item.parent_idx {
1491 let i = usize::try_from(parent_idx).unwrap();
1492 item.module_path =
1493 serialized_index.path_data[i].as_ref().unwrap().module_path.clone();
1494 item.exact_module_path =
1495 serialized_index.path_data[i].as_ref().unwrap().exact_module_path.clone();
1496 }
1497
1498 &mut *item
1499 })
1500 .collect();
1501
1502 let mut associated_item_duplicates = FxHashMap::<(usize, ItemType, Symbol), usize>::default();
1505 for item in crate_items.iter().map(|x| &*x) {
1506 if item.impl_id.is_some()
1507 && let Some(parent_idx) = item.parent_idx
1508 {
1509 let count = associated_item_duplicates
1510 .entry((parent_idx, item.info.ty, item.name))
1511 .or_insert(0);
1512 *count += 1;
1513 }
1514 }
1515
1516 for item in crate_items {
1518 assert_eq!(
1519 item.parent.is_some(),
1520 item.parent_idx.is_some(),
1521 "`{}` is missing idx",
1522 item.name
1523 );
1524
1525 let module_path = Some(serialized_index.get_id_by_module_path(&item.module_path));
1526 let exact_module_path = item
1527 .exact_module_path
1528 .as_ref()
1529 .map(|path| serialized_index.get_id_by_module_path(path));
1530
1531 let new_entry_id = serialized_index.add_entry(
1532 item.name,
1533 EntryData {
1534 ty: item.info.ty,
1535 parent: item.parent_idx,
1536 trait_parent: item.trait_parent_idx,
1537 module_path,
1538 exact_module_path,
1539 deprecated: item
1540 .info
1541 .deprecation
1542 .is_some_and(|deprecation| deprecation.is_in_effect()),
1543 unstable: item.info.is_unstable,
1544 associated_item_disambiguator_or_extern_crate_url: if let Some(impl_id) =
1545 item.impl_id
1546 && let Some(parent_idx) = item.parent_idx
1547 && associated_item_duplicates
1548 .get(&(parent_idx, item.info.ty, item.name))
1549 .copied()
1550 .unwrap_or(0)
1551 > 1
1552 {
1553 Some(render::get_id_for_impl(tcx, ItemId::DefId(impl_id)))
1554 } else if item.info.ty == ItemType::ExternCrate
1555 && let Some(local_def_id) = item.defid.and_then(|def_id| def_id.as_local())
1556 && let cnum = tcx.extern_mod_stmt_cnum(local_def_id).unwrap_or(LOCAL_CRATE)
1557 && let Some(ExternalLocation::Remote { url, is_absolute }) =
1558 cache.extern_locations.get(&cnum)
1559 && *is_absolute
1560 {
1561 Some(format!("{}{}", url, tcx.crate_name(cnum).as_str()))
1562 } else {
1563 None
1564 },
1565 krate: crate_idx,
1566 },
1567 item.info.desc.to_string(),
1568 );
1569
1570 for alias in &item.info.aliases {
1573 serialized_index.push_alias(alias.as_str().to_string(), new_entry_id);
1574 }
1575
1576 fn insert_into_map(
1579 ty: ItemType,
1580 path: &[Symbol],
1581 exact_path: Option<&[Symbol]>,
1582 search_unbox: bool,
1583 serialized_index: &mut SerializedSearchIndex,
1584 used_in_function_signature: &mut BTreeSet<isize>,
1585 ) -> RenderTypeId {
1586 let pathid = serialized_index.names.len();
1587 let pathid = match serialized_index.crate_paths_index.entry((ty, path.to_vec())) {
1588 Entry::Occupied(entry) => {
1589 let id = *entry.get();
1590 if serialized_index.type_data[id].as_mut().is_none() {
1591 serialized_index.type_data[id] = Some(TypeData {
1592 search_unbox,
1593 inverted_function_inputs_index: Vec::new(),
1594 inverted_function_output_index: Vec::new(),
1595 });
1596 } else if search_unbox {
1597 serialized_index.type_data[id].as_mut().unwrap().search_unbox = true;
1598 }
1599 id
1600 }
1601 Entry::Vacant(entry) => {
1602 entry.insert(pathid);
1603 let (name, path) = path.split_last().unwrap();
1604 serialized_index.push_type(
1605 name.to_string(),
1606 PathData {
1607 ty,
1608 module_path: path.to_vec(),
1609 exact_module_path: if let Some(exact_path) = exact_path
1610 && let Some((name2, exact_path)) = exact_path.split_last()
1611 && name == name2
1612 {
1613 Some(exact_path.to_vec())
1614 } else {
1615 None
1616 },
1617 },
1618 TypeData {
1619 inverted_function_inputs_index: Vec::new(),
1620 inverted_function_output_index: Vec::new(),
1621 search_unbox,
1622 },
1623 );
1624 pathid
1625 }
1626 };
1627 used_in_function_signature.insert(isize::try_from(pathid).unwrap());
1628 RenderTypeId::Index(isize::try_from(pathid).unwrap())
1629 }
1630
1631 fn convert_render_type_id(
1632 id: RenderTypeId,
1633 cache: &mut Cache,
1634 serialized_index: &mut SerializedSearchIndex,
1635 used_in_function_signature: &mut BTreeSet<isize>,
1636 tcx: TyCtxt<'_>,
1637 ) -> Option<RenderTypeId> {
1638 use crate::clean::PrimitiveType;
1639 let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache;
1640 let search_unbox = match id {
1641 RenderTypeId::Mut => false,
1642 RenderTypeId::DefId(defid) => {
1643 utils::has_doc_flag(tcx, defid, |d| d.search_unbox.is_some())
1644 }
1645 RenderTypeId::Primitive(
1646 PrimitiveType::Reference | PrimitiveType::RawPointer | PrimitiveType::Tuple,
1647 ) => true,
1648 RenderTypeId::Primitive(..) => false,
1649 RenderTypeId::AssociatedType(..) => false,
1650 RenderTypeId::Index(_) => false,
1653 };
1654 match id {
1655 RenderTypeId::Mut => Some(insert_into_map(
1656 ItemType::Keyword,
1657 &[kw::Mut],
1658 None,
1659 search_unbox,
1660 serialized_index,
1661 used_in_function_signature,
1662 )),
1663 RenderTypeId::DefId(defid) => {
1664 if let Some(&(ref fqp, item_type)) =
1665 paths.get(&defid).or_else(|| external_paths.get(&defid))
1666 {
1667 if tcx.lang_items().fn_mut_trait() == Some(defid)
1668 || tcx.lang_items().fn_once_trait() == Some(defid)
1669 || tcx.lang_items().fn_trait() == Some(defid)
1670 {
1671 let name = *fqp.last().unwrap();
1672 Some(insert_into_map(
1677 item_type,
1678 &[sym::core, sym::ops, name],
1679 Some(&[sym::core, sym::ops, name]),
1680 search_unbox,
1681 serialized_index,
1682 used_in_function_signature,
1683 ))
1684 } else {
1685 let exact_fqp = exact_paths
1686 .get(&defid)
1687 .or_else(|| external_paths.get(&defid).map(|(fqp, _)| fqp))
1688 .map(|v| &v[..])
1689 .filter(|this_fqp| this_fqp.last() == fqp.last());
1696 Some(insert_into_map(
1697 item_type,
1698 fqp,
1699 exact_fqp,
1700 search_unbox,
1701 serialized_index,
1702 used_in_function_signature,
1703 ))
1704 }
1705 } else {
1706 None
1707 }
1708 }
1709 RenderTypeId::Primitive(primitive) => {
1710 let sym = primitive.as_sym();
1711 Some(insert_into_map(
1712 ItemType::Primitive,
1713 &[sym],
1714 None,
1715 search_unbox,
1716 serialized_index,
1717 used_in_function_signature,
1718 ))
1719 }
1720 RenderTypeId::Index(index) => {
1721 used_in_function_signature.insert(index);
1722 Some(id)
1723 }
1724 RenderTypeId::AssociatedType(sym) => Some(insert_into_map(
1725 ItemType::AssocType,
1726 &[sym],
1727 None,
1728 search_unbox,
1729 serialized_index,
1730 used_in_function_signature,
1731 )),
1732 }
1733 }
1734
1735 fn convert_render_type(
1736 ty: &mut RenderType,
1737 cache: &mut Cache,
1738 serialized_index: &mut SerializedSearchIndex,
1739 used_in_function_signature: &mut BTreeSet<isize>,
1740 tcx: TyCtxt<'_>,
1741 ) {
1742 if let Some(generics) = &mut ty.generics {
1743 for item in generics {
1744 convert_render_type(
1745 item,
1746 cache,
1747 serialized_index,
1748 used_in_function_signature,
1749 tcx,
1750 );
1751 }
1752 }
1753 if let Some(bindings) = &mut ty.bindings {
1754 bindings.retain_mut(|(associated_type, constraints)| {
1755 let converted_associated_type = convert_render_type_id(
1756 *associated_type,
1757 cache,
1758 serialized_index,
1759 used_in_function_signature,
1760 tcx,
1761 );
1762 let Some(converted_associated_type) = converted_associated_type else {
1763 return false;
1764 };
1765 *associated_type = converted_associated_type;
1766 for constraint in constraints {
1767 convert_render_type(
1768 constraint,
1769 cache,
1770 serialized_index,
1771 used_in_function_signature,
1772 tcx,
1773 );
1774 }
1775 true
1776 });
1777 }
1778 let Some(id) = ty.id else {
1779 assert!(ty.generics.is_some());
1780 return;
1781 };
1782 ty.id = if let RenderTypeId::DefId(def_id) = id
1783 && matches!(tcx.def_kind(def_id), rustc_hir::def::DefKind::OpaqueTy)
1784 {
1785 None
1788 } else {
1789 convert_render_type_id(id, cache, serialized_index, used_in_function_signature, tcx)
1790 };
1791 use crate::clean::PrimitiveType;
1792 match id {
1796 RenderTypeId::Primitive(PrimitiveType::Array | PrimitiveType::Slice) => {
1798 insert_into_map(
1799 ItemType::Primitive,
1800 &[sym::empty_brackets],
1801 None,
1802 false,
1803 serialized_index,
1804 used_in_function_signature,
1805 );
1806 }
1807 RenderTypeId::Primitive(PrimitiveType::Tuple | PrimitiveType::Unit) => {
1808 insert_into_map(
1810 ItemType::Primitive,
1811 &[sym::empty_parens],
1812 None,
1813 false,
1814 serialized_index,
1815 used_in_function_signature,
1816 );
1817 }
1818 RenderTypeId::Primitive(PrimitiveType::Fn) => {
1820 insert_into_map(
1821 ItemType::Primitive,
1822 &[sym::right_arrow],
1823 None,
1824 false,
1825 serialized_index,
1826 used_in_function_signature,
1827 );
1828 }
1829 RenderTypeId::DefId(did)
1830 if tcx.lang_items().fn_mut_trait() == Some(did)
1831 || tcx.lang_items().fn_once_trait() == Some(did)
1832 || tcx.lang_items().fn_trait() == Some(did) =>
1833 {
1834 insert_into_map(
1835 ItemType::Primitive,
1836 &[sym::right_arrow],
1837 None,
1838 false,
1839 serialized_index,
1840 used_in_function_signature,
1841 );
1842 }
1843 _ => {}
1845 }
1846 }
1847 if let Some(search_type) = &mut item.info.search_type {
1848 let mut used_in_function_inputs = BTreeSet::new();
1849 let mut used_in_function_output = BTreeSet::new();
1850 for item in &mut search_type.inputs {
1851 convert_render_type(
1852 item,
1853 cache,
1854 &mut serialized_index,
1855 &mut used_in_function_inputs,
1856 tcx,
1857 );
1858 }
1859 for item in &mut search_type.output {
1860 convert_render_type(
1861 item,
1862 cache,
1863 &mut serialized_index,
1864 &mut used_in_function_output,
1865 tcx,
1866 );
1867 }
1868 let used_in_constraints = search_type
1869 .where_clause
1870 .iter_mut()
1871 .map(|constraint| {
1872 let mut used_in_constraint = BTreeSet::new();
1873 for trait_ in constraint {
1874 convert_render_type(
1875 trait_,
1876 cache,
1877 &mut serialized_index,
1878 &mut used_in_constraint,
1879 tcx,
1880 );
1881 }
1882 used_in_constraint
1883 })
1884 .collect::<Vec<_>>();
1885 loop {
1886 let mut inserted_any = false;
1887 for (i, used_in_constraint) in used_in_constraints.iter().enumerate() {
1888 let id = !(i as isize);
1889 if used_in_function_inputs.contains(&id)
1890 && !used_in_function_inputs.is_superset(&used_in_constraint)
1891 {
1892 used_in_function_inputs.extend(used_in_constraint.iter().copied());
1893 inserted_any = true;
1894 }
1895 if used_in_function_output.contains(&id)
1896 && !used_in_function_output.is_superset(&used_in_constraint)
1897 {
1898 used_in_function_output.extend(used_in_constraint.iter().copied());
1899 inserted_any = true;
1900 }
1901 }
1902 if !inserted_any {
1903 break;
1904 }
1905 }
1906 let search_type_size = search_type.size() +
1907 if item.info.ty.is_fn_like() { 0 } else { 16 };
1915 serialized_index.function_data[new_entry_id] = Some(search_type.clone());
1916
1917 #[derive(Clone, Copy)]
1918 enum InvertedIndexType {
1919 Inputs,
1920 Output,
1921 }
1922 impl InvertedIndexType {
1923 fn from_type_data(self, type_data: &mut TypeData) -> &mut Vec<Vec<u32>> {
1924 match self {
1925 Self::Inputs => &mut type_data.inverted_function_inputs_index,
1926 Self::Output => &mut type_data.inverted_function_output_index,
1927 }
1928 }
1929 }
1930
1931 let mut process_used_in_function =
1932 |used_in_function: BTreeSet<isize>, index_type: InvertedIndexType| {
1933 for index in used_in_function {
1934 let postings = if index >= 0 {
1935 assert!(serialized_index.path_data[index as usize].is_some());
1936 index_type.from_type_data(
1937 serialized_index.type_data[index as usize].as_mut().unwrap(),
1938 )
1939 } else {
1940 let generic_id = index.unsigned_abs() - 1;
1941 if generic_id >= serialized_index.generic_inverted_index.len() {
1942 serialized_index
1943 .generic_inverted_index
1944 .resize(generic_id + 1, Vec::new());
1945 }
1946 &mut serialized_index.generic_inverted_index[generic_id]
1947 };
1948 if search_type_size >= postings.len() {
1949 postings.resize(search_type_size + 1, Vec::new());
1950 }
1951 let posting = &mut postings[search_type_size];
1952 if posting.last() != Some(&(new_entry_id as u32)) {
1953 posting.push(new_entry_id as u32);
1954 }
1955 }
1956 };
1957
1958 process_used_in_function(used_in_function_inputs, InvertedIndexType::Inputs);
1959 process_used_in_function(used_in_function_output, InvertedIndexType::Output);
1960 }
1961 }
1962
1963 Ok(serialized_index.sort())
1964}
1965
1966pub(crate) fn get_function_type_for_search(
1967 item: &clean::Item,
1968 tcx: TyCtxt<'_>,
1969 impl_generics: Option<&(clean::Type, clean::Generics)>,
1970 parent: Option<DefId>,
1971 cache: &Cache,
1972) -> Option<IndexItemFunctionType> {
1973 let mut trait_info = None;
1974 let impl_or_trait_generics = impl_generics.or_else(|| {
1975 if let Some(def_id) = parent
1976 && let Some(trait_) = cache.traits.get(&def_id)
1977 && let Some((path, _)) =
1978 cache.paths.get(&def_id).or_else(|| cache.external_paths.get(&def_id))
1979 {
1980 let path = clean::Path {
1981 res: rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Trait, def_id),
1982 segments: path
1983 .iter()
1984 .map(|name| clean::PathSegment {
1985 name: *name,
1986 args: clean::GenericArgs::AngleBracketed {
1987 args: ThinVec::new(),
1988 constraints: ThinVec::new(),
1989 },
1990 })
1991 .collect(),
1992 };
1993 trait_info = Some((clean::Type::Path { path }, trait_.generics.clone()));
1994 Some(trait_info.as_ref().unwrap())
1995 } else {
1996 None
1997 }
1998 });
1999 let (mut inputs, mut output, param_names, where_clause) = match item.kind {
2000 clean::ForeignFunctionItem(ref f, _)
2001 | clean::FunctionItem(ref f)
2002 | clean::MethodItem(ref f, _)
2003 | clean::RequiredMethodItem(ref f, _) => {
2004 get_fn_inputs_and_outputs(f, tcx, impl_or_trait_generics, cache)
2005 }
2006 clean::ConstantItem(ref c) => make_nullary_fn(&c.type_),
2007 clean::StaticItem(ref s) => make_nullary_fn(&s.type_),
2008 clean::StructFieldItem(ref t) if let Some(parent) = parent => {
2009 let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> =
2010 Default::default();
2011 let output = get_index_type(t, vec![], &mut rgen);
2012 let input = RenderType {
2013 id: Some(RenderTypeId::DefId(parent)),
2014 generics: None,
2015 bindings: None,
2016 };
2017 (vec![input], vec![output], vec![], vec![])
2018 }
2019 _ => return None,
2020 };
2021
2022 inputs.retain(|a| a.id.is_some() || a.generics.is_some());
2023 output.retain(|a| a.id.is_some() || a.generics.is_some());
2024
2025 Some(IndexItemFunctionType { inputs, output, where_clause, param_names })
2026}
2027
2028fn get_index_type(
2029 clean_type: &clean::Type,
2030 generics: Vec<RenderType>,
2031 rgen: &mut FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)>,
2032) -> RenderType {
2033 RenderType {
2034 id: get_index_type_id(clean_type, rgen),
2035 generics: if generics.is_empty() { None } else { Some(generics) },
2036 bindings: None,
2037 }
2038}
2039
2040fn get_index_type_id(
2041 clean_type: &clean::Type,
2042 rgen: &mut FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)>,
2043) -> Option<RenderTypeId> {
2044 use rustc_hir::def::{DefKind, Res};
2045 match *clean_type {
2046 clean::Type::Path { ref path, .. } => Some(RenderTypeId::DefId(path.def_id())),
2047 clean::DynTrait(ref bounds, _) => {
2048 bounds.first().map(|b| RenderTypeId::DefId(b.trait_.def_id()))
2049 }
2050 clean::Primitive(p) => Some(RenderTypeId::Primitive(p)),
2051 clean::BorrowedRef { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::Reference)),
2052 clean::RawPointer { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::RawPointer)),
2053 clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)),
2055 clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)),
2056 clean::BareFunction(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Fn)),
2057 clean::Tuple(ref n) if n.is_empty() => {
2058 Some(RenderTypeId::Primitive(clean::PrimitiveType::Unit))
2059 }
2060 clean::Tuple(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Tuple)),
2061 clean::QPath(ref data) => {
2062 if data.self_type.is_self_type()
2063 && let Some(clean::Path { res: Res::Def(DefKind::Trait, trait_), .. }) = data.trait_
2064 {
2065 let idx = -isize::try_from(rgen.len() + 1).unwrap();
2066 let (idx, _) = rgen
2067 .entry(SimplifiedParam::AssociatedType(trait_, data.assoc.name))
2068 .or_insert_with(|| (idx, Vec::new()));
2069 Some(RenderTypeId::Index(*idx))
2070 } else {
2071 None
2072 }
2073 }
2074 clean::Type::Pat(..)
2076 | clean::Type::FieldOf(..)
2077 | clean::Generic(_)
2078 | clean::SelfTy
2079 | clean::ImplTrait(_)
2080 | clean::Infer
2081 | clean::UnsafeBinder(_) => None,
2082 }
2083}
2084
2085#[derive(Clone, Copy, Eq, Hash, PartialEq)]
2086enum SimplifiedParam {
2087 Symbol(Symbol),
2089 Anonymous(isize),
2091 AssociatedType(DefId, Symbol),
2094}
2095
2096#[instrument(level = "trace", skip(tcx, rgen, cache))]
2106fn simplify_fn_type<'a, 'tcx>(
2107 self_: Option<&'a Type>,
2108 generics: &Generics,
2109 arg: &'a Type,
2110 tcx: TyCtxt<'tcx>,
2111 recurse: usize,
2112 rgen: &mut FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)>,
2113 is_return: bool,
2114 cache: &Cache,
2115) -> Option<RenderType> {
2116 if recurse >= 10 {
2117 return None;
2120 }
2121
2122 let (is_self, arg) = if let Some(self_) = self_
2124 && arg.is_self_type()
2125 {
2126 (true, self_)
2127 } else {
2128 (false, arg)
2129 };
2130
2131 match *arg {
2134 Type::Generic(arg_s) => {
2135 let where_bounds = generics
2137 .where_predicates
2138 .iter()
2139 .filter_map(|g| {
2140 if let WherePredicate::BoundPredicate { ty, bounds, .. } = g
2141 && *ty == *arg
2142 {
2143 Some(bounds)
2144 } else {
2145 None
2146 }
2147 })
2148 .flatten();
2149 let inline_bounds = generics
2151 .params
2152 .iter()
2153 .find(|g| g.is_type() && g.name == arg_s)
2154 .and_then(|bound| bound.get_bounds())
2155 .into_iter()
2156 .flatten();
2157
2158 let type_bounds = where_bounds
2159 .chain(inline_bounds)
2160 .filter_map(
2161 |bound| if let Some(path) = bound.get_trait_path() { Some(path) } else { None },
2162 )
2163 .filter_map(|path| {
2164 let ty = Type::Path { path };
2165 simplify_fn_type(self_, generics, &ty, tcx, recurse + 1, rgen, is_return, cache)
2166 })
2167 .collect();
2168
2169 Some(if let Some((idx, _)) = rgen.get(&SimplifiedParam::Symbol(arg_s)) {
2170 RenderType { id: Some(RenderTypeId::Index(*idx)), generics: None, bindings: None }
2171 } else {
2172 let idx = -isize::try_from(rgen.len() + 1).unwrap();
2173 rgen.insert(SimplifiedParam::Symbol(arg_s), (idx, type_bounds));
2174 RenderType { id: Some(RenderTypeId::Index(idx)), generics: None, bindings: None }
2175 })
2176 }
2177 Type::ImplTrait(ref bounds) => {
2178 let type_bounds = bounds
2179 .iter()
2180 .filter_map(|bound| bound.get_trait_path())
2181 .filter_map(|path| {
2182 let ty = Type::Path { path };
2183 simplify_fn_type(self_, generics, &ty, tcx, recurse + 1, rgen, is_return, cache)
2184 })
2185 .collect::<Vec<_>>();
2186 Some(if is_return && !type_bounds.is_empty() {
2187 RenderType { id: None, generics: Some(type_bounds), bindings: None }
2189 } else {
2190 let idx = -isize::try_from(rgen.len() + 1).unwrap();
2192 rgen.insert(SimplifiedParam::Anonymous(idx), (idx, type_bounds));
2193 RenderType { id: Some(RenderTypeId::Index(idx)), generics: None, bindings: None }
2194 })
2195 }
2196 Type::Slice(ref ty) => {
2197 let ty_generics =
2198 simplify_fn_type(self_, generics, ty, tcx, recurse + 1, rgen, is_return, cache)
2199 .into_iter()
2200 .collect();
2201 Some(get_index_type(arg, ty_generics, rgen))
2202 }
2203 Type::Array(ref ty, _) => {
2204 let ty_generics =
2205 simplify_fn_type(self_, generics, ty, tcx, recurse + 1, rgen, is_return, cache)
2206 .into_iter()
2207 .collect();
2208 Some(get_index_type(arg, ty_generics, rgen))
2209 }
2210 Type::Tuple(ref tys) => {
2211 let ty_generics = tys
2212 .iter()
2213 .filter_map(|ty| {
2214 simplify_fn_type(self_, generics, ty, tcx, recurse + 1, rgen, is_return, cache)
2215 })
2216 .collect();
2217 Some(get_index_type(arg, ty_generics, rgen))
2218 }
2219 Type::BareFunction(ref bf) => {
2220 let ty_generics = bf
2221 .decl
2222 .inputs
2223 .iter()
2224 .map(|arg| &arg.type_)
2225 .filter_map(|ty| {
2226 simplify_fn_type(self_, generics, ty, tcx, recurse + 1, rgen, is_return, cache)
2227 })
2228 .collect();
2229 let ty_output = simplify_fn_type(
2233 self_,
2234 generics,
2235 &bf.decl.output,
2236 tcx,
2237 recurse + 1,
2238 rgen,
2239 is_return,
2240 cache,
2241 )
2242 .into_iter()
2243 .collect();
2244 let ty_bindings = vec![(RenderTypeId::AssociatedType(sym::Output), ty_output)];
2245 Some(RenderType {
2246 id: get_index_type_id(arg, rgen),
2247 bindings: Some(ty_bindings),
2248 generics: Some(ty_generics),
2249 })
2250 }
2251 Type::BorrowedRef { lifetime: _, mutability, ref type_ }
2252 | Type::RawPointer(mutability, ref type_) => {
2253 let mut ty_generics = Vec::new();
2254 if mutability.is_mut() {
2255 ty_generics.push(RenderType {
2256 id: Some(RenderTypeId::Mut),
2257 generics: None,
2258 bindings: None,
2259 });
2260 }
2261 if let Some(ty) =
2262 simplify_fn_type(self_, generics, type_, tcx, recurse + 1, rgen, is_return, cache)
2263 {
2264 ty_generics.push(ty);
2265 }
2266 Some(get_index_type(arg, ty_generics, rgen))
2267 }
2268 _ => {
2269 let mut ty_generics = Vec::new();
2275 let mut ty_constraints = Vec::new();
2276 if let Some(arg_generics) = arg.generic_args() {
2277 ty_generics = arg_generics
2278 .into_iter()
2279 .filter_map(|param| match param {
2280 clean::GenericArg::Type(ty) => Some(ty),
2281 _ => None,
2282 })
2283 .filter_map(|ty| {
2284 simplify_fn_type(
2285 self_,
2286 generics,
2287 &ty,
2288 tcx,
2289 recurse + 1,
2290 rgen,
2291 is_return,
2292 cache,
2293 )
2294 })
2295 .collect();
2296 for constraint in arg_generics.constraints() {
2297 simplify_fn_constraint(
2298 self_,
2299 generics,
2300 &constraint,
2301 tcx,
2302 recurse + 1,
2303 &mut ty_constraints,
2304 rgen,
2305 is_return,
2306 cache,
2307 );
2308 }
2309 }
2310 if is_self
2323 && let Type::Path { path } = arg
2324 && let def_id = path.def_id()
2325 && let Some(trait_) = cache.traits.get(&def_id)
2326 && trait_.items.iter().any(|at| at.is_required_associated_type())
2327 {
2328 for assoc_ty in &trait_.items {
2329 if let clean::ItemKind::RequiredAssocTypeItem(_generics, bounds) =
2330 &assoc_ty.kind
2331 && let Some(name) = assoc_ty.name
2332 {
2333 let idx = -isize::try_from(rgen.len() + 1).unwrap();
2334 let (idx, stored_bounds) = rgen
2335 .entry(SimplifiedParam::AssociatedType(def_id, name))
2336 .or_insert_with(|| (idx, Vec::new()));
2337 let idx = *idx;
2338 if stored_bounds.is_empty() {
2339 let type_bounds = bounds
2343 .iter()
2344 .filter_map(|bound| bound.get_trait_path())
2345 .filter_map(|path| {
2346 let ty = Type::Path { path };
2347 simplify_fn_type(
2348 self_,
2349 generics,
2350 &ty,
2351 tcx,
2352 recurse + 1,
2353 rgen,
2354 is_return,
2355 cache,
2356 )
2357 })
2358 .collect();
2359 let stored_bounds = &mut rgen
2360 .get_mut(&SimplifiedParam::AssociatedType(def_id, name))
2361 .unwrap()
2362 .1;
2363 if stored_bounds.is_empty() {
2364 *stored_bounds = type_bounds;
2365 }
2366 }
2367 ty_constraints.push((
2368 RenderTypeId::AssociatedType(name),
2369 vec![RenderType {
2370 id: Some(RenderTypeId::Index(idx)),
2371 generics: None,
2372 bindings: None,
2373 }],
2374 ))
2375 }
2376 }
2377 }
2378 let id = get_index_type_id(arg, rgen);
2379 if id.is_some() || !ty_generics.is_empty() {
2380 Some(RenderType {
2381 id,
2382 bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) },
2383 generics: if ty_generics.is_empty() { None } else { Some(ty_generics) },
2384 })
2385 } else {
2386 None
2387 }
2388 }
2389 }
2390}
2391
2392fn simplify_fn_constraint<'a>(
2393 self_: Option<&'a Type>,
2394 generics: &Generics,
2395 constraint: &'a clean::AssocItemConstraint,
2396 tcx: TyCtxt<'_>,
2397 recurse: usize,
2398 res: &mut Vec<(RenderTypeId, Vec<RenderType>)>,
2399 rgen: &mut FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)>,
2400 is_return: bool,
2401 cache: &Cache,
2402) {
2403 let mut ty_constraints = Vec::new();
2404 let ty_constrained_assoc = RenderTypeId::AssociatedType(constraint.assoc.name);
2405 for param in &constraint.assoc.args {
2406 match param {
2407 clean::GenericArg::Type(arg) => {
2408 ty_constraints.extend(simplify_fn_type(
2409 self_,
2410 generics,
2411 &arg,
2412 tcx,
2413 recurse + 1,
2414 rgen,
2415 is_return,
2416 cache,
2417 ));
2418 }
2419 clean::GenericArg::Lifetime(_)
2420 | clean::GenericArg::Const(_)
2421 | clean::GenericArg::Infer => {}
2422 }
2423 }
2424 for constraint in constraint.assoc.args.constraints() {
2425 simplify_fn_constraint(
2426 self_,
2427 generics,
2428 &constraint,
2429 tcx,
2430 recurse + 1,
2431 res,
2432 rgen,
2433 is_return,
2434 cache,
2435 );
2436 }
2437 match &constraint.kind {
2438 clean::AssocItemConstraintKind::Equality { term } => {
2439 if let clean::Term::Type(arg) = &term {
2440 ty_constraints.extend(simplify_fn_type(
2441 self_,
2442 generics,
2443 arg,
2444 tcx,
2445 recurse + 1,
2446 rgen,
2447 is_return,
2448 cache,
2449 ));
2450 }
2451 }
2452 clean::AssocItemConstraintKind::Bound { bounds } => {
2453 for bound in &bounds[..] {
2454 if let Some(path) = bound.get_trait_path() {
2455 let ty = Type::Path { path };
2456 ty_constraints.extend(simplify_fn_type(
2457 self_,
2458 generics,
2459 &ty,
2460 tcx,
2461 recurse + 1,
2462 rgen,
2463 is_return,
2464 cache,
2465 ));
2466 }
2467 }
2468 }
2469 }
2470 res.push((ty_constrained_assoc, ty_constraints));
2471}
2472
2473fn make_nullary_fn(
2477 clean_type: &clean::Type,
2478) -> (Vec<RenderType>, Vec<RenderType>, Vec<Option<Symbol>>, Vec<Vec<RenderType>>) {
2479 let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> = Default::default();
2480 let output = get_index_type(clean_type, vec![], &mut rgen);
2481 (vec![], vec![output], vec![], vec![])
2482}
2483
2484fn get_fn_inputs_and_outputs(
2489 func: &Function,
2490 tcx: TyCtxt<'_>,
2491 impl_or_trait_generics: Option<&(clean::Type, clean::Generics)>,
2492 cache: &Cache,
2493) -> (Vec<RenderType>, Vec<RenderType>, Vec<Option<Symbol>>, Vec<Vec<RenderType>>) {
2494 let decl = &func.decl;
2495
2496 let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> = Default::default();
2497
2498 let combined_generics;
2499 let (self_, generics) = if let Some((impl_self, impl_generics)) = impl_or_trait_generics {
2500 match (impl_generics.is_empty(), func.generics.is_empty()) {
2501 (true, _) => (Some(impl_self), &func.generics),
2502 (_, true) => (Some(impl_self), impl_generics),
2503 (false, false) => {
2504 let params =
2505 func.generics.params.iter().chain(&impl_generics.params).cloned().collect();
2506 let where_predicates = func
2507 .generics
2508 .where_predicates
2509 .iter()
2510 .chain(&impl_generics.where_predicates)
2511 .cloned()
2512 .collect();
2513 combined_generics = clean::Generics { params, where_predicates };
2514 (Some(impl_self), &combined_generics)
2515 }
2516 }
2517 } else {
2518 (None, &func.generics)
2519 };
2520
2521 let param_types = decl
2522 .inputs
2523 .iter()
2524 .filter_map(|param| {
2525 simplify_fn_type(self_, generics, ¶m.type_, tcx, 0, &mut rgen, false, cache)
2526 })
2527 .collect();
2528
2529 let ret_types = simplify_fn_type(self_, generics, &decl.output, tcx, 0, &mut rgen, true, cache)
2530 .into_iter()
2531 .collect();
2532
2533 let mut simplified_params = rgen.into_iter().collect::<Vec<_>>();
2534 simplified_params.sort_by_key(|(_, (idx, _))| -idx);
2535 (
2536 param_types,
2537 ret_types,
2538 simplified_params
2539 .iter()
2540 .map(|(name, (_idx, _traits))| match name {
2541 SimplifiedParam::Symbol(name) => Some(*name),
2542 SimplifiedParam::Anonymous(_) => None,
2543 SimplifiedParam::AssociatedType(def_id, name) => {
2544 Some(Symbol::intern(&format!("{}::{}", tcx.item_name(*def_id), name)))
2545 }
2546 })
2547 .collect(),
2548 simplified_params.into_iter().map(|(_name, (_idx, traits))| traits).collect(),
2549 )
2550}