ouroboros_macro/generate/
type_asserts.rs
1use proc_macro2::TokenStream;
2use quote::{format_ident, quote};
3use syn::GenericParam;
4
5use crate::{
6 covariance_detection::apparent_std_container_type, info_structures::StructInfo,
7 utils::replace_this_with_lifetime,
8};
9
10pub fn make_type_asserts(info: &StructInfo) -> TokenStream {
11 let mut checks = Vec::new();
12 let fake_lifetime = if let Some(GenericParam::Lifetime(param)) = info.generic_params().first() {
13 param.lifetime.ident.clone()
14 } else {
15 format_ident!("static")
16 };
17 for field in &info.fields {
18 let field_type = &field.typ;
19 if let Some((std_type, _eltype)) = apparent_std_container_type(field_type) {
20 let checker_name = match std_type {
21 "Box" => "is_std_box_type",
22 "Arc" => "is_std_arc_type",
23 "Rc" => "is_std_rc_type",
24 _ => unreachable!(),
25 };
26 let checker_name = format_ident!("{}", checker_name);
27 let static_field_type =
28 replace_this_with_lifetime(quote! { #field_type }, fake_lifetime.clone());
29 checks.push(quote! {
30 ::ouroboros::macro_help::CheckIfTypeIsStd::<#static_field_type>::#checker_name();
31 });
32 }
33 }
34 let generic_params = info.generic_params();
35 let generic_where = &info.generics.where_clause;
36 quote! {
37 fn type_asserts <#generic_params>() #generic_where {
38 #(#checks)*
39 }
40 }
41}