diff options
-rw-r--r-- | src/lib.rs | 3 | ||||
-rw-r--r-- | src/transform.rs | 15 | ||||
-rw-r--r-- | ui-tests/src/bin/qualified_self.rs | 10 | ||||
-rw-r--r-- | ui-tests/src/bin/qualified_self.stderr | 5 |
4 files changed, 32 insertions, 1 deletions
@@ -229,6 +229,9 @@ pub fn dynamize(_attr: TokenStream, input: TokenStream) -> TokenStream { n ) } + MethodError::Transform(TransformError::QualifiedSelfAssociatedType) => { + return abort!(span, "dynamize does not support associated types of a qualified Self") + } MethodError::UnconvertedAssocType => { return abort!(span, "dynamize does not support associated types here") } diff --git a/src/transform.rs b/src/transform.rs index 8de4c96..594d383 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use proc_macro2::Span; use quote::quote; use syn::{ - spanned::Spanned, GenericArgument, Generics, Ident, PathArguments, TraitBound, Type, + spanned::Spanned, GenericArgument, Generics, Ident, PathArguments, QSelf, TraitBound, Type, TypeParamBound, TypePath, TypeReference, TypeTraitObject, WherePredicate, }; @@ -11,6 +11,7 @@ use crate::{ filter_map_assoc_paths, match_assoc_type, parse_assoc_type::{BoxType, DestType}, parse_trait_sig::{MethodError, TypeTransform}, + path_is_assoc_type, syn_utils::{iter_path, iter_type, type_arguments_mut}, }; @@ -26,6 +27,7 @@ pub enum TransformError { UnsupportedType, ExpectedAtLeastNTypes(usize), AssocTypeAfterFirstNTypes(usize, Ident), + QualifiedSelfAssociatedType, } impl TypeConverter<'_> { @@ -57,6 +59,17 @@ impl TypeConverter<'_> { } pub fn convert_type(&self, type_: &mut Type) -> Result<TypeTransform, (Span, TransformError)> { + if let Type::Path(TypePath { + qself: Some(QSelf { ty, .. }), + .. + }) = type_ + { + if let Type::Path(TypePath { qself: None, path }) = ty.as_ref() { + if path_is_assoc_type(path) { + return Err((path.span(), TransformError::QualifiedSelfAssociatedType)); + } + } + } if !iter_type(type_).any(match_assoc_type) { return Ok(TypeTransform::NoOp); } diff --git a/ui-tests/src/bin/qualified_self.rs b/ui-tests/src/bin/qualified_self.rs new file mode 100644 index 0000000..b02f623 --- /dev/null +++ b/ui-tests/src/bin/qualified_self.rs @@ -0,0 +1,10 @@ +trait Foo { + type X: Into<String>; +} + +#[dynamize::dynamize] +trait Bar: Foo { + fn test(&self) -> <Self as Foo>::X; +} + +fn main() {} diff --git a/ui-tests/src/bin/qualified_self.stderr b/ui-tests/src/bin/qualified_self.stderr new file mode 100644 index 0000000..1b5f9f9 --- /dev/null +++ b/ui-tests/src/bin/qualified_self.stderr @@ -0,0 +1,5 @@ +error: dynamize does not support associated types of a qualified Self + --> src/bin/qualified_self.rs:7:24 + | +7 | fn test(&self) -> <Self as Foo>::X; + | ^^^^ |