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