Repository: BrynCooke/buildstructor (language: rust)

Issue:
Two builders in the same module clash



Discussion / hints:

Fix patch:
diff --git a/src/buildstructor/codegen.rs b/src/buildstructor/codegen.rs
index a95186e..1e98cbb 100644
--- a/src/buildstructor/codegen.rs
+++ b/src/buildstructor/codegen.rs
@@ -58,7 +58,6 @@ pub fn codegen(ir: Ir) -> Result<TokenStream> {
                 #module_name::new()
             }
         }
-        use #module_name::*;
 
         mod #module_name {
             use super::*;
diff --git a/src/buildstructor/lower.rs b/src/buildstructor/lower.rs
index 73d58ca..02a1a18 100644
--- a/src/buildstructor/lower.rs
+++ b/src/buildstructor/lower.rs
@@ -144,8 +144,14 @@ impl Ir {
             paren_token: Default::default(),
             elems: Punctuated::from_iter(self.builder_fields.iter().map(|field| {
                 match field.field_type {
-                    FieldType::Regular => field.ty.wrap_in_generic(format_ident!("__Required")),
-                    _ => field.ty.wrap_in_generic(format_ident!("__Optional")),
+                    FieldType::Regular => field.ty.wrap_in_generic_with_module(
+                        &self.module_name,
+                        format_ident!("__Required"),
+                    ),
+                    _ => field.ty.wrap_in_generic_with_module(
+                        &self.module_name,
+                        format_ident!("__Optional"),
+                    ),
                 }
             }))
             .with_trailing(),
diff --git a/src/buildstructor/utils.rs b/src/buildstructor/utils.rs
index c8e44f2..2659849 100644
--- a/src/buildstructor/utils.rs
+++ b/src/buildstructor/utils.rs
@@ -187,6 +187,7 @@ pub trait TypeExt {
     fn raw_ident(&self) -> Option<Ident>;
     fn generic_args(&self) -> Option<&Punctuated<GenericArgument, Token![,]>>;
     fn wrap_in_generic(&self, ident: Ident) -> Type;
+    fn wrap_in_generic_with_module(&self, module: &Ident, ident: Ident) -> Type;
     fn to_path(&self) -> Option<Path>;
     fn parse(name: &'static str) -> Type;
 }
@@ -233,6 +234,30 @@ impl TypeExt for Type {
         })
     }
 
+    fn wrap_in_generic_with_module(&self, module: &Ident, ident: Ident) -> Type {
+        Type::Path(TypePath {
+            qself: None,
+            path: Path {
+                leading_colon: None,
+                segments: Punctuated::from_iter(vec![
+                    PathSegment {
+                        ident: module.clone(),
+                        arguments: Default::default(),
+                    },
+                    PathSegment {
+                        ident,
+                        arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments {
+                            colon2_token: Default::default(),
+                            lt_token: Default::default(),
+                            args: Punctuated::from_iter(vec![GenericArgument::Type(self.clone())]),
+                            gt_token: Default::default(),
+                        }),
+                    },
+                ]),
+            },
+        })
+    }
+
     fn to_path(&self) -> Option<Path> {
         if let Type::Path(path) = self {
             return Some(path.path.clone());


Test patch:
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 bb54993..ebe1d9f 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__async_test.snap
@@ -3,14 +3,13 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl Foo {
-    fn builder() -> __foo_builder::__FooBuilder<(__Required<usize>,)> {
+    fn builder() -> __foo_builder::__FooBuilder<(__foo_builder::__Required<usize>,)> {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new() -> __FooBuilder<(__Required<usize>,)> {
+    pub fn new() -> __FooBuilder<(__foo_builder::__Required<usize>,)> {
         __FooBuilder {
             fields: (__required(),),
             phantom: core::default::Default::default(),
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 02a610e..38b1349 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
@@ -4,18 +4,17 @@ expression: output
 ---
 impl Foo {
     fn builder<K: Into<String> + Eq + Hash, V: Into<String>>() -> __foo_builder::__FooBuilder<
-            (__Optional<HashMap<K, V>>,),
+            (__foo_builder::__Optional<HashMap<K, V>>,),
             K,
             V,
         > {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
     pub fn new<K: Into<String> + Eq + Hash, V: Into<String>>() -> __FooBuilder<
-            (__Optional<HashMap<K, V>>,),
+            (__foo_builder::__Optional<HashMap<K, V>>,),
             K,
             V,
         > {
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 22bb90a..d9a4e47 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
@@ -4,16 +4,15 @@ expression: output
 ---
 impl Foo {
     fn builder() -> __foo_builder::__FooBuilder<
-            (__Optional<HashMap<Option<String>, Option<String>>>,),
+            (__foo_builder::__Optional<HashMap<Option<String>, Option<String>>>,),
         > {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
     pub fn new() -> __FooBuilder<
-            (__Optional<HashMap<Option<String>, Option<String>>>,),
+            (__foo_builder::__Optional<HashMap<Option<String>, Option<String>>>,),
         > {
         __FooBuilder {
             fields: (__optional(),),
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 abbdf66..69a5729 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__collection_test.snap
@@ -5,28 +5,27 @@ expression: output
 impl Foo {
     fn builder() -> __foo_builder::__FooBuilder<
             (
-                __Required<usize>,
-                __Optional<HashSet<String>>,
-                __Optional<HashMap<String, String>>,
-                __Optional<Vec<String>>,
-                __Optional<BTreeMap<String, String>>,
-                __Optional<BTreeSet<String>>,
+                __foo_builder::__Required<usize>,
+                __foo_builder::__Optional<HashSet<String>>,
+                __foo_builder::__Optional<HashMap<String, String>>,
+                __foo_builder::__Optional<Vec<String>>,
+                __foo_builder::__Optional<BTreeMap<String, String>>,
+                __foo_builder::__Optional<BTreeSet<String>>,
             ),
         > {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
     pub fn new() -> __FooBuilder<
             (
-                __Required<usize>,
-                __Optional<HashSet<String>>,
-                __Optional<HashMap<String, String>>,
-                __Optional<Vec<String>>,
-                __Optional<BTreeMap<String, String>>,
-                __Optional<BTreeSet<String>>,
+                __foo_builder::__Required<usize>,
+                __foo_builder::__Optional<HashSet<String>>,
+                __foo_builder::__Optional<HashMap<String, String>>,
+                __foo_builder::__Optional<Vec<String>>,
+                __foo_builder::__Optional<BTreeMap<String, String>>,
+                __foo_builder::__Optional<BTreeSet<String>>,
             ),
         > {
         __FooBuilder {
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 fce6566..391cc7b 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__fallible_test.snap
@@ -3,14 +3,13 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl Foo {
-    fn builder() -> __foo_builder::__FooBuilder<(__Required<usize>,)> {
+    fn builder() -> __foo_builder::__FooBuilder<(__foo_builder::__Required<usize>,)> {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new() -> __FooBuilder<(__Required<usize>,)> {
+    pub fn new() -> __FooBuilder<(__foo_builder::__Required<usize>,)> {
         __FooBuilder {
             fields: (__required(),),
             phantom: core::default::Default::default(),
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 1aac642..cd04be4 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__generic_test.snap
@@ -3,14 +3,13 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl<T> Foo<T> {
-    fn builder() -> __foo_builder::__FooBuilder<(__Required<T>,), T> {
+    fn builder() -> __foo_builder::__FooBuilder<(__foo_builder::__Required<T>,), T> {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new<T>() -> __FooBuilder<(__Required<T>,), T> {
+    pub fn new<T>() -> __FooBuilder<(__foo_builder::__Required<T>,), T> {
         __FooBuilder {
             fields: (__required(),),
             phantom: core::default::Default::default(),
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 15fd547..7dd75a9 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__into_test.snap
@@ -3,14 +3,16 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl Foo {
-    fn builder<T: Into<String>>() -> __foo_builder::__FooBuilder<(__Required<T>,), T> {
+    fn builder<T: Into<String>>() -> __foo_builder::__FooBuilder<
+            (__foo_builder::__Required<T>,),
+            T,
+        > {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new<T: Into<String>>() -> __FooBuilder<(__Required<T>,), T> {
+    pub fn new<T: Into<String>>() -> __FooBuilder<(__foo_builder::__Required<T>,), T> {
         __FooBuilder {
             fields: (__required(),),
             phantom: core::default::Default::default(),
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 2d4dc74..4d64317 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
@@ -3,14 +3,13 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl Foo {
-    fn builder<T>() -> __foo_builder::__FooBuilder<(__Required<T>,), T> {
+    fn builder<T>() -> __foo_builder::__FooBuilder<(__foo_builder::__Required<T>,), T> {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new<T>() -> __FooBuilder<(__Required<T>,), T> {
+    pub fn new<T>() -> __FooBuilder<(__foo_builder::__Required<T>,), T> {
         __FooBuilder {
             fields: (__required(),),
             phantom: core::default::Default::default(),
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 70098e7..f301373 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
@@ -3,14 +3,17 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl Foo {
-    fn builder() -> __foo_builder::__FooBuilder<(__Required<usize>, __Required<usize>)> {
+    fn builder() -> __foo_builder::__FooBuilder<
+            (__foo_builder::__Required<usize>, __foo_builder::__Required<usize>),
+        > {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new() -> __FooBuilder<(__Required<usize>, __Required<usize>)> {
+    pub fn new() -> __FooBuilder<
+            (__foo_builder::__Required<usize>, __foo_builder::__Required<usize>),
+        > {
         __FooBuilder {
             fields: (__required(), __required()),
             phantom: core::default::Default::default(),
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 57c4e8e..46eaa65 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__option_test.snap
@@ -3,14 +3,15 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl Foo {
-    fn builder() -> __foo_builder::__FooBuilder<(__Optional<Option<usize>>,)> {
+    fn builder() -> __foo_builder::__FooBuilder<
+            (__foo_builder::__Optional<Option<usize>>,),
+        > {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new() -> __FooBuilder<(__Optional<Option<usize>>,)> {
+    pub fn new() -> __FooBuilder<(__foo_builder::__Optional<Option<usize>>,)> {
         __FooBuilder {
             fields: (__optional(),),
             phantom: core::default::Default::default(),
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 dddbde6..a8740bb 100644
--- a/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap
+++ b/src/buildstructor/snapshots/buildstructor__buildstructor__codegen__tests__pub_test.snap
@@ -3,14 +3,15 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl Foo {
-    pub fn builder() -> __foo_builder::__FooBuilder<(__Required<usize>,)> {
+    pub fn builder() -> __foo_builder::__FooBuilder<
+            (__foo_builder::__Required<usize>,),
+        > {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new() -> __FooBuilder<(__Required<usize>,)> {
+    pub fn new() -> __FooBuilder<(__foo_builder::__Required<usize>,)> {
         __FooBuilder {
             fields: (__required(),),
             phantom: core::default::Default::default(),
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 4c3ef42..51be2f3 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
@@ -3,14 +3,13 @@ source: src/buildstructor/codegen.rs
 expression: output
 ---
 impl Foo {
-    fn builder() -> __foo_builder::__FooBuilder<(__Required<usize>,)> {
+    fn builder() -> __foo_builder::__FooBuilder<(__foo_builder::__Required<usize>,)> {
         __foo_builder::new()
     }
 }
-use __foo_builder::*;
 mod __foo_builder {
     use super::*;
-    pub fn new() -> __FooBuilder<(__Required<usize>,)> {
+    pub fn new() -> __FooBuilder<(__foo_builder::__Required<usize>,)> {
         __FooBuilder {
             fields: (__required(),),
             phantom: core::default::Default::default(),
diff --git a/tests/buildstructor/pass/multiple_builders.rs b/tests/buildstructor/pass/multiple_builders.rs
new file mode 100644
index 0000000..c9ef38e
--- /dev/null
+++ b/tests/buildstructor/pass/multiple_builders.rs
@@ -0,0 +1,27 @@
+use buildstructor::builder;
+pub struct Foo1 {
+    simple: usize,
+}
+
+pub struct Foo2 {
+    simple: usize,
+}
+
+#[builder]
+impl Foo1 {
+    fn new(simple: usize) -> Foo1 {
+        Self { simple }
+    }
+}
+
+#[builder]
+impl Foo2 {
+    fn new(simple: usize) -> Foo2 {
+        Self { simple }
+    }
+}
+
+fn main() {
+    let _ = Foo1::builder().simple(3).build();
+    let _ = Foo2::builder().simple(3).build();
+}