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_signature_index: other_type_data
293 .inverted_function_signature_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 }),
311 (Some(mut self_type_data), Some(other_type_data)) => {
312 for (size, other_list) in other_type_data
313 .inverted_function_signature_index
314 .iter()
315 .enumerate()
316 {
317 while self_type_data.inverted_function_signature_index.len()
318 <= size
319 {
320 self_type_data
321 .inverted_function_signature_index
322 .push(Vec::new());
323 }
324 self_type_data.inverted_function_signature_index[size].extend(
325 other_list.iter().copied().map(|fnid| {
326 assert!(
327 other.function_data[usize::try_from(fnid).unwrap()]
328 .is_some(),
329 );
330 fnid + u32::try_from(other_entryid_offset).unwrap()
333 }),
334 )
335 }
336 Some(self_type_data)
337 }
338 (None, None) => None,
339 };
340 self.type_data[self_pathid] = new_type_data;
341 self_pathid
342 }
343 };
344 map_other_pathid_to_self_pathid.push(self_pathid);
345 } else {
346 map_other_pathid_to_self_pathid.push(!0);
350 }
351 }
352 for other_entryid in 0..other.names.len() {
353 if skips.contains(&other_entryid) {
354 self.push(String::new(), None, None, String::new(), None, None, None);
356 } else {
357 self.push(
358 other.names[other_entryid].clone(),
359 other.path_data[other_entryid].clone(),
360 other.entry_data[other_entryid].as_ref().map(|other_entry_data| EntryData {
361 parent: other_entry_data
362 .parent
363 .map(|parent| map_other_pathid_to_self_pathid[parent])
364 .clone(),
365 module_path: other_entry_data
366 .module_path
367 .map(|path| map_other_pathid_to_self_pathid[path])
368 .clone(),
369 exact_module_path: other_entry_data
370 .exact_module_path
371 .map(|exact_path| map_other_pathid_to_self_pathid[exact_path])
372 .clone(),
373 krate: map_other_pathid_to_self_pathid[other_entry_data.krate],
374 ..other_entry_data.clone()
375 }),
376 other.descs[other_entryid].clone(),
377 other.function_data[other_entryid].as_ref().map(|function_data| FunctionData {
378 function_signature: {
379 let (mut func, _offset) =
380 IndexItemFunctionType::read_from_string_without_param_names(
381 function_data.function_signature.as_bytes(),
382 );
383 fn map_fn_sig_item(
384 map_other_pathid_to_self_pathid: &mut Vec<usize>,
385 ty: &mut RenderType,
386 ) {
387 match ty.id {
388 None => {}
389 Some(RenderTypeId::Index(generic)) if generic < 0 => {}
390 Some(RenderTypeId::Index(id)) => {
391 let id = usize::try_from(id).unwrap();
392 let id = map_other_pathid_to_self_pathid[id];
393 assert!(id != !0);
394 ty.id =
395 Some(RenderTypeId::Index(isize::try_from(id).unwrap()));
396 }
397 _ => unreachable!(),
398 }
399 if let Some(generics) = &mut ty.generics {
400 for generic in generics {
401 map_fn_sig_item(map_other_pathid_to_self_pathid, generic);
402 }
403 }
404 if let Some(bindings) = &mut ty.bindings {
405 for (param, constraints) in bindings {
406 *param = match *param {
407 param @ RenderTypeId::Index(generic) if generic < 0 => {
408 param
409 }
410 RenderTypeId::Index(id) => {
411 let id = usize::try_from(id).unwrap();
412 let id = map_other_pathid_to_self_pathid[id];
413 assert!(id != !0);
414 RenderTypeId::Index(isize::try_from(id).unwrap())
415 }
416 _ => unreachable!(),
417 };
418 for constraint in constraints {
419 map_fn_sig_item(
420 map_other_pathid_to_self_pathid,
421 constraint,
422 );
423 }
424 }
425 }
426 }
427 for input in &mut func.inputs {
428 map_fn_sig_item(&mut map_other_pathid_to_self_pathid, input);
429 }
430 for output in &mut func.output {
431 map_fn_sig_item(&mut map_other_pathid_to_self_pathid, output);
432 }
433 for clause in &mut func.where_clause {
434 for entry in clause {
435 map_fn_sig_item(&mut map_other_pathid_to_self_pathid, entry);
436 }
437 }
438 let mut result =
439 String::with_capacity(function_data.function_signature.len());
440 func.write_to_string_without_param_names(&mut result);
441 result
442 },
443 param_names: function_data.param_names.clone(),
444 }),
445 other.type_data[other_entryid].as_ref().map(|type_data| TypeData {
446 inverted_function_signature_index: type_data
447 .inverted_function_signature_index
448 .iter()
449 .cloned()
450 .map(|mut list| {
451 for fnid in &mut list {
452 assert!(
453 other.function_data[usize::try_from(*fnid).unwrap()]
454 .is_some(),
455 );
456 *fnid += u32::try_from(other_entryid_offset).unwrap();
459 }
460 list
461 })
462 .collect(),
463 search_unbox: type_data.search_unbox,
464 }),
465 other.alias_pointers[other_entryid]
466 .map(|alias_pointer| alias_pointer + other_entryid_offset),
467 );
468 }
469 }
470 for (i, other_generic_inverted_index) in other.generic_inverted_index.iter().enumerate() {
471 for (size, other_list) in other_generic_inverted_index.iter().enumerate() {
472 let self_generic_inverted_index = match self.generic_inverted_index.get_mut(i) {
473 Some(self_generic_inverted_index) => self_generic_inverted_index,
474 None => {
475 self.generic_inverted_index.push(Vec::new());
476 self.generic_inverted_index.last_mut().unwrap()
477 }
478 };
479 while self_generic_inverted_index.len() <= size {
480 self_generic_inverted_index.push(Vec::new());
481 }
482 self_generic_inverted_index[size].extend(
483 other_list
484 .iter()
485 .copied()
486 .map(|fnid| fnid + u32::try_from(other_entryid_offset).unwrap()),
487 );
488 }
489 }
490 self
491 }
492
493 pub(crate) fn sort(self) -> SerializedSearchIndex {
494 let mut idlist: Vec<usize> = (0..self.names.len()).collect();
495 idlist.sort_by_key(|&id| {
498 (
499 self.names[id].is_empty(),
500 self.names[id].len(),
501 &self.names[id],
502 self.entry_data[id].as_ref().map_or("", |entry| self.names[entry.krate].as_str()),
503 self.path_data[id].as_ref().map_or(&[][..], |entry| &entry.module_path[..]),
504 )
505 });
506 let map = FxHashMap::from_iter(
507 idlist.iter().enumerate().map(|(new_id, &old_id)| (old_id, new_id)),
508 );
509 let mut new = SerializedSearchIndex::default();
510 for &id in &idlist {
511 if self.names[id].is_empty() {
512 break;
513 }
514 new.push(
515 self.names[id].clone(),
516 self.path_data[id].clone(),
517 self.entry_data[id].as_ref().map(
518 |EntryData {
519 krate,
520 ty,
521 module_path,
522 exact_module_path,
523 parent,
524 deprecated,
525 associated_item_disambiguator,
526 }| EntryData {
527 krate: *map.get(krate).unwrap(),
528 ty: *ty,
529 module_path: module_path.and_then(|path_id| map.get(&path_id).copied()),
530 exact_module_path: exact_module_path
531 .and_then(|path_id| map.get(&path_id).copied()),
532 parent: parent.and_then(|path_id| map.get(&path_id).copied()),
533 deprecated: *deprecated,
534 associated_item_disambiguator: associated_item_disambiguator.clone(),
535 },
536 ),
537 self.descs[id].clone(),
538 self.function_data[id].as_ref().map(
539 |FunctionData { function_signature, param_names }| FunctionData {
540 function_signature: {
541 let (mut func, _offset) =
542 IndexItemFunctionType::read_from_string_without_param_names(
543 function_signature.as_bytes(),
544 );
545 fn map_fn_sig_item(map: &FxHashMap<usize, usize>, ty: &mut RenderType) {
546 match ty.id {
547 None => {}
548 Some(RenderTypeId::Index(generic)) if generic < 0 => {}
549 Some(RenderTypeId::Index(id)) => {
550 let id = usize::try_from(id).unwrap();
551 let id = *map.get(&id).unwrap();
552 assert!(id != !0);
553 ty.id =
554 Some(RenderTypeId::Index(isize::try_from(id).unwrap()));
555 }
556 _ => unreachable!(),
557 }
558 if let Some(generics) = &mut ty.generics {
559 for generic in generics {
560 map_fn_sig_item(map, generic);
561 }
562 }
563 if let Some(bindings) = &mut ty.bindings {
564 for (param, constraints) in bindings {
565 *param = match *param {
566 param @ RenderTypeId::Index(generic) if generic < 0 => {
567 param
568 }
569 RenderTypeId::Index(id) => {
570 let id = usize::try_from(id).unwrap();
571 let id = *map.get(&id).unwrap();
572 assert!(id != !0);
573 RenderTypeId::Index(isize::try_from(id).unwrap())
574 }
575 _ => unreachable!(),
576 };
577 for constraint in constraints {
578 map_fn_sig_item(map, constraint);
579 }
580 }
581 }
582 }
583 for input in &mut func.inputs {
584 map_fn_sig_item(&map, input);
585 }
586 for output in &mut func.output {
587 map_fn_sig_item(&map, output);
588 }
589 for clause in &mut func.where_clause {
590 for entry in clause {
591 map_fn_sig_item(&map, entry);
592 }
593 }
594 let mut result = String::with_capacity(function_signature.len());
595 func.write_to_string_without_param_names(&mut result);
596 result
597 },
598 param_names: param_names.clone(),
599 },
600 ),
601 self.type_data[id].as_ref().map(
602 |TypeData { search_unbox, inverted_function_signature_index }| {
603 let inverted_function_signature_index: Vec<Vec<u32>> =
604 inverted_function_signature_index
605 .iter()
606 .cloned()
607 .map(|mut list| {
608 for id in &mut list {
609 *id = u32::try_from(
610 *map.get(&usize::try_from(*id).unwrap()).unwrap(),
611 )
612 .unwrap();
613 }
614 list.sort();
615 list
616 })
617 .collect();
618 TypeData { search_unbox: *search_unbox, inverted_function_signature_index }
619 },
620 ),
621 self.alias_pointers[id].and_then(|alias| map.get(&alias).copied()),
622 );
623 }
624 new.generic_inverted_index = self
625 .generic_inverted_index
626 .into_iter()
627 .map(|mut postings| {
628 for list in postings.iter_mut() {
629 let mut new_list: Vec<u32> = list
630 .iter()
631 .copied()
632 .filter_map(|id| u32::try_from(*map.get(&usize::try_from(id).ok()?)?).ok())
633 .collect();
634 new_list.sort();
635 *list = new_list;
636 }
637 postings
638 })
639 .collect();
640 new
641 }
642
643 pub(crate) fn write_to(self, doc_root: &Path, resource_suffix: &str) -> Result<(), Error> {
644 let SerializedSearchIndex {
645 names,
646 path_data,
647 entry_data,
648 descs,
649 function_data,
650 type_data,
651 alias_pointers,
652 generic_inverted_index,
653 crate_paths_index: _,
654 } = self;
655 let mut serialized_root = Vec::new();
656 serialized_root.extend_from_slice(br#"rr_('{"normalizedName":{"I":""#);
657 let normalized_names = names
658 .iter()
659 .map(|name| {
660 if name.contains("_") {
661 name.replace("_", "").to_ascii_lowercase()
662 } else {
663 name.to_ascii_lowercase()
664 }
665 })
666 .collect::<Vec<String>>();
667 let names_search_tree = stringdex_internals::tree::encode_search_tree_ukkonen(
668 normalized_names.iter().map(|name| name.as_bytes()),
669 );
670 let dir_path = doc_root.join(format!("search.index/"));
671 let _ = std::fs::remove_dir_all(&dir_path); stringdex_internals::write_tree_to_disk(
673 &names_search_tree,
674 &dir_path,
675 &mut serialized_root,
676 )
677 .map_err(|error| Error {
678 file: dir_path,
679 error: format!("failed to write name tree to disk: {error}"),
680 })?;
681 std::mem::drop(names_search_tree);
682 serialized_root.extend_from_slice(br#"","#);
683 serialized_root.extend_from_slice(&perform_write_strings(
684 doc_root,
685 "normalizedName",
686 normalized_names.into_iter(),
687 )?);
688 serialized_root.extend_from_slice(br#"},"crateNames":{"#);
689 let mut crates: Vec<&[u8]> = entry_data
690 .iter()
691 .filter_map(|entry_data| Some(names[entry_data.as_ref()?.krate].as_bytes()))
692 .collect();
693 crates.sort();
694 crates.dedup();
695 serialized_root.extend_from_slice(&perform_write_strings(
696 doc_root,
697 "crateNames",
698 crates.into_iter(),
699 )?);
700 serialized_root.extend_from_slice(br#"},"name":{"#);
701 serialized_root.extend_from_slice(&perform_write_strings(doc_root, "name", names.iter())?);
702 serialized_root.extend_from_slice(br#"},"path":{"#);
703 serialized_root.extend_from_slice(&perform_write_serde(doc_root, "path", path_data)?);
704 serialized_root.extend_from_slice(br#"},"entry":{"#);
705 serialized_root.extend_from_slice(&perform_write_serde(doc_root, "entry", entry_data)?);
706 serialized_root.extend_from_slice(br#"},"desc":{"#);
707 serialized_root.extend_from_slice(&perform_write_strings(
708 doc_root,
709 "desc",
710 descs.into_iter(),
711 )?);
712 serialized_root.extend_from_slice(br#"},"function":{"#);
713 serialized_root.extend_from_slice(&perform_write_serde(
714 doc_root,
715 "function",
716 function_data,
717 )?);
718 serialized_root.extend_from_slice(br#"},"type":{"#);
719 serialized_root.extend_from_slice(&perform_write_serde(doc_root, "type", type_data)?);
720 serialized_root.extend_from_slice(br#"},"alias":{"#);
721 serialized_root.extend_from_slice(&perform_write_serde(doc_root, "alias", alias_pointers)?);
722 serialized_root.extend_from_slice(br#"},"generic_inverted_index":{"#);
723 serialized_root.extend_from_slice(&perform_write_postings(
724 doc_root,
725 "generic_inverted_index",
726 generic_inverted_index,
727 )?);
728 serialized_root.extend_from_slice(br#"}}')"#);
729 fn perform_write_strings(
730 doc_root: &Path,
731 dirname: &str,
732 mut column: impl Iterator<Item = impl AsRef<[u8]> + Clone> + ExactSizeIterator,
733 ) -> Result<Vec<u8>, Error> {
734 let dir_path = doc_root.join(format!("search.index/{dirname}"));
735 stringdex_internals::write_data_to_disk(&mut column, &dir_path).map_err(|error| Error {
736 file: dir_path,
737 error: format!("failed to write column to disk: {error}"),
738 })
739 }
740 fn perform_write_serde(
741 doc_root: &Path,
742 dirname: &str,
743 column: Vec<Option<impl Serialize>>,
744 ) -> Result<Vec<u8>, Error> {
745 perform_write_strings(
746 doc_root,
747 dirname,
748 column.into_iter().map(|value| {
749 if let Some(value) = value {
750 serde_json::to_vec(&value).unwrap()
751 } else {
752 Vec::new()
753 }
754 }),
755 )
756 }
757 fn perform_write_postings(
758 doc_root: &Path,
759 dirname: &str,
760 column: Vec<Vec<Vec<u32>>>,
761 ) -> Result<Vec<u8>, Error> {
762 perform_write_strings(
763 doc_root,
764 dirname,
765 column.into_iter().map(|postings| {
766 let mut buf = Vec::new();
767 encode::write_postings_to_string(&postings, &mut buf);
768 buf
769 }),
770 )
771 }
772 std::fs::write(
773 doc_root.join(format!("search.index/root{resource_suffix}.js")),
774 serialized_root,
775 )
776 .map_err(|error| Error {
777 file: doc_root.join(format!("search.index/root{resource_suffix}.js")),
778 error: format!("failed to write root to disk: {error}"),
779 })?;
780 Ok(())
781 }
782}
783
784#[derive(Clone, Debug)]
785struct EntryData {
786 krate: usize,
787 ty: ItemType,
788 module_path: Option<usize>,
789 exact_module_path: Option<usize>,
790 parent: Option<usize>,
791 deprecated: bool,
792 associated_item_disambiguator: Option<String>,
793}
794
795impl Serialize for EntryData {
796 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
797 where
798 S: Serializer,
799 {
800 let mut seq = serializer.serialize_seq(None)?;
801 seq.serialize_element(&self.krate)?;
802 seq.serialize_element(&self.ty)?;
803 seq.serialize_element(&self.module_path.map(|id| id + 1).unwrap_or(0))?;
804 seq.serialize_element(&self.exact_module_path.map(|id| id + 1).unwrap_or(0))?;
805 seq.serialize_element(&self.parent.map(|id| id + 1).unwrap_or(0))?;
806 seq.serialize_element(&if self.deprecated { 1 } else { 0 })?;
807 if let Some(disambig) = &self.associated_item_disambiguator {
808 seq.serialize_element(&disambig)?;
809 }
810 seq.end()
811 }
812}
813
814impl<'de> Deserialize<'de> for EntryData {
815 fn deserialize<D>(deserializer: D) -> Result<EntryData, D::Error>
816 where
817 D: Deserializer<'de>,
818 {
819 struct EntryDataVisitor;
820 impl<'de> de::Visitor<'de> for EntryDataVisitor {
821 type Value = EntryData;
822 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
823 write!(formatter, "path data")
824 }
825 fn visit_seq<A: de::SeqAccess<'de>>(self, mut v: A) -> Result<EntryData, A::Error> {
826 let krate: usize =
827 v.next_element()?.ok_or_else(|| A::Error::missing_field("krate"))?;
828 let ty: ItemType =
829 v.next_element()?.ok_or_else(|| A::Error::missing_field("ty"))?;
830 let module_path: SerializedOptional32 =
831 v.next_element()?.ok_or_else(|| A::Error::missing_field("module_path"))?;
832 let exact_module_path: SerializedOptional32 = v
833 .next_element()?
834 .ok_or_else(|| A::Error::missing_field("exact_module_path"))?;
835 let parent: SerializedOptional32 =
836 v.next_element()?.ok_or_else(|| A::Error::missing_field("parent"))?;
837 let deprecated: u32 = v.next_element()?.unwrap_or(0);
838 let associated_item_disambiguator: Option<String> = v.next_element()?;
839 Ok(EntryData {
840 krate,
841 ty,
842 module_path: Option::<i32>::from(module_path).map(|path| path as usize),
843 exact_module_path: Option::<i32>::from(exact_module_path)
844 .map(|path| path as usize),
845 parent: Option::<i32>::from(parent).map(|path| path as usize),
846 deprecated: deprecated != 0,
847 associated_item_disambiguator,
848 })
849 }
850 }
851 deserializer.deserialize_any(EntryDataVisitor)
852 }
853}
854
855#[derive(Clone, Debug)]
856struct PathData {
857 ty: ItemType,
858 module_path: Vec<Symbol>,
859 exact_module_path: Option<Vec<Symbol>>,
860}
861
862impl Serialize for PathData {
863 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
864 where
865 S: Serializer,
866 {
867 let mut seq = serializer.serialize_seq(None)?;
868 seq.serialize_element(&self.ty)?;
869 seq.serialize_element(&if self.module_path.is_empty() {
870 String::new()
871 } else {
872 join_path_syms(&self.module_path)
873 })?;
874 if let Some(ref path) = self.exact_module_path {
875 seq.serialize_element(&if path.is_empty() {
876 String::new()
877 } else {
878 join_path_syms(path)
879 })?;
880 }
881 seq.end()
882 }
883}
884
885impl<'de> Deserialize<'de> for PathData {
886 fn deserialize<D>(deserializer: D) -> Result<PathData, D::Error>
887 where
888 D: Deserializer<'de>,
889 {
890 struct PathDataVisitor;
891 impl<'de> de::Visitor<'de> for PathDataVisitor {
892 type Value = PathData;
893 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
894 write!(formatter, "path data")
895 }
896 fn visit_seq<A: de::SeqAccess<'de>>(self, mut v: A) -> Result<PathData, A::Error> {
897 let ty: ItemType =
898 v.next_element()?.ok_or_else(|| A::Error::missing_field("ty"))?;
899 let module_path: String =
900 v.next_element()?.ok_or_else(|| A::Error::missing_field("module_path"))?;
901 let exact_module_path: Option<String> =
902 v.next_element()?.and_then(SerializedOptionalString::into);
903 Ok(PathData {
904 ty,
905 module_path: if module_path.is_empty() {
906 vec![]
907 } else {
908 module_path.split("::").map(Symbol::intern).collect()
909 },
910 exact_module_path: exact_module_path.map(|path| {
911 if path.is_empty() {
912 vec![]
913 } else {
914 path.split("::").map(Symbol::intern).collect()
915 }
916 }),
917 })
918 }
919 }
920 deserializer.deserialize_any(PathDataVisitor)
921 }
922}
923
924#[derive(Clone, Debug)]
925struct TypeData {
926 search_unbox: bool,
937 inverted_function_signature_index: Vec<Vec<u32>>,
949}
950
951impl Serialize for TypeData {
952 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
953 where
954 S: Serializer,
955 {
956 if self.search_unbox || !self.inverted_function_signature_index.is_empty() {
957 let mut seq = serializer.serialize_seq(None)?;
958 if !self.inverted_function_signature_index.is_empty() {
959 let mut buf = Vec::new();
960 encode::write_postings_to_string(&self.inverted_function_signature_index, &mut buf);
961 let mut serialized_result = Vec::new();
962 stringdex_internals::encode::write_base64_to_bytes(&buf, &mut serialized_result);
963 seq.serialize_element(&String::from_utf8(serialized_result).unwrap())?;
964 }
965 if self.search_unbox {
966 seq.serialize_element(&1)?;
967 }
968 seq.end()
969 } else {
970 None::<()>.serialize(serializer)
971 }
972 }
973}
974
975impl<'de> Deserialize<'de> for TypeData {
976 fn deserialize<D>(deserializer: D) -> Result<TypeData, D::Error>
977 where
978 D: Deserializer<'de>,
979 {
980 struct TypeDataVisitor;
981 impl<'de> de::Visitor<'de> for TypeDataVisitor {
982 type Value = TypeData;
983 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
984 write!(formatter, "type data")
985 }
986 fn visit_none<E>(self) -> Result<TypeData, E> {
987 Ok(TypeData { inverted_function_signature_index: vec![], search_unbox: false })
988 }
989 fn visit_seq<A: de::SeqAccess<'de>>(self, mut v: A) -> Result<TypeData, A::Error> {
990 let inverted_function_signature_index: String =
991 v.next_element()?.unwrap_or(String::new());
992 let search_unbox: u32 = v.next_element()?.unwrap_or(0);
993 let mut idx: Vec<u8> = Vec::new();
994 stringdex_internals::decode::read_base64_from_bytes(
995 inverted_function_signature_index.as_bytes(),
996 &mut idx,
997 )
998 .unwrap();
999 let mut inverted_function_signature_index = Vec::new();
1000 encode::read_postings_from_string(&mut inverted_function_signature_index, &idx);
1001 Ok(TypeData { inverted_function_signature_index, search_unbox: search_unbox == 1 })
1002 }
1003 }
1004 deserializer.deserialize_any(TypeDataVisitor)
1005 }
1006}
1007
1008enum SerializedOptionalString {
1009 None,
1010 Some(String),
1011}
1012
1013impl From<SerializedOptionalString> for Option<String> {
1014 fn from(me: SerializedOptionalString) -> Option<String> {
1015 match me {
1016 SerializedOptionalString::Some(string) => Some(string),
1017 SerializedOptionalString::None => None,
1018 }
1019 }
1020}
1021
1022impl Serialize for SerializedOptionalString {
1023 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1024 where
1025 S: Serializer,
1026 {
1027 match self {
1028 SerializedOptionalString::Some(string) => string.serialize(serializer),
1029 SerializedOptionalString::None => 0.serialize(serializer),
1030 }
1031 }
1032}
1033impl<'de> Deserialize<'de> for SerializedOptionalString {
1034 fn deserialize<D>(deserializer: D) -> Result<SerializedOptionalString, D::Error>
1035 where
1036 D: Deserializer<'de>,
1037 {
1038 struct SerializedOptionalStringVisitor;
1039 impl<'de> de::Visitor<'de> for SerializedOptionalStringVisitor {
1040 type Value = SerializedOptionalString;
1041 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1042 write!(formatter, "0 or string")
1043 }
1044 fn visit_u64<E: de::Error>(self, v: u64) -> Result<SerializedOptionalString, E> {
1045 if v != 0 {
1046 return Err(E::missing_field("not 0"));
1047 }
1048 Ok(SerializedOptionalString::None)
1049 }
1050 fn visit_string<E: de::Error>(self, v: String) -> Result<SerializedOptionalString, E> {
1051 Ok(SerializedOptionalString::Some(v))
1052 }
1053 fn visit_str<E: de::Error>(self, v: &str) -> Result<SerializedOptionalString, E> {
1054 Ok(SerializedOptionalString::Some(v.to_string()))
1055 }
1056 }
1057 deserializer.deserialize_any(SerializedOptionalStringVisitor)
1058 }
1059}
1060
1061enum SerializedOptional32 {
1062 None,
1063 Some(i32),
1064}
1065
1066impl From<SerializedOptional32> for Option<i32> {
1067 fn from(me: SerializedOptional32) -> Option<i32> {
1068 match me {
1069 SerializedOptional32::Some(number) => Some(number),
1070 SerializedOptional32::None => None,
1071 }
1072 }
1073}
1074
1075impl Serialize for SerializedOptional32 {
1076 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1077 where
1078 S: Serializer,
1079 {
1080 match self {
1081 &SerializedOptional32::Some(number) if number < 0 => number.serialize(serializer),
1082 &SerializedOptional32::Some(number) => (number + 1).serialize(serializer),
1083 &SerializedOptional32::None => 0.serialize(serializer),
1084 }
1085 }
1086}
1087impl<'de> Deserialize<'de> for SerializedOptional32 {
1088 fn deserialize<D>(deserializer: D) -> Result<SerializedOptional32, D::Error>
1089 where
1090 D: Deserializer<'de>,
1091 {
1092 struct SerializedOptional32Visitor;
1093 impl<'de> de::Visitor<'de> for SerializedOptional32Visitor {
1094 type Value = SerializedOptional32;
1095 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1096 write!(formatter, "integer")
1097 }
1098 fn visit_i64<E: de::Error>(self, v: i64) -> Result<SerializedOptional32, E> {
1099 Ok(match v {
1100 0 => SerializedOptional32::None,
1101 v if v < 0 => SerializedOptional32::Some(v as i32),
1102 v => SerializedOptional32::Some(v as i32 - 1),
1103 })
1104 }
1105 fn visit_u64<E: de::Error>(self, v: u64) -> Result<SerializedOptional32, E> {
1106 Ok(match v {
1107 0 => SerializedOptional32::None,
1108 v => SerializedOptional32::Some(v as i32 - 1),
1109 })
1110 }
1111 }
1112 deserializer.deserialize_any(SerializedOptional32Visitor)
1113 }
1114}
1115
1116#[derive(Clone, Debug)]
1117pub struct FunctionData {
1118 function_signature: String,
1119 param_names: Vec<String>,
1120}
1121
1122impl Serialize for FunctionData {
1123 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1124 where
1125 S: Serializer,
1126 {
1127 let mut seq = serializer.serialize_seq(None)?;
1128 seq.serialize_element(&self.function_signature)?;
1129 seq.serialize_element(&self.param_names)?;
1130 seq.end()
1131 }
1132}
1133
1134impl<'de> Deserialize<'de> for FunctionData {
1135 fn deserialize<D>(deserializer: D) -> Result<FunctionData, D::Error>
1136 where
1137 D: Deserializer<'de>,
1138 {
1139 struct FunctionDataVisitor;
1140 impl<'de> de::Visitor<'de> for FunctionDataVisitor {
1141 type Value = FunctionData;
1142 fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1143 write!(formatter, "fn data")
1144 }
1145 fn visit_seq<A: de::SeqAccess<'de>>(self, mut v: A) -> Result<FunctionData, A::Error> {
1146 let function_signature: String = v
1147 .next_element()?
1148 .ok_or_else(|| A::Error::missing_field("function_signature"))?;
1149 let param_names: Vec<String> =
1150 v.next_element()?.ok_or_else(|| A::Error::missing_field("param_names"))?;
1151 Ok(FunctionData { function_signature, param_names })
1152 }
1153 }
1154 deserializer.deserialize_any(FunctionDataVisitor)
1155 }
1156}
1157
1158pub(crate) fn build_index(
1160 krate: &clean::Crate,
1161 cache: &mut Cache,
1162 tcx: TyCtxt<'_>,
1163 doc_root: &Path,
1164 resource_suffix: &str,
1165) -> Result<SerializedSearchIndex, Error> {
1166 let mut search_index = std::mem::take(&mut cache.search_index);
1167
1168 for &OrphanImplItem { impl_id, parent, ref item, ref impl_generics } in &cache.orphan_impl_items
1171 {
1172 if let Some((fqp, _)) = cache.paths.get(&parent) {
1173 let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
1174 search_index.push(IndexItem {
1175 ty: item.type_(),
1176 defid: item.item_id.as_def_id(),
1177 name: item.name.unwrap(),
1178 module_path: fqp[..fqp.len() - 1].to_vec(),
1179 desc,
1180 parent: Some(parent),
1181 parent_idx: None,
1182 exact_module_path: None,
1183 impl_id,
1184 search_type: get_function_type_for_search(
1185 item,
1186 tcx,
1187 impl_generics.as_ref(),
1188 Some(parent),
1189 cache,
1190 ),
1191 aliases: item.attrs.get_doc_aliases(),
1192 deprecation: item.deprecation(tcx),
1193 });
1194 }
1195 }
1196
1197 search_index.sort_unstable_by(|k1, k2| {
1199 let k1 =
1202 (&k1.module_path, k1.name.as_str(), &k1.ty, k1.parent.map(|id| (id.index, id.krate)));
1203 let k2 =
1204 (&k2.module_path, k2.name.as_str(), &k2.ty, k2.parent.map(|id| (id.index, id.krate)));
1205 Ord::cmp(&k1, &k2)
1206 });
1207
1208 let mut serialized_index = SerializedSearchIndex::load(doc_root, resource_suffix)?;
1213
1214 let crate_name = krate.name(tcx);
1216 let crate_doc =
1217 short_markdown_summary(&krate.module.doc_value(), &krate.module.link_names(cache));
1218 let crate_idx = {
1219 let crate_path = (ItemType::ExternCrate, vec![crate_name]);
1220 match serialized_index.crate_paths_index.entry(crate_path) {
1221 Entry::Occupied(index) => {
1222 let index = *index.get();
1223 serialized_index.descs[index] = crate_doc;
1224 for type_data in serialized_index.type_data.iter_mut() {
1225 if let Some(TypeData { inverted_function_signature_index, .. }) = type_data {
1226 for list in &mut inverted_function_signature_index[..] {
1227 list.retain(|fnid| {
1228 serialized_index.entry_data[usize::try_from(*fnid).unwrap()]
1229 .as_ref()
1230 .unwrap()
1231 .krate
1232 != index
1233 });
1234 }
1235 }
1236 }
1237 for i in (index + 1)..serialized_index.entry_data.len() {
1238 if let Some(EntryData { krate, .. }) = serialized_index.entry_data[i]
1240 && krate == index
1241 {
1242 serialized_index.entry_data[i] = None;
1243 serialized_index.descs[i] = String::new();
1244 serialized_index.function_data[i] = None;
1245 if serialized_index.path_data[i].is_none() {
1246 serialized_index.names[i] = String::new();
1247 }
1248 }
1249 if let Some(alias_pointer) = serialized_index.alias_pointers[i]
1250 && serialized_index.entry_data[alias_pointer].is_none()
1251 {
1252 serialized_index.alias_pointers[i] = None;
1253 if serialized_index.path_data[i].is_none()
1254 && serialized_index.entry_data[i].is_none()
1255 {
1256 serialized_index.names[i] = String::new();
1257 }
1258 }
1259 }
1260 index
1261 }
1262 Entry::Vacant(slot) => {
1263 let krate = serialized_index.names.len();
1264 slot.insert(krate);
1265 serialized_index.push(
1266 crate_name.as_str().to_string(),
1267 Some(PathData {
1268 ty: ItemType::ExternCrate,
1269 module_path: vec![],
1270 exact_module_path: None,
1271 }),
1272 Some(EntryData {
1273 krate,
1274 ty: ItemType::ExternCrate,
1275 module_path: None,
1276 exact_module_path: None,
1277 parent: None,
1278 deprecated: false,
1279 associated_item_disambiguator: None,
1280 }),
1281 crate_doc,
1282 None,
1283 None,
1284 None,
1285 );
1286 krate
1287 }
1288 }
1289 };
1290
1291 let crate_items: Vec<&mut IndexItem> = search_index
1293 .iter_mut()
1294 .map(|item| {
1295 item.parent_idx = item.parent.and_then(|defid| {
1296 cache.paths.get(&defid).map(|&(ref fqp, ty)| {
1297 let pathid = serialized_index.names.len();
1298 match serialized_index.crate_paths_index.entry((ty, fqp.clone())) {
1299 Entry::Occupied(entry) => *entry.get(),
1300 Entry::Vacant(entry) => {
1301 entry.insert(pathid);
1302 let (name, path) = fqp.split_last().unwrap();
1303 serialized_index.push_path(
1304 name.as_str().to_string(),
1305 PathData {
1306 ty,
1307 module_path: path.to_vec(),
1308 exact_module_path: if let Some(exact_path) =
1309 cache.exact_paths.get(&defid)
1310 && let Some((name2, exact_path)) = exact_path.split_last()
1311 && name == name2
1312 {
1313 Some(exact_path.to_vec())
1314 } else {
1315 None
1316 },
1317 },
1318 );
1319 usize::try_from(pathid).unwrap()
1320 }
1321 }
1322 })
1323 });
1324
1325 if let Some(defid) = item.defid
1326 && item.parent_idx.is_none()
1327 {
1328 let exact_fqp = cache
1332 .exact_paths
1333 .get(&defid)
1334 .or_else(|| cache.external_paths.get(&defid).map(|(fqp, _)| fqp));
1335 item.exact_module_path = exact_fqp.and_then(|fqp| {
1336 if fqp.last() != Some(&item.name) {
1343 return None;
1344 }
1345 let path =
1346 if item.ty == ItemType::Macro && tcx.has_attr(defid, sym::macro_export) {
1347 vec![tcx.crate_name(defid.krate)]
1349 } else {
1350 if fqp.len() < 2 {
1351 return None;
1352 }
1353 fqp[..fqp.len() - 1].to_vec()
1354 };
1355 if path == item.module_path {
1356 return None;
1357 }
1358 Some(path)
1359 });
1360 } else if let Some(parent_idx) = item.parent_idx {
1361 let i = usize::try_from(parent_idx).unwrap();
1362 item.module_path =
1363 serialized_index.path_data[i].as_ref().unwrap().module_path.clone();
1364 item.exact_module_path =
1365 serialized_index.path_data[i].as_ref().unwrap().exact_module_path.clone();
1366 }
1367
1368 &mut *item
1369 })
1370 .collect();
1371
1372 let mut associated_item_duplicates = FxHashMap::<(usize, ItemType, Symbol), usize>::default();
1375 for item in crate_items.iter().map(|x| &*x) {
1376 if item.impl_id.is_some()
1377 && let Some(parent_idx) = item.parent_idx
1378 {
1379 let count =
1380 associated_item_duplicates.entry((parent_idx, item.ty, item.name)).or_insert(0);
1381 *count += 1;
1382 }
1383 }
1384
1385 for item in crate_items {
1387 assert_eq!(
1388 item.parent.is_some(),
1389 item.parent_idx.is_some(),
1390 "`{}` is missing idx",
1391 item.name
1392 );
1393
1394 let module_path = Some(serialized_index.get_id_by_module_path(&item.module_path));
1395 let exact_module_path = item
1396 .exact_module_path
1397 .as_ref()
1398 .map(|path| serialized_index.get_id_by_module_path(path));
1399
1400 let new_entry_id = serialized_index.push(
1401 item.name.as_str().to_string(),
1402 None,
1403 Some(EntryData {
1404 ty: item.ty,
1405 parent: item.parent_idx,
1406 module_path,
1407 exact_module_path,
1408 deprecated: item.deprecation.is_some(),
1409 associated_item_disambiguator: if let Some(impl_id) = item.impl_id
1410 && let Some(parent_idx) = item.parent_idx
1411 && associated_item_duplicates
1412 .get(&(parent_idx, item.ty, item.name))
1413 .copied()
1414 .unwrap_or(0)
1415 > 1
1416 {
1417 Some(render::get_id_for_impl(tcx, ItemId::DefId(impl_id)))
1418 } else {
1419 None
1420 },
1421 krate: crate_idx,
1422 }),
1423 item.desc.to_string(),
1424 None, None,
1426 None,
1427 );
1428
1429 for alias in &item.aliases[..] {
1432 serialized_index.push_alias(alias.as_str().to_string(), new_entry_id);
1433 }
1434
1435 fn insert_into_map(
1438 ty: ItemType,
1439 path: &[Symbol],
1440 exact_path: Option<&[Symbol]>,
1441 search_unbox: bool,
1442 serialized_index: &mut SerializedSearchIndex,
1443 used_in_function_signature: &mut BTreeSet<isize>,
1444 ) -> RenderTypeId {
1445 let pathid = serialized_index.names.len();
1446 let pathid = match serialized_index.crate_paths_index.entry((ty, path.to_vec())) {
1447 Entry::Occupied(entry) => {
1448 let id = *entry.get();
1449 if serialized_index.type_data[id].as_mut().is_none() {
1450 serialized_index.type_data[id] = Some(TypeData {
1451 search_unbox,
1452 inverted_function_signature_index: Vec::new(),
1453 });
1454 } else if search_unbox {
1455 serialized_index.type_data[id].as_mut().unwrap().search_unbox = true;
1456 }
1457 id
1458 }
1459 Entry::Vacant(entry) => {
1460 entry.insert(pathid);
1461 let (name, path) = path.split_last().unwrap();
1462 serialized_index.push_type(
1463 name.to_string(),
1464 PathData {
1465 ty,
1466 module_path: path.to_vec(),
1467 exact_module_path: if let Some(exact_path) = exact_path
1468 && let Some((name2, exact_path)) = exact_path.split_last()
1469 && name == name2
1470 {
1471 Some(exact_path.to_vec())
1472 } else {
1473 None
1474 },
1475 },
1476 TypeData { search_unbox, inverted_function_signature_index: Vec::new() },
1477 );
1478 pathid
1479 }
1480 };
1481 used_in_function_signature.insert(isize::try_from(pathid).unwrap());
1482 RenderTypeId::Index(isize::try_from(pathid).unwrap())
1483 }
1484
1485 fn convert_render_type_id(
1486 id: RenderTypeId,
1487 cache: &mut Cache,
1488 serialized_index: &mut SerializedSearchIndex,
1489 used_in_function_signature: &mut BTreeSet<isize>,
1490 tcx: TyCtxt<'_>,
1491 ) -> Option<RenderTypeId> {
1492 use crate::clean::PrimitiveType;
1493 let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache;
1494 let search_unbox = match id {
1495 RenderTypeId::Mut => false,
1496 RenderTypeId::DefId(defid) => utils::has_doc_flag(tcx, defid, sym::search_unbox),
1497 RenderTypeId::Primitive(
1498 PrimitiveType::Reference | PrimitiveType::RawPointer | PrimitiveType::Tuple,
1499 ) => true,
1500 RenderTypeId::Primitive(..) => false,
1501 RenderTypeId::AssociatedType(..) => false,
1502 RenderTypeId::Index(_) => false,
1505 };
1506 match id {
1507 RenderTypeId::Mut => Some(insert_into_map(
1508 ItemType::Keyword,
1509 &[kw::Mut],
1510 None,
1511 search_unbox,
1512 serialized_index,
1513 used_in_function_signature,
1514 )),
1515 RenderTypeId::DefId(defid) => {
1516 if let Some(&(ref fqp, item_type)) =
1517 paths.get(&defid).or_else(|| external_paths.get(&defid))
1518 {
1519 if tcx.lang_items().fn_mut_trait() == Some(defid)
1520 || tcx.lang_items().fn_once_trait() == Some(defid)
1521 || tcx.lang_items().fn_trait() == Some(defid)
1522 {
1523 let name = *fqp.last().unwrap();
1524 Some(insert_into_map(
1529 item_type,
1530 &[sym::core, sym::ops, name],
1531 Some(&[sym::core, sym::ops, name]),
1532 search_unbox,
1533 serialized_index,
1534 used_in_function_signature,
1535 ))
1536 } else {
1537 let exact_fqp = exact_paths
1538 .get(&defid)
1539 .or_else(|| external_paths.get(&defid).map(|(fqp, _)| fqp))
1540 .map(|v| &v[..])
1541 .filter(|this_fqp| this_fqp.last() == fqp.last());
1548 Some(insert_into_map(
1549 item_type,
1550 fqp,
1551 exact_fqp,
1552 search_unbox,
1553 serialized_index,
1554 used_in_function_signature,
1555 ))
1556 }
1557 } else {
1558 None
1559 }
1560 }
1561 RenderTypeId::Primitive(primitive) => {
1562 let sym = primitive.as_sym();
1563 Some(insert_into_map(
1564 ItemType::Primitive,
1565 &[sym],
1566 None,
1567 search_unbox,
1568 serialized_index,
1569 used_in_function_signature,
1570 ))
1571 }
1572 RenderTypeId::Index(index) => {
1573 used_in_function_signature.insert(index);
1574 Some(id)
1575 }
1576 RenderTypeId::AssociatedType(sym) => Some(insert_into_map(
1577 ItemType::AssocType,
1578 &[sym],
1579 None,
1580 search_unbox,
1581 serialized_index,
1582 used_in_function_signature,
1583 )),
1584 }
1585 }
1586
1587 fn convert_render_type(
1588 ty: &mut RenderType,
1589 cache: &mut Cache,
1590 serialized_index: &mut SerializedSearchIndex,
1591 used_in_function_signature: &mut BTreeSet<isize>,
1592 tcx: TyCtxt<'_>,
1593 ) {
1594 if let Some(generics) = &mut ty.generics {
1595 for item in generics {
1596 convert_render_type(
1597 item,
1598 cache,
1599 serialized_index,
1600 used_in_function_signature,
1601 tcx,
1602 );
1603 }
1604 }
1605 if let Some(bindings) = &mut ty.bindings {
1606 bindings.retain_mut(|(associated_type, constraints)| {
1607 let converted_associated_type = convert_render_type_id(
1608 *associated_type,
1609 cache,
1610 serialized_index,
1611 used_in_function_signature,
1612 tcx,
1613 );
1614 let Some(converted_associated_type) = converted_associated_type else {
1615 return false;
1616 };
1617 *associated_type = converted_associated_type;
1618 for constraint in constraints {
1619 convert_render_type(
1620 constraint,
1621 cache,
1622 serialized_index,
1623 used_in_function_signature,
1624 tcx,
1625 );
1626 }
1627 true
1628 });
1629 }
1630 let Some(id) = ty.id else {
1631 assert!(ty.generics.is_some());
1632 return;
1633 };
1634 ty.id = convert_render_type_id(
1635 id,
1636 cache,
1637 serialized_index,
1638 used_in_function_signature,
1639 tcx,
1640 );
1641 use crate::clean::PrimitiveType;
1642 match id {
1646 RenderTypeId::Primitive(PrimitiveType::Array | PrimitiveType::Slice) => {
1648 insert_into_map(
1649 ItemType::Primitive,
1650 &[Symbol::intern("[]")],
1651 None,
1652 false,
1653 serialized_index,
1654 used_in_function_signature,
1655 );
1656 }
1657 RenderTypeId::Primitive(PrimitiveType::Tuple | PrimitiveType::Unit) => {
1658 insert_into_map(
1660 ItemType::Primitive,
1661 &[Symbol::intern("()")],
1662 None,
1663 false,
1664 serialized_index,
1665 used_in_function_signature,
1666 );
1667 }
1668 RenderTypeId::Primitive(PrimitiveType::Fn) => {
1670 insert_into_map(
1671 ItemType::Primitive,
1672 &[Symbol::intern("->")],
1673 None,
1674 false,
1675 serialized_index,
1676 used_in_function_signature,
1677 );
1678 }
1679 RenderTypeId::DefId(did)
1680 if tcx.lang_items().fn_mut_trait() == Some(did)
1681 || tcx.lang_items().fn_once_trait() == Some(did)
1682 || tcx.lang_items().fn_trait() == Some(did) =>
1683 {
1684 insert_into_map(
1685 ItemType::Primitive,
1686 &[Symbol::intern("->")],
1687 None,
1688 false,
1689 serialized_index,
1690 used_in_function_signature,
1691 );
1692 }
1693 _ => {}
1695 }
1696 }
1697 if let Some(search_type) = &mut item.search_type {
1698 let mut used_in_function_signature = BTreeSet::new();
1699 for item in &mut search_type.inputs {
1700 convert_render_type(
1701 item,
1702 cache,
1703 &mut serialized_index,
1704 &mut used_in_function_signature,
1705 tcx,
1706 );
1707 }
1708 for item in &mut search_type.output {
1709 convert_render_type(
1710 item,
1711 cache,
1712 &mut serialized_index,
1713 &mut used_in_function_signature,
1714 tcx,
1715 );
1716 }
1717 for constraint in &mut search_type.where_clause {
1718 for trait_ in &mut constraint[..] {
1719 convert_render_type(
1720 trait_,
1721 cache,
1722 &mut serialized_index,
1723 &mut used_in_function_signature,
1724 tcx,
1725 );
1726 }
1727 }
1728 let search_type_size = search_type.size() +
1729 if item.ty.is_fn_like() { 0 } else { 16 };
1737 serialized_index.function_data[new_entry_id] = Some(FunctionData {
1738 function_signature: {
1739 let mut function_signature = String::new();
1740 search_type.write_to_string_without_param_names(&mut function_signature);
1741 function_signature
1742 },
1743 param_names: search_type
1744 .param_names
1745 .iter()
1746 .map(|sym| sym.map(|sym| sym.to_string()).unwrap_or(String::new()))
1747 .collect::<Vec<String>>(),
1748 });
1749 for index in used_in_function_signature {
1750 let postings = if index >= 0 {
1751 assert!(serialized_index.path_data[index as usize].is_some());
1752 &mut serialized_index.type_data[index as usize]
1753 .as_mut()
1754 .unwrap()
1755 .inverted_function_signature_index
1756 } else {
1757 let generic_id = usize::try_from(-index).unwrap() - 1;
1758 for _ in serialized_index.generic_inverted_index.len()..=generic_id {
1759 serialized_index.generic_inverted_index.push(Vec::new());
1760 }
1761 &mut serialized_index.generic_inverted_index[generic_id]
1762 };
1763 while postings.len() <= search_type_size {
1764 postings.push(Vec::new());
1765 }
1766 postings[search_type_size].push(new_entry_id as u32);
1767 }
1768 }
1769 }
1770
1771 Ok(serialized_index.sort())
1772}
1773
1774pub(crate) fn get_function_type_for_search(
1775 item: &clean::Item,
1776 tcx: TyCtxt<'_>,
1777 impl_generics: Option<&(clean::Type, clean::Generics)>,
1778 parent: Option<DefId>,
1779 cache: &Cache,
1780) -> Option<IndexItemFunctionType> {
1781 let mut trait_info = None;
1782 let impl_or_trait_generics = impl_generics.or_else(|| {
1783 if let Some(def_id) = parent
1784 && let Some(trait_) = cache.traits.get(&def_id)
1785 && let Some((path, _)) =
1786 cache.paths.get(&def_id).or_else(|| cache.external_paths.get(&def_id))
1787 {
1788 let path = clean::Path {
1789 res: rustc_hir::def::Res::Def(rustc_hir::def::DefKind::Trait, def_id),
1790 segments: path
1791 .iter()
1792 .map(|name| clean::PathSegment {
1793 name: *name,
1794 args: clean::GenericArgs::AngleBracketed {
1795 args: ThinVec::new(),
1796 constraints: ThinVec::new(),
1797 },
1798 })
1799 .collect(),
1800 };
1801 trait_info = Some((clean::Type::Path { path }, trait_.generics.clone()));
1802 Some(trait_info.as_ref().unwrap())
1803 } else {
1804 None
1805 }
1806 });
1807 let (mut inputs, mut output, param_names, where_clause) = match item.kind {
1808 clean::ForeignFunctionItem(ref f, _)
1809 | clean::FunctionItem(ref f)
1810 | clean::MethodItem(ref f, _)
1811 | clean::RequiredMethodItem(ref f) => {
1812 get_fn_inputs_and_outputs(f, tcx, impl_or_trait_generics, cache)
1813 }
1814 clean::ConstantItem(ref c) => make_nullary_fn(&c.type_),
1815 clean::StaticItem(ref s) => make_nullary_fn(&s.type_),
1816 clean::StructFieldItem(ref t) if let Some(parent) = parent => {
1817 let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> =
1818 Default::default();
1819 let output = get_index_type(t, vec![], &mut rgen);
1820 let input = RenderType {
1821 id: Some(RenderTypeId::DefId(parent)),
1822 generics: None,
1823 bindings: None,
1824 };
1825 (vec![input], vec![output], vec![], vec![])
1826 }
1827 _ => return None,
1828 };
1829
1830 inputs.retain(|a| a.id.is_some() || a.generics.is_some());
1831 output.retain(|a| a.id.is_some() || a.generics.is_some());
1832
1833 Some(IndexItemFunctionType { inputs, output, where_clause, param_names })
1834}
1835
1836fn get_index_type(
1837 clean_type: &clean::Type,
1838 generics: Vec<RenderType>,
1839 rgen: &mut FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)>,
1840) -> RenderType {
1841 RenderType {
1842 id: get_index_type_id(clean_type, rgen),
1843 generics: if generics.is_empty() { None } else { Some(generics) },
1844 bindings: None,
1845 }
1846}
1847
1848fn get_index_type_id(
1849 clean_type: &clean::Type,
1850 rgen: &mut FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)>,
1851) -> Option<RenderTypeId> {
1852 use rustc_hir::def::{DefKind, Res};
1853 match *clean_type {
1854 clean::Type::Path { ref path, .. } => Some(RenderTypeId::DefId(path.def_id())),
1855 clean::DynTrait(ref bounds, _) => {
1856 bounds.first().map(|b| RenderTypeId::DefId(b.trait_.def_id()))
1857 }
1858 clean::Primitive(p) => Some(RenderTypeId::Primitive(p)),
1859 clean::BorrowedRef { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::Reference)),
1860 clean::RawPointer { .. } => Some(RenderTypeId::Primitive(clean::PrimitiveType::RawPointer)),
1861 clean::Slice(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Slice)),
1863 clean::Array(_, _) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Array)),
1864 clean::BareFunction(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Fn)),
1865 clean::Tuple(ref n) if n.is_empty() => {
1866 Some(RenderTypeId::Primitive(clean::PrimitiveType::Unit))
1867 }
1868 clean::Tuple(_) => Some(RenderTypeId::Primitive(clean::PrimitiveType::Tuple)),
1869 clean::QPath(ref data) => {
1870 if data.self_type.is_self_type()
1871 && let Some(clean::Path { res: Res::Def(DefKind::Trait, trait_), .. }) = data.trait_
1872 {
1873 let idx = -isize::try_from(rgen.len() + 1).unwrap();
1874 let (idx, _) = rgen
1875 .entry(SimplifiedParam::AssociatedType(trait_, data.assoc.name))
1876 .or_insert_with(|| (idx, Vec::new()));
1877 Some(RenderTypeId::Index(*idx))
1878 } else {
1879 None
1880 }
1881 }
1882 clean::Type::Pat(..)
1884 | clean::Generic(_)
1885 | clean::SelfTy
1886 | clean::ImplTrait(_)
1887 | clean::Infer
1888 | clean::UnsafeBinder(_) => None,
1889 }
1890}
1891
1892#[derive(Clone, Copy, Eq, Hash, PartialEq)]
1893enum SimplifiedParam {
1894 Symbol(Symbol),
1896 Anonymous(isize),
1898 AssociatedType(DefId, Symbol),
1901}
1902
1903#[instrument(level = "trace", skip(tcx, res, rgen, cache))]
1913fn simplify_fn_type<'a, 'tcx>(
1914 self_: Option<&'a Type>,
1915 generics: &Generics,
1916 arg: &'a Type,
1917 tcx: TyCtxt<'tcx>,
1918 recurse: usize,
1919 res: &mut Vec<RenderType>,
1920 rgen: &mut FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)>,
1921 is_return: bool,
1922 cache: &Cache,
1923) {
1924 if recurse >= 10 {
1925 return;
1928 }
1929
1930 let (is_self, arg) = if let Some(self_) = self_
1932 && arg.is_self_type()
1933 {
1934 (true, self_)
1935 } else {
1936 (false, arg)
1937 };
1938
1939 match *arg {
1942 Type::Generic(arg_s) => {
1943 let mut type_bounds = Vec::new();
1945 for where_pred in generics.where_predicates.iter().filter(|g| match g {
1946 WherePredicate::BoundPredicate { ty, .. } => *ty == *arg,
1947 _ => false,
1948 }) {
1949 let bounds = where_pred.get_bounds().unwrap_or(&[]);
1950 for bound in bounds.iter() {
1951 if let Some(path) = bound.get_trait_path() {
1952 let ty = Type::Path { path };
1953 simplify_fn_type(
1954 self_,
1955 generics,
1956 &ty,
1957 tcx,
1958 recurse + 1,
1959 &mut type_bounds,
1960 rgen,
1961 is_return,
1962 cache,
1963 );
1964 }
1965 }
1966 }
1967 if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
1969 for bound in bound.get_bounds().unwrap_or(&[]) {
1970 if let Some(path) = bound.get_trait_path() {
1971 let ty = Type::Path { path };
1972 simplify_fn_type(
1973 self_,
1974 generics,
1975 &ty,
1976 tcx,
1977 recurse + 1,
1978 &mut type_bounds,
1979 rgen,
1980 is_return,
1981 cache,
1982 );
1983 }
1984 }
1985 }
1986 if let Some((idx, _)) = rgen.get(&SimplifiedParam::Symbol(arg_s)) {
1987 res.push(RenderType {
1988 id: Some(RenderTypeId::Index(*idx)),
1989 generics: None,
1990 bindings: None,
1991 });
1992 } else {
1993 let idx = -isize::try_from(rgen.len() + 1).unwrap();
1994 rgen.insert(SimplifiedParam::Symbol(arg_s), (idx, type_bounds));
1995 res.push(RenderType {
1996 id: Some(RenderTypeId::Index(idx)),
1997 generics: None,
1998 bindings: None,
1999 });
2000 }
2001 }
2002 Type::ImplTrait(ref bounds) => {
2003 let mut type_bounds = Vec::new();
2004 for bound in bounds {
2005 if let Some(path) = bound.get_trait_path() {
2006 let ty = Type::Path { path };
2007 simplify_fn_type(
2008 self_,
2009 generics,
2010 &ty,
2011 tcx,
2012 recurse + 1,
2013 &mut type_bounds,
2014 rgen,
2015 is_return,
2016 cache,
2017 );
2018 }
2019 }
2020 if is_return && !type_bounds.is_empty() {
2021 res.push(RenderType { id: None, generics: Some(type_bounds), bindings: None });
2023 } else {
2024 let idx = -isize::try_from(rgen.len() + 1).unwrap();
2026 rgen.insert(SimplifiedParam::Anonymous(idx), (idx, type_bounds));
2027 res.push(RenderType {
2028 id: Some(RenderTypeId::Index(idx)),
2029 generics: None,
2030 bindings: None,
2031 });
2032 }
2033 }
2034 Type::Slice(ref ty) => {
2035 let mut ty_generics = Vec::new();
2036 simplify_fn_type(
2037 self_,
2038 generics,
2039 ty,
2040 tcx,
2041 recurse + 1,
2042 &mut ty_generics,
2043 rgen,
2044 is_return,
2045 cache,
2046 );
2047 res.push(get_index_type(arg, ty_generics, rgen));
2048 }
2049 Type::Array(ref ty, _) => {
2050 let mut ty_generics = Vec::new();
2051 simplify_fn_type(
2052 self_,
2053 generics,
2054 ty,
2055 tcx,
2056 recurse + 1,
2057 &mut ty_generics,
2058 rgen,
2059 is_return,
2060 cache,
2061 );
2062 res.push(get_index_type(arg, ty_generics, rgen));
2063 }
2064 Type::Tuple(ref tys) => {
2065 let mut ty_generics = Vec::new();
2066 for ty in tys {
2067 simplify_fn_type(
2068 self_,
2069 generics,
2070 ty,
2071 tcx,
2072 recurse + 1,
2073 &mut ty_generics,
2074 rgen,
2075 is_return,
2076 cache,
2077 );
2078 }
2079 res.push(get_index_type(arg, ty_generics, rgen));
2080 }
2081 Type::BareFunction(ref bf) => {
2082 let mut ty_generics = Vec::new();
2083 for ty in bf.decl.inputs.iter().map(|arg| &arg.type_) {
2084 simplify_fn_type(
2085 self_,
2086 generics,
2087 ty,
2088 tcx,
2089 recurse + 1,
2090 &mut ty_generics,
2091 rgen,
2092 is_return,
2093 cache,
2094 );
2095 }
2096 let mut ty_output = Vec::new();
2100 simplify_fn_type(
2101 self_,
2102 generics,
2103 &bf.decl.output,
2104 tcx,
2105 recurse + 1,
2106 &mut ty_output,
2107 rgen,
2108 is_return,
2109 cache,
2110 );
2111 let ty_bindings = vec![(RenderTypeId::AssociatedType(sym::Output), ty_output)];
2112 res.push(RenderType {
2113 id: get_index_type_id(arg, rgen),
2114 bindings: Some(ty_bindings),
2115 generics: Some(ty_generics),
2116 });
2117 }
2118 Type::BorrowedRef { lifetime: _, mutability, ref type_ }
2119 | Type::RawPointer(mutability, ref type_) => {
2120 let mut ty_generics = Vec::new();
2121 if mutability.is_mut() {
2122 ty_generics.push(RenderType {
2123 id: Some(RenderTypeId::Mut),
2124 generics: None,
2125 bindings: None,
2126 });
2127 }
2128 simplify_fn_type(
2129 self_,
2130 generics,
2131 type_,
2132 tcx,
2133 recurse + 1,
2134 &mut ty_generics,
2135 rgen,
2136 is_return,
2137 cache,
2138 );
2139 res.push(get_index_type(arg, ty_generics, rgen));
2140 }
2141 _ => {
2142 let mut ty_generics = Vec::new();
2148 let mut ty_constraints = Vec::new();
2149 if let Some(arg_generics) = arg.generic_args() {
2150 for ty in arg_generics.into_iter().filter_map(|param| match param {
2151 clean::GenericArg::Type(ty) => Some(ty),
2152 _ => None,
2153 }) {
2154 simplify_fn_type(
2155 self_,
2156 generics,
2157 &ty,
2158 tcx,
2159 recurse + 1,
2160 &mut ty_generics,
2161 rgen,
2162 is_return,
2163 cache,
2164 );
2165 }
2166 for constraint in arg_generics.constraints() {
2167 simplify_fn_constraint(
2168 self_,
2169 generics,
2170 &constraint,
2171 tcx,
2172 recurse + 1,
2173 &mut ty_constraints,
2174 rgen,
2175 is_return,
2176 cache,
2177 );
2178 }
2179 }
2180 if is_self
2193 && let Type::Path { path } = arg
2194 && let def_id = path.def_id()
2195 && let Some(trait_) = cache.traits.get(&def_id)
2196 && trait_.items.iter().any(|at| at.is_required_associated_type())
2197 {
2198 for assoc_ty in &trait_.items {
2199 if let clean::ItemKind::RequiredAssocTypeItem(_generics, bounds) =
2200 &assoc_ty.kind
2201 && let Some(name) = assoc_ty.name
2202 {
2203 let idx = -isize::try_from(rgen.len() + 1).unwrap();
2204 let (idx, stored_bounds) = rgen
2205 .entry(SimplifiedParam::AssociatedType(def_id, name))
2206 .or_insert_with(|| (idx, Vec::new()));
2207 let idx = *idx;
2208 if stored_bounds.is_empty() {
2209 let mut type_bounds = Vec::new();
2213 for bound in bounds {
2214 if let Some(path) = bound.get_trait_path() {
2215 let ty = Type::Path { path };
2216 simplify_fn_type(
2217 self_,
2218 generics,
2219 &ty,
2220 tcx,
2221 recurse + 1,
2222 &mut type_bounds,
2223 rgen,
2224 is_return,
2225 cache,
2226 );
2227 }
2228 }
2229 let stored_bounds = &mut rgen
2230 .get_mut(&SimplifiedParam::AssociatedType(def_id, name))
2231 .unwrap()
2232 .1;
2233 if stored_bounds.is_empty() {
2234 *stored_bounds = type_bounds;
2235 }
2236 }
2237 ty_constraints.push((
2238 RenderTypeId::AssociatedType(name),
2239 vec![RenderType {
2240 id: Some(RenderTypeId::Index(idx)),
2241 generics: None,
2242 bindings: None,
2243 }],
2244 ))
2245 }
2246 }
2247 }
2248 let id = get_index_type_id(arg, rgen);
2249 if id.is_some() || !ty_generics.is_empty() {
2250 res.push(RenderType {
2251 id,
2252 bindings: if ty_constraints.is_empty() { None } else { Some(ty_constraints) },
2253 generics: if ty_generics.is_empty() { None } else { Some(ty_generics) },
2254 });
2255 }
2256 }
2257 }
2258}
2259
2260fn simplify_fn_constraint<'a>(
2261 self_: Option<&'a Type>,
2262 generics: &Generics,
2263 constraint: &'a clean::AssocItemConstraint,
2264 tcx: TyCtxt<'_>,
2265 recurse: usize,
2266 res: &mut Vec<(RenderTypeId, Vec<RenderType>)>,
2267 rgen: &mut FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)>,
2268 is_return: bool,
2269 cache: &Cache,
2270) {
2271 let mut ty_constraints = Vec::new();
2272 let ty_constrained_assoc = RenderTypeId::AssociatedType(constraint.assoc.name);
2273 for param in &constraint.assoc.args {
2274 match param {
2275 clean::GenericArg::Type(arg) => simplify_fn_type(
2276 self_,
2277 generics,
2278 &arg,
2279 tcx,
2280 recurse + 1,
2281 &mut ty_constraints,
2282 rgen,
2283 is_return,
2284 cache,
2285 ),
2286 clean::GenericArg::Lifetime(_)
2287 | clean::GenericArg::Const(_)
2288 | clean::GenericArg::Infer => {}
2289 }
2290 }
2291 for constraint in constraint.assoc.args.constraints() {
2292 simplify_fn_constraint(
2293 self_,
2294 generics,
2295 &constraint,
2296 tcx,
2297 recurse + 1,
2298 res,
2299 rgen,
2300 is_return,
2301 cache,
2302 );
2303 }
2304 match &constraint.kind {
2305 clean::AssocItemConstraintKind::Equality { term } => {
2306 if let clean::Term::Type(arg) = &term {
2307 simplify_fn_type(
2308 self_,
2309 generics,
2310 arg,
2311 tcx,
2312 recurse + 1,
2313 &mut ty_constraints,
2314 rgen,
2315 is_return,
2316 cache,
2317 );
2318 }
2319 }
2320 clean::AssocItemConstraintKind::Bound { bounds } => {
2321 for bound in &bounds[..] {
2322 if let Some(path) = bound.get_trait_path() {
2323 let ty = Type::Path { path };
2324 simplify_fn_type(
2325 self_,
2326 generics,
2327 &ty,
2328 tcx,
2329 recurse + 1,
2330 &mut ty_constraints,
2331 rgen,
2332 is_return,
2333 cache,
2334 );
2335 }
2336 }
2337 }
2338 }
2339 res.push((ty_constrained_assoc, ty_constraints));
2340}
2341
2342fn make_nullary_fn(
2346 clean_type: &clean::Type,
2347) -> (Vec<RenderType>, Vec<RenderType>, Vec<Option<Symbol>>, Vec<Vec<RenderType>>) {
2348 let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> = Default::default();
2349 let output = get_index_type(clean_type, vec![], &mut rgen);
2350 (vec![], vec![output], vec![], vec![])
2351}
2352
2353fn get_fn_inputs_and_outputs(
2358 func: &Function,
2359 tcx: TyCtxt<'_>,
2360 impl_or_trait_generics: Option<&(clean::Type, clean::Generics)>,
2361 cache: &Cache,
2362) -> (Vec<RenderType>, Vec<RenderType>, Vec<Option<Symbol>>, Vec<Vec<RenderType>>) {
2363 let decl = &func.decl;
2364
2365 let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> = Default::default();
2366
2367 let combined_generics;
2368 let (self_, generics) = if let Some((impl_self, impl_generics)) = impl_or_trait_generics {
2369 match (impl_generics.is_empty(), func.generics.is_empty()) {
2370 (true, _) => (Some(impl_self), &func.generics),
2371 (_, true) => (Some(impl_self), impl_generics),
2372 (false, false) => {
2373 let params =
2374 func.generics.params.iter().chain(&impl_generics.params).cloned().collect();
2375 let where_predicates = func
2376 .generics
2377 .where_predicates
2378 .iter()
2379 .chain(&impl_generics.where_predicates)
2380 .cloned()
2381 .collect();
2382 combined_generics = clean::Generics { params, where_predicates };
2383 (Some(impl_self), &combined_generics)
2384 }
2385 }
2386 } else {
2387 (None, &func.generics)
2388 };
2389
2390 let mut param_types = Vec::new();
2391 for param in decl.inputs.iter() {
2392 simplify_fn_type(
2393 self_,
2394 generics,
2395 ¶m.type_,
2396 tcx,
2397 0,
2398 &mut param_types,
2399 &mut rgen,
2400 false,
2401 cache,
2402 );
2403 }
2404
2405 let mut ret_types = Vec::new();
2406 simplify_fn_type(self_, generics, &decl.output, tcx, 0, &mut ret_types, &mut rgen, true, cache);
2407
2408 let mut simplified_params = rgen.into_iter().collect::<Vec<_>>();
2409 simplified_params.sort_by_key(|(_, (idx, _))| -idx);
2410 (
2411 param_types,
2412 ret_types,
2413 simplified_params
2414 .iter()
2415 .map(|(name, (_idx, _traits))| match name {
2416 SimplifiedParam::Symbol(name) => Some(*name),
2417 SimplifiedParam::Anonymous(_) => None,
2418 SimplifiedParam::AssociatedType(def_id, name) => {
2419 Some(Symbol::intern(&format!("{}::{}", tcx.item_name(*def_id), name)))
2420 }
2421 })
2422 .collect(),
2423 simplified_params.into_iter().map(|(_name, (_idx, traits))| traits).collect(),
2424 )
2425}