Skip to content

Commit eab9a77

Browse files
committed
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 <[email protected]> Reviewed-by: Robert Findley <[email protected]>
1 parent d3f5cf9 commit eab9a77

File tree

4 files changed

+145
-3
lines changed

4 files changed

+145
-3
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// This file is tested when running "go test -run Manual"
6+
// without source arguments. Use for one-off debugging.
7+
8+
package p
9+
10+
import "fmt"
11+
12+
type F[A, B any] int
13+
14+
func G[A, B any](F[A, B]) {
15+
}
16+
17+
func _() {
18+
// TODO(gri) only report one error below (issue #50932)
19+
var x F /* ERROR cannot infer B */ /* ERROR got 1 arguments but 2 type parameters */ [int]
20+
G(x /* ERROR does not match */)
21+
}
22+
23+
// test case from issue
24+
// (lots of errors but doesn't crash anymore)
25+
26+
type RC[G any, RG any] interface {
27+
~[]RG
28+
}
29+
30+
type RG[G any] struct{}
31+
32+
type RSC[G any] []*RG[G]
33+
34+
type M[Rc RC[G, RG], G any, RG any] struct {
35+
Fn func(Rc)
36+
}
37+
38+
type NFn[Rc RC[G, RG], G any, RG any] func(Rc)
39+
40+
func NC[Rc RC[G, RG], G any, RG any](nFn NFn[Rc, G, RG]) {
41+
var empty Rc
42+
nFn(empty)
43+
}
44+
45+
func NSG[G any](c RSC[G]) {
46+
fmt.Println(c)
47+
}
48+
49+
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] {
50+
51+
var nFn NFn /* ERROR got 2 arguments */ /* ERROR Rc does not match */ [Rc, RG]
52+
53+
var empty Rc
54+
switch any(empty).(type) {
55+
case BC /* ERROR undeclared name: BC */ :
56+
57+
case RSC[G]:
58+
nFn = NSG /* ERROR cannot use NSG\[G\] */ [G]
59+
}
60+
61+
return M /* ERROR got 2 arguments */ [Rc, RG]{
62+
Fn: func(rc Rc) {
63+
NC(nFn /* ERROR does not match */ )
64+
},
65+
}
66+
67+
return M /* ERROR got 2 arguments */ [Rc, RG]{}
68+
}

src/cmd/compile/internal/types2/unify.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,11 +457,14 @@ func (u *unifier) nify(x, y Type, p *ifacePair) bool {
457457
xargs := x.targs.list()
458458
yargs := y.targs.list()
459459

460+
if len(xargs) != len(yargs) {
461+
return false
462+
}
463+
460464
// TODO(gri) This is not always correct: two types may have the same names
461465
// in the same package if one of them is nested in a function.
462466
// Extremely unlikely but we need an always correct solution.
463467
if x.obj.pkg == y.obj.pkg && x.obj.name == y.obj.name {
464-
assert(len(xargs) == len(yargs))
465468
for i, x := range xargs {
466469
if !u.nify(x, yargs[i], p) {
467470
return false
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// This file is tested when running "go test -run Manual"
6+
// without source arguments. Use for one-off debugging.
7+
8+
package p
9+
10+
import "fmt"
11+
12+
type F[A, B any] int
13+
14+
func G[A, B any](F[A, B]) {
15+
}
16+
17+
func _() {
18+
// TODO(gri) only report one error below (issue #50932)
19+
var x F /* ERROR cannot infer B */ /* ERROR got 1 arguments but 2 type parameters */ [int]
20+
G(x /* ERROR does not match */)
21+
}
22+
23+
// test case from issue
24+
// (lots of errors but doesn't crash anymore)
25+
26+
type RC[G any, RG any] interface {
27+
~[]RG
28+
}
29+
30+
type RG[G any] struct{}
31+
32+
type RSC[G any] []*RG[G]
33+
34+
type M[Rc RC[G, RG], G any, RG any] struct {
35+
Fn func(Rc)
36+
}
37+
38+
type NFn[Rc RC[G, RG], G any, RG any] func(Rc)
39+
40+
func NC[Rc RC[G, RG], G any, RG any](nFn NFn[Rc, G, RG]) {
41+
var empty Rc
42+
nFn(empty)
43+
}
44+
45+
func NSG[G any](c RSC[G]) {
46+
fmt.Println(c)
47+
}
48+
49+
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] {
50+
51+
var nFn NFn /* ERROR got 2 arguments */ /* ERROR Rc does not match */ [Rc, RG]
52+
53+
var empty Rc
54+
switch any(empty).(type) {
55+
case BC /* ERROR undeclared name: BC */ :
56+
57+
case RSC[G]:
58+
nFn = NSG /* ERROR cannot use NSG\[G\] */ [G]
59+
}
60+
61+
return M /* ERROR got 2 arguments */ [Rc, RG]{
62+
Fn: func(rc Rc) {
63+
NC(nFn /* ERROR does not match */ )
64+
},
65+
}
66+
67+
return M /* ERROR got 2 arguments */ [Rc, RG]{}
68+
}

src/go/types/unify.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ func (d *tparamsList) index(typ Type) int {
164164
}
165165

166166
// If tpar is a type parameter in list, tparamIndex returns the type parameter index.
167-
// Otherwise, the result is < 0. tpar must not be nil.j
167+
// Otherwise, the result is < 0. tpar must not be nil.
168168
func tparamIndex(list []*TypeParam, tpar *TypeParam) int {
169169
// Once a type parameter is bound its index is >= 0. However, there are some
170170
// 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 {
457457
xargs := x.targs.list()
458458
yargs := y.targs.list()
459459

460+
if len(xargs) != len(yargs) {
461+
return false
462+
}
463+
460464
// TODO(gri) This is not always correct: two types may have the same names
461465
// in the same package if one of them is nested in a function.
462466
// Extremely unlikely but we need an always correct solution.
463467
if x.obj.pkg == y.obj.pkg && x.obj.name == y.obj.name {
464-
assert(len(xargs) == len(yargs))
465468
for i, x := range xargs {
466469
if !u.nify(x, yargs[i], p) {
467470
return false

0 commit comments

Comments
 (0)