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