1
0
mirror of https://github.com/golang/go synced 2024-11-25 23:58:02 -07:00

go/types, types2: unalias tilde terms in underIs

Unalias the ~T terms during underIs. Before, if T was an alias
of U, it may pass T to the iteration function. The iterator
function expects an underlying type, under(U), to be passed.
This caused several bugs where underIs is used without
eventually taking the underlying type.

Updates #68935
Fixes #68903

Change-Id: Ie8691d8dddaea00e1dcba94d17c0f1b021fc49a2
Reviewed-on: https://go-review.googlesource.com/c/go/+/606075
Reviewed-by: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
Tim King 2024-08-15 16:48:42 -07:00
parent 6fb6ace308
commit 1a90dcdaaf
4 changed files with 54 additions and 4 deletions

View File

@ -131,8 +131,8 @@ func (s *_TypeSet) underIs(f func(Type) bool) bool {
} }
for _, t := range s.terms { for _, t := range s.terms {
assert(t.typ != nil) assert(t.typ != nil)
// x == under(x) for ~x terms // Unalias(x) == under(x) for ~x terms
u := t.typ u := Unalias(t.typ)
if !t.tilde { if !t.tilde {
u = under(u) u = under(u)
} }

View File

@ -134,8 +134,8 @@ func (s *_TypeSet) underIs(f func(Type) bool) bool {
} }
for _, t := range s.terms { for _, t := range s.terms {
assert(t.typ != nil) assert(t.typ != nil)
// x == under(x) for ~x terms // Unalias(x) == under(x) for ~x terms
u := t.typ u := Unalias(t.typ)
if !t.tilde { if !t.tilde {
u = under(u) u = under(u)
} }

View File

@ -0,0 +1,24 @@
// Copyright 2024 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.
package p
type A = [4]int
type B = map[string]interface{}
func _[T ~A](x T) {
_ = len(x)
}
func _[U ~A](x U) {
_ = cap(x)
}
func _[V ~A]() {
_ = V{}
}
func _[W ~B](a interface{}) {
_ = a.(W)["key"]
}

View File

@ -0,0 +1,26 @@
// Copyright 2024 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.
package p
type A = struct {
F string
G int
}
func Make[T ~A]() T {
return T{
F: "blah",
G: 1234,
}
}
type N struct {
F string
G int
}
func _() {
_ = Make[N]()
}