diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 7 | ||||
-rw-r--r-- | src/trait_sig.rs | 40 | ||||
-rw-r--r-- | src/transform.rs | 27 |
3 files changed, 49 insertions, 25 deletions
@@ -85,7 +85,8 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream { let mut type_converter = TypeConverter { collections: method_attrs.collections, - ..TypeConverter::default() + assoc_type_conversions: HashMap::new(), + trait_ident: original_trait.ident.clone(), }; for item in &original_trait.items { @@ -158,8 +159,8 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream { MethodError::Transform(TransformError::QualifiedAssociatedType) => { return abort!(span, "dynamize does not support qualified associated types") } - MethodError::Transform(TransformError::QualifiedSelfAssociatedType) => { - return abort!(span, "dynamize does not support associated types of a qualified Self") + MethodError::Transform(TransformError::SelfQualifiedAsOtherTrait) => { + return abort!(span, "dynamize does not support Self qualified as another trait") } MethodError::UnconvertedAssocType => { return abort!(span, "dynamize does not support associated types here") diff --git a/src/trait_sig.rs b/src/trait_sig.rs index 3fb439f..5d8eddf 100644 --- a/src/trait_sig.rs +++ b/src/trait_sig.rs @@ -140,6 +140,8 @@ fn bounds_self_and_has_bound_sized(predicate: &WherePredicate) -> bool { #[cfg(test)] mod tests { + use std::collections::HashMap; + use quote::{format_ident, quote}; use syn::{TraitItemMethod, Type}; @@ -149,6 +151,14 @@ mod tests { transform::{TransformError, TypeConverter}, }; + fn test_converter() -> TypeConverter<'static> { + TypeConverter { + assoc_type_conversions: HashMap::new(), + collections: HashMap::new(), + trait_ident: format_ident!("test"), + } + } + #[test] fn ok_void() { let mut type1: TraitItemMethod = syn::parse2(quote! { @@ -157,7 +167,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Ok(SignatureChanges { return_type: TypeTransform::NoOp, .. @@ -172,7 +182,7 @@ mod tests { }) .unwrap(); - let mut type_converter = TypeConverter::default(); + let mut type_converter = test_converter(); let ident = format_ident!("A"); let dest_inner = Type::Verbatim(quote! {Example}); let dest = DestType::Into(&dest_inner); @@ -195,7 +205,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err(( _, MethodError::Transform(TransformError::AssocTypeWithoutDestType) @@ -211,7 +221,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::NonDispatchableMethod)) )); } @@ -224,7 +234,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::NonDispatchableMethod)) )); } @@ -237,7 +247,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::NonDispatchableMethod)) )); } @@ -250,7 +260,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::NonDispatchableMethod)) )); } @@ -263,7 +273,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::Transform(TransformError::UnsupportedType))) )); } @@ -276,7 +286,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::Transform(TransformError::UnsupportedType))) )); } @@ -289,7 +299,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::Transform(TransformError::UnsupportedType))) )); } @@ -302,7 +312,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::Transform(TransformError::UnsupportedType))) )); } @@ -315,7 +325,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::AssocTypeInInputs)) )); } @@ -328,7 +338,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::AssocTypeInInputs)) )); } @@ -341,7 +351,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::ImplTraitInInputs)) )); } @@ -354,7 +364,7 @@ mod tests { .unwrap(); assert!(matches!( - convert_trait_signature(&mut type1.sig, &Default::default()), + convert_trait_signature(&mut type1.sig, &test_converter()), Err((_, MethodError::Transform(TransformError::UnsupportedType))) )); } diff --git a/src/transform.rs b/src/transform.rs index eed48c4..75138c9 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -14,10 +14,10 @@ use crate::{ trait_sig::{MethodError, TypeTransform}, }; -#[derive(Default)] pub struct TypeConverter<'a> { pub assoc_type_conversions: HashMap<Ident, DestType<'a>>, pub collections: HashMap<Ident, usize>, + pub trait_ident: Ident, } #[derive(Debug)] @@ -27,7 +27,7 @@ pub enum TransformError { ExpectedAtLeastNTypes(usize), AssocTypeAfterFirstNTypes(usize, Ident), QualifiedAssociatedType, - QualifiedSelfAssociatedType, + SelfQualifiedAsOtherTrait, } impl TypeConverter<'_> { @@ -115,7 +115,8 @@ impl TypeConverter<'_> { } if let Type::Path(TypePath { - qself: Some(qself), .. + path, + qself: Some(qself), }) = type_ { if let Type::Path(self_path) = qself.ty.as_ref() { @@ -123,10 +124,22 @@ impl TypeConverter<'_> { if !self_path.path.is_ident("Self") { return Err((self_path.span(), TransformError::QualifiedAssociatedType)); } - return Err(( - self_path.span(), - TransformError::QualifiedSelfAssociatedType, - )); + + if qself.position == 1 + && path.segments.len() == 2 + && path.segments[0].arguments.is_empty() + && path.segments[0].ident == self.trait_ident + { + let ident = &path.segments[1].ident; + let dest_type = + self.assoc_type_conversions.get(ident).ok_or_else(|| { + (ident.span(), TransformError::AssocTypeWithoutDestType) + })?; + *type_ = dest_type.get_dest(); + return Ok(dest_type.type_transformation()); + } + + return Err((path.span(), TransformError::SelfQualifiedAsOtherTrait)); } } } else if let Type::Path(TypePath { path, qself: None }) = type_ { |