(
&mut self,
payload_for: PayloadFor,
module: &str,
index: usize,
func_name: &str,
payload_type: Option<&Type>,
)
| 522 | } |
| 523 | |
| 524 | fn generate_payload( |
| 525 | &mut self, |
| 526 | payload_for: PayloadFor, |
| 527 | module: &str, |
| 528 | index: usize, |
| 529 | func_name: &str, |
| 530 | payload_type: Option<&Type>, |
| 531 | ) { |
| 532 | // Rust requires one-impl-per-type, so any `id` here is transformed |
| 533 | // into its canonical representation using |
| 534 | // `get_representative_type`. This ensures that type aliases, uses, |
| 535 | // etc, all get canonicalized to the exact same ID regardless of |
| 536 | // type structure. This canonical key is used for deduplication only. |
| 537 | // |
| 538 | // Note that `get_representative_type` maps ids-to-ids which is 95% |
| 539 | // of what we want, but this additionally goes one layer further to |
| 540 | // see if the final id is actually itself a typedef, which would |
| 541 | // always be to a primitive, and then uses the primitive type |
| 542 | // instead of the typedef to canonicalize with other streams/futures |
| 543 | // using the primitive type. |
| 544 | let canonical_payload = match payload_type { |
| 545 | Some(Type::Id(id)) => { |
| 546 | let id = self.r#gen.types.get_representative_type(*id); |
| 547 | match self.resolve.types[id].kind { |
| 548 | TypeDefKind::Type(t) => Some(t), |
| 549 | _ => Some(Type::Id(id)), |
| 550 | } |
| 551 | } |
| 552 | other => other.copied(), |
| 553 | }; |
| 554 | { |
| 555 | let map = match payload_for { |
| 556 | PayloadFor::Future => &self.r#gen.future_payloads, |
| 557 | PayloadFor::Stream => &self.r#gen.stream_payloads, |
| 558 | }; |
| 559 | if map.contains_key(&canonical_payload) { |
| 560 | return; |
| 561 | } |
| 562 | } |
| 563 | |
| 564 | // Use the original (non-canonicalized) type for generating the |
| 565 | // type name and code. Since structurally equal types |
| 566 | // resolve to the same Rust type, it doesn't matter which alias |
| 567 | // path we use in the generated `impl`. |
| 568 | let payload_type = match payload_type { |
| 569 | Some(Type::Id(id)) => match self.resolve.types[*id].kind { |
| 570 | TypeDefKind::Type(t) => Some(t), |
| 571 | _ => Some(Type::Id(*id)), |
| 572 | }, |
| 573 | other => other.copied(), |
| 574 | }; |
| 575 | let payload_type = payload_type.as_ref(); |
| 576 | let name = match payload_type { |
| 577 | Some(payload_type) => self.type_name_owned(payload_type), |
| 578 | None => "()".into(), |
| 579 | }; |
| 580 | let ordinal = match payload_for { |
| 581 | PayloadFor::Future => self.r#gen.future_payloads.len(), |
no test coverage detected