maxbrunsfeld/counterfeiter

Go 1.18 generics

cipriantarta opened this issue · 8 comments

First of all, love your library.
I was wondering if you plan on supporting the go 1.18 generics in the near future.

I'm happy to help if you give me some pointers on guidance on how you would approach this

I want to follow-up this issue in case there is a plan for supporting go 1.18 generics.

I'm currently encountering problems with counterfeit as it does't identifying any as a valid type.

cannot use tx (variable of type *"database/sql".Tx) as outbox.SQLDBOrTx value in argument to s.notifyClearanceUpdate: wrong type for method ExecContext (have func(ctx context.Context, query string, args ...invalid type) (database/sql.Result, error), want func(ctx context.Context, query string, args ...interface{}) (database/sql.Result, error))

After looking deeper in the code, I realized that the library uses go/types for type definition. In the end, my problem was fixed by reinstalling counterfeiter using Go 1.18

hey @hleonps , were you able to generate mocks for any interface using generics? If yes, let me know how that worked.

@chattarajoy My problem came with counterfeiter not recognizing any as an valid type while creating the mocks. It wasn't an interface with generics syntax. Just in case, it was because I go install counterfeiter with 1.17 some months ago, and when I tried to use that binary, of course it couldn't identify any as valid. Re-running go install (now using 1.18) fixed it.

The original poster of this issue seemed only to have a problem with considering any to be a valid type, but counterfeiter mocks definitely do not appear to support generic interfaces. We need a syntax to tell counterfeiter to generate a mock for a generic interface for a concrete type or types. Something along the lines of this:

//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate

//counterfeiter:generate . MyInterface[string, int],MyInterface[uint32, any]

type MyInterface[T any, U any] {
    SomeFunction(arg T) (U, error)
}

It defnitely does not work, currently, since it attempts to create a filename that includes the generic type specifiers between square brackets, nor can you specify multiple mocks in a single line like in my example.

Right it doesn't work for generic interfaces as of now.

For the record, while it doesn't generate generic interfaces, the underlying generated code is perfectly compatible with generics. I just manually added a generic type specifier to an already-generated mock and everything worked just fine. It seems that all it needs is an understanding of the syntax and the ability to generate mocks using the syntax.

Gentle bump here. This is going to be the slow death of this library if not fixed :).

I'm open to a PR! I just haven't written any code yet that requires this, making it hard to prioritize.