awalterschulze / goderive

Derives and generates mundane golang functions that you do not want to maintain yourself
Apache License 2.0
1.23k stars 44 forks source link

`Equal` generation requires pointer types to be generated correctly #81

Open jamietanna opened 1 year ago

jamietanna commented 1 year ago

Following the example code on the README:

type MyStruct struct {
    Int64     int64
    StringPtr *string
}

func (this *MyStruct) Equal(that *MyStruct) bool {
    return deriveEqual(this, that)
}

// alternatively
func (this MyStruct) Equal(that MyStruct) bool {
    return deriveEqual(&this, &that)
}

Results in:

func deriveEqual(this, that *MyStruct) bool {
    return (this == nil && that == nil) ||
        this != nil && that != nil &&
            this.Int64 == that.Int64 &&
            ((this.StringPtr == nil && that.StringPtr == nil) || (this.StringPtr != nil && that.StringPtr != nil && *(this.StringPtr) == *(that.StringPtr)))
}

However, when this uses a non-pointer receiver:

func (this MyStruct) Equal(that MyStruct) bool {
    return deriveEqual(this, that)
}

This generates:

func deriveEqual(this, that MyStruct) bool {
    return ((&this == nil && &that == nil) || (&this != nil && &that != nil && (*(&this)).Equal(*(&that))))
}

Which doesn't perform the same checks?

awalterschulze commented 1 year ago

Still technically correct, but you are right, we could do better here, by not doing the checks

dimovnike commented 9 months ago

Doesn't seem even technically correct because it causes infinite recursion and a stack overflow.