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