Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Const generics with other generics yields compilation error #106

Closed
awesomelemonade opened this issue Jul 27, 2023 · 1 comment
Closed

Comments

@awesomelemonade
Copy link
Contributor

use typed_builder::TypedBuilder;

// works
#[derive(TypedBuilder)]
struct TestA<const A: usize> {
    data: [u32; A],
}

// works
#[derive(TypedBuilder)]
struct TestB<A, B> {
    data: [A; 3],
    data2: [B; 3],
}

// doesn't work
// #[derive(TypedBuilder)]
// struct TestC<const NUM_COLS: usize, const NUM_ROWS: usize> {
//     data: [[u32; NUM_ROWS]; NUM_COLS],
// }

// doesn't work
// #[derive(TypedBuilder)]
// struct TestD<const A: usize, const B: usize> {
//     data: [u32; A],
//     data2: [u32; B],
// }

// doesn't work
// #[derive(TypedBuilder)]
// struct TestE<const A: usize, B> {
//     data: [u32; A],
//     data2: [B; 3],
// }

deriving on struct TestC yields this:

impl<const NUM_COLS: usize, const NUM_ROWS: usize> TestC<NUM_COLS, NUM_ROWS> {
    #[doc = "\n                Create a builder for building `TestC`.\n                On the builder, call `.data(...)` to set the values of the fields.\n                Finally, call `.build()` to create the instance of `TestC`.\n                "]
    #[allow(dead_code, clippy::default_trait_access)]
    fn builder() -> TestCBuilder<NUM_COLS, NUM_ROWS, ((),)> {
        TestCBuilder {
            fields: ((),),
            phantom: ::core::default::Default::default(),
        }
    }
}
#[must_use]
#[doc(hidden)]
#[allow(dead_code, non_camel_case_types, non_snake_case)]
struct TestCBuilder<const NUM_COLS: usize, const NUM_ROWS: usize, TypedBuilderFields = ((),)> {
    fields: TypedBuilderFields,
    phantom: ::core::marker::PhantomData<(,)>, // ERROR HERE
}
impl<const NUM_COLS: usize, const NUM_ROWS: usize, TypedBuilderFields> Clone
    for TestCBuilder<NUM_COLS, NUM_ROWS, TypedBuilderFields>
where
    TypedBuilderFields: Clone,
{
    #[allow(clippy::default_trait_access)]
    fn clone(&self) -> Self {
        Self {
            fields: self.fields.clone(),
            phantom: ::core::marker::PhantomData,
        }
    }
}
#[allow(dead_code, non_camel_case_types, missing_docs)]
impl<const NUM_COLS: usize, const NUM_ROWS: usize> TestCBuilder<NUM_COLS, NUM_ROWS, ((),)> {
    pub fn data(
        self,
        data: [[u32; NUM_ROWS]; NUM_COLS],
    ) -> TestCBuilder<NUM_COLS, NUM_ROWS, (([[u32; NUM_ROWS]; NUM_COLS],),)> {
        let data = (data,);
        let (_,) = self.fields;
        TestCBuilder {
            fields: (data,),
            phantom: self.phantom,
        }
    }
}
#[doc(hidden)]
#[allow(dead_code, non_camel_case_types, non_snake_case)]
pub enum TestCBuilder_Error_Repeated_field_data {}

#[doc(hidden)]
#[allow(dead_code, non_camel_case_types, missing_docs)]
impl<const NUM_COLS: usize, const NUM_ROWS: usize>
    TestCBuilder<NUM_COLS, NUM_ROWS, (([[u32; NUM_ROWS]; NUM_COLS],),)>
{
    #[deprecated(note = "Repeated field data")]
    pub fn data(
        self,
        _: TestCBuilder_Error_Repeated_field_data,
    ) -> TestCBuilder<NUM_COLS, NUM_ROWS, (([[u32; NUM_ROWS]; NUM_COLS],),)> {
        self
    }
}
#[doc(hidden)]
#[allow(dead_code, non_camel_case_types, non_snake_case)]
pub enum TestCBuilder_Error_Missing_required_field_data {}

#[doc(hidden)]
#[allow(dead_code, non_camel_case_types, missing_docs, clippy::panic)]
impl<const NUM_COLS: usize, const NUM_ROWS: usize> TestCBuilder<NUM_COLS, NUM_ROWS, ((),)> {
    #[deprecated(note = "Missing required field data")]
    pub fn build(self, _: TestCBuilder_Error_Missing_required_field_data) -> ! {
        panic!()
    }
}
#[allow(dead_code, non_camel_case_types, missing_docs)]
impl<const NUM_COLS: usize, const NUM_ROWS: usize>
    TestCBuilder<NUM_COLS, NUM_ROWS, (([[u32; NUM_ROWS]; NUM_COLS],),)>
{
    #[allow(clippy::default_trait_access)]
    pub fn build(self) -> TestC<NUM_COLS, NUM_ROWS> {
        let (data,) = self.fields;
        let data = data.0;
        #[allow(deprecated)]
        TestC { data }.into()
    }
}

We can see in the "ERROR HERE" comment, it generates an extra "," in the phantom which breaks everything

@awesomelemonade
Copy link
Contributor Author

Fixed with a48ed34

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant