mirror of
https://github.com/golang/go
synced 2024-11-26 16:16:57 -07:00
go/types, types2: fix unification code for defined types
Fixes #50929. Change-Id: I65b8eaf5e4b423839bc53c7b1db3679961498c8a Reviewed-on: https://go-review.googlesource.com/c/go/+/382076 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
d3f5cf9d28
commit
eab9a77a60
68
src/cmd/compile/internal/types2/testdata/fixedbugs/issue50929.go2
vendored
Normal file
68
src/cmd/compile/internal/types2/testdata/fixedbugs/issue50929.go2
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is tested when running "go test -run Manual"
|
||||
// without source arguments. Use for one-off debugging.
|
||||
|
||||
package p
|
||||
|
||||
import "fmt"
|
||||
|
||||
type F[A, B any] int
|
||||
|
||||
func G[A, B any](F[A, B]) {
|
||||
}
|
||||
|
||||
func _() {
|
||||
// TODO(gri) only report one error below (issue #50932)
|
||||
var x F /* ERROR cannot infer B */ /* ERROR got 1 arguments but 2 type parameters */ [int]
|
||||
G(x /* ERROR does not match */)
|
||||
}
|
||||
|
||||
// test case from issue
|
||||
// (lots of errors but doesn't crash anymore)
|
||||
|
||||
type RC[G any, RG any] interface {
|
||||
~[]RG
|
||||
}
|
||||
|
||||
type RG[G any] struct{}
|
||||
|
||||
type RSC[G any] []*RG[G]
|
||||
|
||||
type M[Rc RC[G, RG], G any, RG any] struct {
|
||||
Fn func(Rc)
|
||||
}
|
||||
|
||||
type NFn[Rc RC[G, RG], G any, RG any] func(Rc)
|
||||
|
||||
func NC[Rc RC[G, RG], G any, RG any](nFn NFn[Rc, G, RG]) {
|
||||
var empty Rc
|
||||
nFn(empty)
|
||||
}
|
||||
|
||||
func NSG[G any](c RSC[G]) {
|
||||
fmt.Println(c)
|
||||
}
|
||||
|
||||
func MMD[Rc RC /* ERROR cannot infer RG */ /* ERROR got 1 arguments */ [RG], RG any, G any]() M /* ERROR got 2 arguments */ /* ERROR Rc does not match */ [Rc, RG] {
|
||||
|
||||
var nFn NFn /* ERROR got 2 arguments */ /* ERROR Rc does not match */ [Rc, RG]
|
||||
|
||||
var empty Rc
|
||||
switch any(empty).(type) {
|
||||
case BC /* ERROR undeclared name: BC */ :
|
||||
|
||||
case RSC[G]:
|
||||
nFn = NSG /* ERROR cannot use NSG\[G\] */ [G]
|
||||
}
|
||||
|
||||
return M /* ERROR got 2 arguments */ [Rc, RG]{
|
||||
Fn: func(rc Rc) {
|
||||
NC(nFn /* ERROR does not match */ )
|
||||
},
|
||||
}
|
||||
|
||||
return M /* ERROR got 2 arguments */ [Rc, RG]{}
|
||||
}
|
@ -457,11 +457,14 @@ func (u *unifier) nify(x, y Type, p *ifacePair) bool {
|
||||
xargs := x.targs.list()
|
||||
yargs := y.targs.list()
|
||||
|
||||
if len(xargs) != len(yargs) {
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO(gri) This is not always correct: two types may have the same names
|
||||
// in the same package if one of them is nested in a function.
|
||||
// Extremely unlikely but we need an always correct solution.
|
||||
if x.obj.pkg == y.obj.pkg && x.obj.name == y.obj.name {
|
||||
assert(len(xargs) == len(yargs))
|
||||
for i, x := range xargs {
|
||||
if !u.nify(x, yargs[i], p) {
|
||||
return false
|
||||
|
68
src/go/types/testdata/fixedbugs/issue50929.go2
vendored
Normal file
68
src/go/types/testdata/fixedbugs/issue50929.go2
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file is tested when running "go test -run Manual"
|
||||
// without source arguments. Use for one-off debugging.
|
||||
|
||||
package p
|
||||
|
||||
import "fmt"
|
||||
|
||||
type F[A, B any] int
|
||||
|
||||
func G[A, B any](F[A, B]) {
|
||||
}
|
||||
|
||||
func _() {
|
||||
// TODO(gri) only report one error below (issue #50932)
|
||||
var x F /* ERROR cannot infer B */ /* ERROR got 1 arguments but 2 type parameters */ [int]
|
||||
G(x /* ERROR does not match */)
|
||||
}
|
||||
|
||||
// test case from issue
|
||||
// (lots of errors but doesn't crash anymore)
|
||||
|
||||
type RC[G any, RG any] interface {
|
||||
~[]RG
|
||||
}
|
||||
|
||||
type RG[G any] struct{}
|
||||
|
||||
type RSC[G any] []*RG[G]
|
||||
|
||||
type M[Rc RC[G, RG], G any, RG any] struct {
|
||||
Fn func(Rc)
|
||||
}
|
||||
|
||||
type NFn[Rc RC[G, RG], G any, RG any] func(Rc)
|
||||
|
||||
func NC[Rc RC[G, RG], G any, RG any](nFn NFn[Rc, G, RG]) {
|
||||
var empty Rc
|
||||
nFn(empty)
|
||||
}
|
||||
|
||||
func NSG[G any](c RSC[G]) {
|
||||
fmt.Println(c)
|
||||
}
|
||||
|
||||
func MMD[Rc RC /* ERROR cannot infer RG */ /* ERROR got 1 arguments */ [RG], RG any, G any]() M /* ERROR got 2 arguments */ /* ERROR Rc does not match */ [Rc, RG] {
|
||||
|
||||
var nFn NFn /* ERROR got 2 arguments */ /* ERROR Rc does not match */ [Rc, RG]
|
||||
|
||||
var empty Rc
|
||||
switch any(empty).(type) {
|
||||
case BC /* ERROR undeclared name: BC */ :
|
||||
|
||||
case RSC[G]:
|
||||
nFn = NSG /* ERROR cannot use NSG\[G\] */ [G]
|
||||
}
|
||||
|
||||
return M /* ERROR got 2 arguments */ [Rc, RG]{
|
||||
Fn: func(rc Rc) {
|
||||
NC(nFn /* ERROR does not match */ )
|
||||
},
|
||||
}
|
||||
|
||||
return M /* ERROR got 2 arguments */ [Rc, RG]{}
|
||||
}
|
@ -164,7 +164,7 @@ func (d *tparamsList) index(typ Type) int {
|
||||
}
|
||||
|
||||
// If tpar is a type parameter in list, tparamIndex returns the type parameter index.
|
||||
// Otherwise, the result is < 0. tpar must not be nil.j
|
||||
// Otherwise, the result is < 0. tpar must not be nil.
|
||||
func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
|
||||
// Once a type parameter is bound its index is >= 0. However, there are some
|
||||
// code paths (namely tracing and type hashing) by which it is possible to
|
||||
@ -457,11 +457,14 @@ func (u *unifier) nify(x, y Type, p *ifacePair) bool {
|
||||
xargs := x.targs.list()
|
||||
yargs := y.targs.list()
|
||||
|
||||
if len(xargs) != len(yargs) {
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO(gri) This is not always correct: two types may have the same names
|
||||
// in the same package if one of them is nested in a function.
|
||||
// Extremely unlikely but we need an always correct solution.
|
||||
if x.obj.pkg == y.obj.pkg && x.obj.name == y.obj.name {
|
||||
assert(len(xargs) == len(yargs))
|
||||
for i, x := range xargs {
|
||||
if !u.nify(x, yargs[i], p) {
|
||||
return false
|
||||
|
Loading…
Reference in New Issue
Block a user