From 73b1ca899858b7079bec54a6e4f29941cbb8d0bd Mon Sep 17 00:00:00 2001
From: Martin Fischer <martin@push-f.com>
Date: Wed, 24 Nov 2021 19:30:32 +0100
Subject: better error message for <Self as Foo>::X

---
 src/lib.rs                             |  3 +++
 src/transform.rs                       | 15 ++++++++++++++-
 ui-tests/src/bin/qualified_self.rs     | 10 ++++++++++
 ui-tests/src/bin/qualified_self.stderr |  5 +++++
 4 files changed, 32 insertions(+), 1 deletion(-)
 create mode 100644 ui-tests/src/bin/qualified_self.rs
 create mode 100644 ui-tests/src/bin/qualified_self.stderr

diff --git a/src/lib.rs b/src/lib.rs
index 277720e..00b9772 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;
+  |                        ^^^^
-- 
cgit v1.2.3