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