golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.72k stars 17.5k forks source link

cmd/go2go: cannot use x (variable of type X(T)) as X(T) value in assignment #40300

Closed Merovius closed 2 years ago

Merovius commented 4 years ago

What did you do?

Tried to compile this program (playground link):

type A(type T) struct {
    x X(T)
}

func F(type T)(x X(T)) {
    var a A(T)
    a.x = x
}

type X(type T) func(y Y(T))

type Y(type T) func(a *A(T))

What did you expect to see?

No output, as in this program (playground link):

type A(type T) struct {
    x X(T)
}

func F(type T)(x X(T)) {
    var a A(T)
    a.x = x
}

type X(type T) func(y func(a *A(T)))

type Y(type T) func(a *A(T))

What did you see instead?

Compiler error:

type checking failed for main prog.go2:12:8: cannot use x (variable of type X(T)) as X(T) value in assignment


I tried to minimize the code as much as possible, that's why the original intent is a bit obscured.

I suspect that this is a bug in the prototype - at least I see no reason why it would work with func(*A(T)), but not with Y(T). I thought it might be an issue with recursive generic types (A(T) mentions X(T) mentions Y(T) mentions A(T)), but it should fulfill the requirement of only mentioning the original parameters in the same order. And I wouldn't understand why the error is reported in the assignment and why it vanishes when you delete that. In any case, the error message is, of course, not super helpful :)

I'd be interested to know if this is WAI or a limitation of the prototype.

ianlancetaylor commented 4 years ago

CC @griesemer

Appears to be a problem in the type checker. It seems like this should work; if it doesn't work, it definitely needs a better error message.

griesemer commented 4 years ago

This appears to be an evaluation/type-checking ordering problem caused by the mutually referencing types. Moving the declaration of type Y to the beginning "solves" the problem: https://go2goplay.golang.org/p/h4tcdkyvm2N .

This (and related issues) require some significant re-engineering of the type-checker. Probably won't address in the prototype, in favor of spending engineering effort on a real implementation. Leaving open so we have a test case.

Merovius commented 2 years ago

Not only does the prototype no longer matter, this also build now, so closing.