Skip to content

Generic components require generic types to be PartialEq #8

@kirillsemyonkin

Description

@kirillsemyonkin

#[derive] is not perfect (funnily enough, I wrote this before I found the Rust blog quotation, where they mention it being "Perfect derive"), and Rust generates impls with that derived trait also present for generic parameters (e.g. derive(Clone) does impl<T: Clone> Clone for ...). This would happen even for instances when the requirement for the generic parameter is not required (e.g. an Rc<T> field means the struct does not actually require Clone on T).

yew-autoprops does #[derive(PartialEq)], which means when generating impls Rust will place such a requirement on the generic parameters as well. This means following example will not be valid:

#[autoprops_component]
pub fn Example<T>(something: Rc<T>) {
    html! {}
}

As it comes up with the following error:

can't compare `T` with `T`
no implementation for `T == T`
- required for `ExampleProps<T>` to implement `PartialEq`
- required by a bound in `Properties`
- consider further restricting type parameter `T`: `, T: std::cmp::PartialEq`

As all props fields are probably expected to be PartialEq (which isn't always the case with derive), I suggest manually implementing PartialEq for the props struct, containing comparisons for all the fields:

impl<T> PartialEq for ExampleProps<T> {
    fn eq(&self, other: &Self) -> bool {
        #pats_modified_1 = self; // adds _1 to each field, you also have to check that no name ends with _1/_2, otherwise add more underscores i guess
        #pats_modified_2 = other; // adds _2 to each field
        #comparisons // prop_1 == prop_2 && another_prop_1 == another_prop_2 && ...
    }
}

For generic parameters that are to be used directly as a type of a prop field, the user will have to declare them as PartialEq, which is the case for both derive and manual impl solutions.

This is a breaking problem (you cannot implement a custom PartialEq, unlike with non-autoprops props), and fixing it would improve experience of using generics by a lot compared to non-autoprops components.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions