Repository: BrynCooke/buildstructor (language: rust)

Issue:
Parameters fail to find associated types of generics
When using a buildstructor with associated type parameters a compile error is generated as some type info is missing on the intermediate builder type.


Discussion / hints:

Fix patch:
diff --git a/.tool-versions b/.tool-versions
index 09ab85c..aa9c22d 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1,1 +1,1 @@
-rust 1.63.0
+rust 1.64.0
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 314f62f..2fbb399 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## 0.5.1 - 2022-11-03
+[#96](https://github.com/BrynCooke/buildstructor/issues/96)
+Fix associated type parameters:
+```rust
+#[buildstructor]
+impl<T: MyTrait> Foo<T> {
+    #[builder]
+    pub fn new(foo: T, bar: T::Bar) -> Foo<T> {
+        Foo { foo, bar }
+    }
+}
+```
+
 ## 0.5.0 - 2022-08-05
 
 [#81](https://github.com/BrynCooke/buildstructor/issues/81)
diff --git a/src/buildstructor/codegen.rs b/src/buildstructor/codegen.rs
index 95b6a46..17bd711 100644
--- a/src/buildstructor/codegen.rs
+++ b/src/buildstructor/codegen.rs
@@ -72,7 +72,7 @@ pub fn codegen(ir: Ir) -> Result<TokenStream> {
     let builder_init_generics = Generics::combine(vec![&ir.impl_generics, &ir.delegate_generics]);
     let builder_init_generic_args = builder_init_generics.to_generic_args().maybe();
     let builder_init_generic_args_with_lifetime = builder_init_generics
-        .to_generic_args()
+        .to_generic_bounds()
         .with_implicit_lifetime(ir.implicit_lifetime);
     let builder_init_generic_args_phantom = builder_init_generic_args.clone().map(|a| {
         let args: Punctuated<GenericArgument, Token![,]> =
@@ -158,6 +158,7 @@ pub fn codegen(ir: Ir) -> Result<TokenStream> {
         }
 
         #[doc=#type_doc]
+        #[allow(type_alias_bounds)]
         #vis type #builder_alias_name #builder_init_generic_args_with_lifetime = #module_name::#builder_name #builder_init_generic_args_with_state_with_lifetime;
 
         mod #module_name {
@@ -647,4 +648,9 @@ mod tests {
     fn specialization_self() {
         assert_codegen!(specialization_returns_self_test_case());
     }
+
+    #[test]
+    fn associated_types() {
+        assert_codegen!(associated_types_test_case());
+    }
 }
diff --git a/src/buildstructor/mod.rs b/src/buildstructor/mod.rs
index a3f69ab..897ed22 100644
--- a/src/buildstructor/mod.rs
+++ b/src/buildstructor/mod.rs
@@ -337,4 +337,16 @@ mod tests {
             }
         )
     }
+
+    pub fn associated_types_test_case() -> Ast {
+        parse_quote!(
+            #[buildstructor]
+            impl<T: MyTrait> Foo<T> {
+                #[builder]
+                pub fn new(foo: T, bar: T::Bar) -> Foo<T> {
+                    Foo { foo, bar }
+                }
+            }
+        )
+    }
 }
diff --git a/src/buildstructor/utils.rs b/src/buildstructor/utils.rs
index 3d4f959..09bad96 100644
--- a/src/buildstructor/utils.rs
+++ b/src/buildstructor/utils.rs
@@ -2,8 +2,8 @@ use quote::format_ident;
 use syn::punctuated::Punctuated;
 use syn::spanned::Spanned;
 use syn::{
-    AngleBracketedGenericArguments, Expr, ExprPath, ExprTuple, GenericArgument, GenericParam,
-    Generics, Ident, Lifetime, Path, PathArguments, PathSegment, Token, TraitBound,
+    AngleBracketedGenericArguments, Constraint, Expr, ExprPath, ExprTuple, GenericArgument,
+    GenericParam, Generics, Ident, Lifetime, Path, PathArguments, PathSegment, Token, TraitBound,
     TraitBoundModifier, Type, TypeParam, TypeParamBound, TypePath, TypeTuple, WhereClause,
 };
 
@@ -60,6 +60,7 @@ impl IdentExt for Ident {
 pub trait GenericsExt {
     fn to_tuple_type(&self) -> TypeTuple;
     fn to_generic_args(&self) -> AngleBracketedGenericArguments;
+    fn to_generic_bounds(&self) -> AngleBracketedGenericArguments;
     fn to_expr_tuple(&self, populate: impl Fn(usize, &TypeParam) -> Expr) -> ExprTuple;
     fn without(self, idx: usize) -> Self;
     fn combine(generics: Vec<&Generics>) -> Generics;
@@ -94,6 +95,23 @@ impl GenericsExt for Generics {
         }
     }
 
+    fn to_generic_bounds(&self) -> AngleBracketedGenericArguments {
+        AngleBracketedGenericArguments {
+            colon2_token: None,
+            lt_token: Default::default(),
+            args: Punctuated::from_iter(self.params.iter().filter_map(|p| match p {
+                GenericParam::Type(t) => Some(GenericArgument::Constraint(Constraint {
+                    ident: t.ident.clone(),
+                    bounds: t.bounds.clone(),
+                    colon_token: Default::default(),
+                })),
+                GenericParam::Lifetime(l) => Some(GenericArgument::Lifetime(l.lifetime.clone())),
+                GenericParam::Const(_) => None,
+            })),
+            gt_token: Default::default(),
+        }
+    }
+
     fn to_expr_tuple(&self, populate: impl Fn(usize, &TypeParam) -> Expr) -> ExprTuple {
         ExprTuple {
             attrs: Default::default(),


Test patch:
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__associated_types.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__associated_types.snap
new file mode 100644
index 0000000..d743bc4
--- /dev/null
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__associated_types.snap
@@ -0,0 +1,97 @@
+---
+source: src/buildstructor/codegen.rs
+expression: output
+---
+impl<T: MyTrait> Foo<T> {
+    pub fn builder() -> NewFooBuilder<T> {
+        __foo_new_builder::new()
+    }
+}
+///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
+pub type NewFooBuilder<T: MyTrait> = __foo_new_builder::__FooBuilder<
+    (__foo_new_builder::__Required<T>, __foo_new_builder::__Required<T::Bar>),
+    T,
+>;
+mod __foo_new_builder {
+    use super::*;
+    #[inline(always)]
+    pub fn new<T: MyTrait>() -> __FooBuilder<
+        (__foo_new_builder::__Required<T>, __foo_new_builder::__Required<T::Bar>),
+        T,
+    > {
+        __FooBuilder {
+            fields: (__required(), __required()),
+            _phantom: core::default::Default::default(),
+        }
+    }
+    pub struct __Required<T> {
+        _uninit: std::mem::MaybeUninit<T>,
+    }
+    pub struct __Optional<T> {
+        lazy: Option<T>,
+    }
+    pub struct __Set<T> {
+        value: T,
+    }
+    #[inline(always)]
+    fn __set<T>(value: T) -> __Set<T> {
+        __Set { value }
+    }
+    #[inline(always)]
+    fn __required<T>() -> __Required<T> {
+        __Required::<T> {
+            _uninit: std::mem::MaybeUninit::uninit(),
+        }
+    }
+    #[inline(always)]
+    fn __optional<T>() -> __Optional<T> {
+        __Optional::<T> { lazy: None }
+    }
+    impl<T: Default> From<__Optional<T>> for __Set<T> {
+        #[inline(always)]
+        fn from(o: __Optional<T>) -> Self {
+            __Set {
+                value: o.lazy.unwrap_or_default(),
+            }
+        }
+    }
+    pub struct __FooBuilder<__P, T> {
+        fields: __P,
+        _phantom: core::marker::PhantomData<(T)>,
+    }
+    impl<__1, T: MyTrait> __FooBuilder<(__Required<T>, __1), T> {
+        #[inline(always)]
+        pub fn foo(self, foo: T) -> __FooBuilder<(__Set<T>, __1), T> {
+            let foo = foo;
+            __FooBuilder {
+                fields: (__set(foo), self.fields.1),
+                _phantom: core::default::Default::default(),
+            }
+        }
+    }
+    impl<__0, T: MyTrait> __FooBuilder<(__0, __Required<T::Bar>), T> {
+        #[inline(always)]
+        pub fn bar<__T: Into<T::Bar>>(
+            self,
+            bar: __T,
+        ) -> __FooBuilder<(__0, __Set<T::Bar>), T> {
+            let bar = bar.into();
+            __FooBuilder {
+                fields: (self.fields.0, __set(bar)),
+                _phantom: core::default::Default::default(),
+            }
+        }
+    }
+    impl<
+        T: MyTrait,
+        __P0: Into<__Set<T>>,
+        __P1: Into<__Set<T::Bar>>,
+    > __FooBuilder<(__P0, __P1), T> {
+        #[inline(always)]
+        pub fn build(self) -> Foo<T> {
+            Foo::new(self.fields.0.into().value, self.fields.1.into().value)
+        }
+    }
+}
+
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap
index e25e8eb..f2d3264 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<usize>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_generics_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_generics_test.snap
index fdc8ba3..49093a0 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_generics_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_generics_test.snap
@@ -8,7 +8,8 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
-type NewFooBuilder<K, V> = __foo_new_builder::__FooBuilder<
+#[allow(type_alias_bounds)]
+type NewFooBuilder<K: Into<String> + Eq + Hash, V: Into<String>> = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Optional<HashMap<K, V>>,),
     K,
     V,
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_generics_test2.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_generics_test2.snap
index 486e497..e700ada 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_generics_test2.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_generics_test2.snap
@@ -11,7 +11,8 @@ impl Collections {
     }
 }
 ///Autogenerated by buildstructor
-type NewCollectionsBuilder<K, V> = __collections_new_builder::__CollectionsBuilder<
+#[allow(type_alias_bounds)]
+type NewCollectionsBuilder<K: Into<String> + Eq + Hash, V: Into<String>> = __collections_new_builder::__CollectionsBuilder<
     (
         __collections_new_builder::__Optional<HashMap<K, V>>,
         __collections_new_builder::__Optional<HashSet<K>>,
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_option_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_option_test.snap
index 3e4f60b..5de05cf 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_option_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_option_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Optional<HashMap<Option<String>, Option<String>>>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap
index d2b04a5..889a4b7 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (
         __foo_new_builder::__Required<usize>,
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__doc.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__doc.snap
index 14fbfcc..5173989 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__doc.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__doc.snap
@@ -9,6 +9,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<usize>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap
index 5e4881c..123fdbd 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<usize>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap
index 5ee96bc..44418d9 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap
@@ -8,6 +8,7 @@ impl<T> Foo<T> {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder<T> = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<T>,),
     T,
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap
index b3306f5..87a3d40 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap
@@ -8,7 +8,8 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
-type NewFooBuilder<T> = __foo_new_builder::__FooBuilder<
+#[allow(type_alias_bounds)]
+type NewFooBuilder<T: Into<String>> = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<T>,),
     T,
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_where_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_where_test.snap
index 2e309b3..855aee5 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_where_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_where_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder<T> = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<T>,),
     T,
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__lifetime.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__lifetime.snap
index 283e1ac..612abc4 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__lifetime.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__lifetime.snap
@@ -8,6 +8,7 @@ impl<'a> Foo<'a> {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder<'a> = __foo_new_builder::__FooBuilder<
     'a,
     (__foo_new_builder::__Required<&'a String>,),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multi_field_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multi_field_test.snap
index 6c91a8f..c17472a 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multi_field_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multi_field_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<usize>, __foo_new_builder::__Required<usize>),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multiple_generics_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multiple_generics_test.snap
index c076498..d14691a 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multiple_generics_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__multiple_generics_test.snap
@@ -8,6 +8,7 @@ impl<T> Request<T> {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 pub type FakeNewRequestBuilder<T, K, V> = __request_fake_new_builder::__RequestBuilder<
     (
         __request_fake_new_builder::__Optional<Vec<(K, V)>>,
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap
index aa2cf5d..17bf3b8 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Optional<Option<usize>>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap
index 743eb00..e955b0a 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 pub type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<usize>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__reference.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__reference.snap
index 18ca0ff..88a8e82 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__reference.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__reference.snap
@@ -9,6 +9,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder<'__a> = __foo_new_builder::__FooBuilder<
     '__a,
     (__foo_new_builder::__Required<&usize>,),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__returns_self_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__returns_self_test.snap
index 27bad23..a624eee 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__returns_self_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__returns_self_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<usize>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-2.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-2.snap
index 0ec94ec..fc7b88f 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-2.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-2.snap
@@ -8,6 +8,7 @@ impl Client {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type CallWithNoReturnRefClientBuilder<'__a> = __client_call_with_no_return_ref_builder::__ClientBuilder<
     '__a,
     (__client_call_with_no_return_ref_builder::__Required<String>,),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-3.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-3.snap
index a1a8117..0c76918 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-3.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-3.snap
@@ -8,6 +8,7 @@ impl Client {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type CallWithReturnClientBuilder = __client_call_with_return_builder::__ClientBuilder<
     (__client_call_with_return_builder::__Required<String>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-4.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-4.snap
index 1d49573..cb92c26 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-4.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver-4.snap
@@ -8,6 +8,7 @@ impl Client {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type CallWithReturnRefClientBuilder<'__a> = __client_call_with_return_ref_builder::__ClientBuilder<
     '__a,
     (__client_call_with_return_ref_builder::__Required<String>,),
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver.snap
index 71f80ae..43cc5e0 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_receiver.snap
@@ -8,6 +8,7 @@ impl Client {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type CallWithNoReturnClientBuilder = __client_call_with_no_return_builder::__ClientBuilder<
     (__client_call_with_no_return_builder::__Required<String>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_reference.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_reference.snap
index 0b4e86e..78e3a3c 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_reference.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__self_reference.snap
@@ -8,6 +8,7 @@ impl Client {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewClientBuilder<'__a> = __client_new_builder::__ClientBuilder<'__a, ()>;
 mod __client_new_builder {
     use super::*;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__single_field_test.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__single_field_test.snap
index 27bad23..a624eee 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__single_field_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__single_field_test.snap
@@ -8,6 +8,7 @@ impl Foo {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type NewFooBuilder = __foo_new_builder::__FooBuilder<
     (__foo_new_builder::__Required<usize>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__specialization.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__specialization.snap
index 8e6eed5..a78d730 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__specialization.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__specialization.snap
@@ -8,6 +8,7 @@ impl Foo<usize> {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type BoundNewFooBuilder = __foo_bound_new_builder::__FooBuilder<
     (__foo_bound_new_builder::__Required<usize>,),
 >;
diff --git a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__specialization_self.snap b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__specialization_self.snap
index 8e6eed5..a78d730 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__specialization_self.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__specialization_self.snap
@@ -8,6 +8,7 @@ impl Foo<usize> {
     }
 }
 ///Autogenerated by buildstructor
+#[allow(type_alias_bounds)]
 type BoundNewFooBuilder = __foo_bound_new_builder::__FooBuilder<
     (__foo_bound_new_builder::__Required<usize>,),
 >;
diff --git a/tests/buildstructor/fail/duplicate.stderr b/tests/buildstructor/fail/duplicate.stderr
index 54f8961..2252475 100644
--- a/tests/buildstructor/fail/duplicate.stderr
+++ b/tests/buildstructor/fail/duplicate.stderr
@@ -2,7 +2,7 @@ error[E0599]: no method named `simple` found for struct `__FooBuilder<(__Set<Str
   --> tests/buildstructor/fail/duplicate.rs:15:40
    |
 6  | #[buildstructor]
-   | ---------------- method `simple` not found for this
+   | ---------------- method `simple` not found for this struct
 ...
 15 |     let _ = Foo::builder().simple("3").simple("3").build();
    |                                        ^^^^^^ method not found in `__FooBuilder<(__Set<String>,)>`
diff --git a/tests/buildstructor/pass/associated_types.rs b/tests/buildstructor/pass/associated_types.rs
new file mode 100644
index 0000000..71a308a
--- /dev/null
+++ b/tests/buildstructor/pass/associated_types.rs
@@ -0,0 +1,29 @@
+use buildstructor::buildstructor;
+
+pub trait MyTrait {
+    type Bar;
+}
+
+struct MyTraitImpl {}
+
+impl MyTrait for MyTraitImpl {
+    type Bar = String;
+}
+
+#[derive(Debug)]
+pub struct Foo<T: MyTrait> {
+    foo: T,
+    bar: T::Bar,
+}
+
+#[buildstructor]
+impl<T: MyTrait> Foo<T> {
+    #[builder]
+    pub fn new(foo: T, bar: T::Bar) -> Foo<T> {
+        Foo { foo, bar }
+    }
+}
+
+fn main() {
+    let _ = Foo::builder().foo(MyTraitImpl {}).bar("hi").build();
+}