mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
go/types, types2: fix string to type parameter conversions
Converting an untyped constant to a type parameter results in a non-constant value; but the constant must still be representable by all specific types of the type parameter. Adjust the special handling for constant-to-type parameter conversions to also include string-to-[]byte and []rune conversions, which are handled separately for conversions to types that are not type parameters because those are not constant conversions in non-generic code. Fixes #51386. Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1 Reviewed-on: https://go-review.googlesource.com/c/go/+/388254 Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
eb8198d2f6
commit
f9285818b6
|
@ -49,11 +49,14 @@ func (check *Checker) conversion(x *operand, T Type) {
|
|||
// have specific types, constant x cannot be
|
||||
// converted.
|
||||
ok = T.(*TypeParam).underIs(func(u Type) bool {
|
||||
// t is nil if there are no specific type terms
|
||||
// u is nil if there are no specific type terms
|
||||
if u == nil {
|
||||
cause = check.sprintf("%s does not contain specific types", T)
|
||||
return false
|
||||
}
|
||||
if isString(x.typ) && isBytesOrRunes(u) {
|
||||
return true
|
||||
}
|
||||
if !constConvertibleTo(u, nil) {
|
||||
cause = check.sprintf("cannot convert %s to %s (in %s)", x, u, T)
|
||||
return false
|
||||
|
|
17
src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
vendored
Normal file
17
src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// 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.
|
||||
|
||||
package p
|
||||
|
||||
type myString string
|
||||
|
||||
func _[P ~string | ~[]byte | ~[]rune]() {
|
||||
_ = P("")
|
||||
const s myString = ""
|
||||
_ = P(s)
|
||||
}
|
||||
|
||||
func _[P myString]() {
|
||||
_ = P("")
|
||||
}
|
|
@ -48,11 +48,14 @@ func (check *Checker) conversion(x *operand, T Type) {
|
|||
// have specific types, constant x cannot be
|
||||
// converted.
|
||||
ok = T.(*TypeParam).underIs(func(u Type) bool {
|
||||
// t is nil if there are no specific type terms
|
||||
// u is nil if there are no specific type terms
|
||||
if u == nil {
|
||||
cause = check.sprintf("%s does not contain specific types", T)
|
||||
return false
|
||||
}
|
||||
if isString(x.typ) && isBytesOrRunes(u) {
|
||||
return true
|
||||
}
|
||||
if !constConvertibleTo(u, nil) {
|
||||
cause = check.sprintf("cannot convert %s to %s (in %s)", x, u, T)
|
||||
return false
|
||||
|
|
17
src/go/types/testdata/fixedbugs/issue51386.go2
vendored
Normal file
17
src/go/types/testdata/fixedbugs/issue51386.go2
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// 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.
|
||||
|
||||
package p
|
||||
|
||||
type myString string
|
||||
|
||||
func _[P ~string | ~[]byte | ~[]rune]() {
|
||||
_ = P("")
|
||||
const s myString = ""
|
||||
_ = P(s)
|
||||
}
|
||||
|
||||
func _[P myString]() {
|
||||
_ = P("")
|
||||
}
|
Loading…
Reference in a new issue