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