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