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