aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Fischer <martin@push-f.com>2021-11-25 13:48:26 +0100
committerMartin Fischer <martin@push-f.com>2021-11-25 13:48:46 +0100
commit8046190e8f537407210fb87acbfe96d4084d58da (patch)
tree34c093627f5fd75db82cb8fb48402b82ace7d803 /src
parent74a29b912aaa14dbeb7e5c51ae11c61e733ef645 (diff)
support Self qualified as same trait
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs7
-rw-r--r--src/trait_sig.rs40
-rw-r--r--src/transform.rs27
3 files changed, 49 insertions, 25 deletions
diff --git a/src/lib.rs b/src/lib.rs
index fc559bc..f8fdde8 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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_ {