diff options
| author | Martin Fischer <martin@push-f.com> | 2021-11-19 10:35:56 +0100 | 
|---|---|---|
| committer | Martin Fischer <martin@push-f.com> | 2021-11-19 10:35:56 +0100 | 
| commit | d8a313dd422c78fb018cfe4249b526fe3e9dc851 (patch) | |
| tree | 743e20edfd20058b6b784b9099544ff3878d3278 /src | |
| parent | eb686879fdd7cde5d09837c202ebd25c9c9889a6 (diff) | |
allow same-named method generics if they have same bounds
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 25 | 
1 files changed, 23 insertions, 2 deletions
| @@ -1,5 +1,7 @@  #![doc = include_str!("../README.md")] +use std::collections::HashMap; +  use proc_macro::TokenStream;  use proc_macro2::Group;  use quote::format_ident; @@ -8,6 +10,7 @@ use quote::quote_spanned;  use quote::ToTokens;  use syn::parse_macro_input;  use syn::punctuated::Punctuated; +use syn::spanned::Spanned;  use syn::token::Brace;  use syn::token::Gt;  use syn::token::Lt; @@ -171,6 +174,14 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream {          items: Vec::new(),      }; +    let mut generic_map = HashMap::new(); + +    for generic in &dyn_trait.generics.params { +        if let GenericParam::Type(type_param) = generic { +            generic_map.insert(type_param.ident.clone(), type_param.bounds.clone()); +        } +    } +      for (signature, parsed_method) in objectifiable_methods {          let mut new_method = TraitItemMethod {              attrs: Vec::new(), @@ -235,8 +246,18 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream {              // FUTURE: use Vec::drain_filter once it's stable              let mut i = 0;              while i < params.len() { -                if matches!(params[i], GenericParam::Type(_)) { -                    dyn_trait.generics.params.push(params.remove(i)); +                if let GenericParam::Type(type_param) = ¶ms[i] { +                    if let Some(bounds) = generic_map.get(&type_param.ident) { +                        if *bounds == type_param.bounds { +                            params.remove(i); +                            continue; +                        } else { +                            return abort!(type_param.span(), "dynamize failure: there exists a same-named method generic with different bounds"); +                        } +                    } else { +                        generic_map.insert(type_param.ident.clone(), type_param.bounds.clone()); +                        dyn_trait.generics.params.push(params.remove(i)); +                    }                  } else {                      i += 1;                  } | 
