Go: cmd/go2go: constraints on type arguments appear to be ignored when validating other constraint arguments on functions

Created on 21 Jun 2020  路  5Comments  路  Source: golang/go

What version of Go are you using (go version)?

Verified on the dev.go2go branch

$ go version
% bin/go version
go version devel +0a030888da Sat Jun 20 04:46:40 2020 +0000 linux/amd64

Does this issue reproduce with the latest release?

Not in a release as it's on the `dev.go2go branch.

Also present in the go2go playground (currently version devel +5f01333bf1 Wed Jun 17 04:20:54 2020 +0000.)

What operating system and processor architecture are you using (go env)?

LInux AMD64, but also the go2go playground

What did you do?

package main

type MapSliceConstraint(type K comparable, V interface{}) interface {
    type map[K]V, []V
}

func genLen(type T MapSliceConstraint(K, V), K comparable, V interface{})(collection T) int {
    return len(collection)
}

https://go2goplay.golang.org/p/1gqiYuDELuI (trimmed)
https://go2goplay.golang.org/p/qcdfl0tuHlb (with a main)

What did you expect to see?

Compiling and printing:

len map: 1
len slice: 2

What did you see instead?

% go tool go2go run fim.go2
type checking failed for main
/tmp/go2go-run155966463/fim.go2:11:39: K does not satisfy comparable

(same error on either of the go2go playground links above)

NeedsInvestigation

Most helpful comment

func genLen(type K comparable, V interface{}, T MapSliceConstraint(K, V))(collection T) int
instead of
func genLen(type T MapSliceConstraint(K, V), K comparable, V interface{})(collection T) int

https://go2goplay.golang.org/p/zpEMFBQSep-
works correctly.

All 5 comments

func genLen(type K comparable, V interface{}, T MapSliceConstraint(K, V))(collection T) int
instead of
func genLen(type T MapSliceConstraint(K, V), K comparable, V interface{})(collection T) int

https://go2goplay.golang.org/p/zpEMFBQSep-
works correctly.

This seems to be an error in the type checker.

At the very least the error message is wrong, as K is constrained to satisfy comparable.

It's a phase-ordering issue. We know that we have several of those and fixing them will require a fairly substantial rewrite of the core of the type checker which we didn't attempt yet since this is a prototype.

(Both go/types, but also the compiler, have some of these phase-ordering issues with type-checking, due to the "eager" approach of type-checking. For regular Go, these issues mostly appear for corner-case scenarios. Unfortunately, with generics, correct phase-ordering has become paramount.)

This is another simpler case for this bug (I think): https://go2goplay.golang.org/p/6Dqyz11MnFA

func Max(type T comparable)(slice []T) T {
    m := slice[0]
    for i := 1; i < len(slice); i++ {
        if v:= slice[i]; v > m { // ERROR: cannot compare v > m (operator > not defined for T)
            m = v
        }
    }
    return m
}

@OneOfOne The test case in https://github.com/golang/go/issues/39733#issuecomment-648876070 isn't valid: comparable permits == and !=, it doesn't permit >.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bbodenmiller picture bbodenmiller  路  3Comments

Miserlou picture Miserlou  路  3Comments

jayhuang75 picture jayhuang75  路  3Comments

dominikh picture dominikh  路  3Comments

natefinch picture natefinch  路  3Comments