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

Using default generic parameter types for skippable fields #198

Closed
srithon opened this issue Feb 14, 2021 · 1 comment
Closed

Using default generic parameter types for skippable fields #198

srithon opened this issue Feb 14, 2021 · 1 comment

Comments

@srithon
Copy link

srithon commented Feb 14, 2021

In a project I'm working on, I have an immutable buildable struct that contains an optional generic field. When this field is not set, the compiler throws an error because it cannot infer its type.

However, since the struct is immutable, this field would stay None forever, meaning that its corresponding type would not be relevant. I attempted to fix this by giving it a Default Generic Type Parameter with a throwaway type, but it did not work as I expected.

This is a minimal example of the issue.

I set the placeholder type to Vec<String> because in my project the type of B has bounds which prevent it from being ().

use derive_builder::Builder;

#[derive(Builder)]
struct GenericStruct<A, B = Vec<String>> {
    required_field: A,

    #[builder(setter(strip_option), default)]
    optional_field: Option<B>
}

fn main() {
    let a = GenericStructBuilder::default()
        .optional_field(30)
        .required_field("hello")
        .build();

    // **Error**
    let b = GenericStructBuilder::default()
        .required_field("hello")
        .build();
}
error[E0282]: type annotations needed for `std::result::Result<GenericStruct<&str, B>, String>`
  --> src/main.rs:18:13
   |
18 |     let b = GenericStructBuilder::default()
   |         -   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `B` declared on the struct `GenericStructBuilder`
   |         |
   |         consider giving `b` the explicit type `std::result::Result<GenericStruct<&str, B>, String>`, where the type parameter `B` is specified

Potential User Workarounds

  1. Remove strip_option and default, and make users explicitly pass in Option::<()>::None to the setter
  2. Something with Box?

Potential Crate Solutions

  1. Internally use workaround Add MIT/Apache2 License, Readme #1 before build() to set the type

Other Notes

Resources

@TedDriggs
Copy link
Collaborator

I'm not sure there's anything this crate can do, I'm afraid.

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

2 participants