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