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