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