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}