mirror of
https://github.com/golang/go
synced 2024-11-11 22:20:22 -07:00
go/types: slice-to-array-pointer conversion requires go1.17
This is a port of CL 315169 to go/types. It uses a slightly different mechanism for evaluating the convertibility error message, to be consistent with operand.assignableTo. Change-Id: Iea2e2a9fbb4cf17d472b2b7392786118e079528a Reviewed-on: https://go-review.googlesource.com/c/go/+/315809 Trust: Robert Findley <rfindley@google.com> Run-TryBot: Robert Findley <rfindley@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
parent
8e91458b19
commit
ffc38d8ab4
@ -406,7 +406,7 @@ func AssignableTo(V, T Type) bool {
|
||||
// ConvertibleTo reports whether a value of type V is convertible to a value of type T.
|
||||
func ConvertibleTo(V, T Type) bool {
|
||||
x := operand{mode: value, typ: V}
|
||||
return x.convertibleTo(nil, T) // check not needed for non-constant x
|
||||
return x.convertibleTo(nil, T, nil) // check not needed for non-constant x
|
||||
}
|
||||
|
||||
// Implements reports whether type V implements interface T.
|
||||
|
@ -17,6 +17,7 @@ func (check *Checker) conversion(x *operand, T Type) {
|
||||
constArg := x.mode == constant_
|
||||
|
||||
var ok bool
|
||||
var reason string
|
||||
switch {
|
||||
case constArg && isConstType(T):
|
||||
// constant conversion
|
||||
@ -31,14 +32,18 @@ func (check *Checker) conversion(x *operand, T Type) {
|
||||
x.val = constant.MakeString(string(codepoint))
|
||||
ok = true
|
||||
}
|
||||
case x.convertibleTo(check, T):
|
||||
case x.convertibleTo(check, T, &reason):
|
||||
// non-constant conversion
|
||||
x.mode = value
|
||||
ok = true
|
||||
}
|
||||
|
||||
if !ok {
|
||||
check.errorf(x, _InvalidConversion, "cannot convert %s to %s", x, T)
|
||||
if reason != "" {
|
||||
check.errorf(x, _InvalidConversion, "cannot convert %s to %s (%s)", x, T, reason)
|
||||
} else {
|
||||
check.errorf(x, _InvalidConversion, "cannot convert %s to %s", x, T)
|
||||
}
|
||||
x.mode = invalid
|
||||
return
|
||||
}
|
||||
@ -79,7 +84,7 @@ func (check *Checker) conversion(x *operand, T Type) {
|
||||
// convertibleTo reports whether T(x) is valid.
|
||||
// The check parameter may be nil if convertibleTo is invoked through an
|
||||
// exported API call, i.e., when all methods have been type-checked.
|
||||
func (x *operand) convertibleTo(check *Checker, T Type) bool {
|
||||
func (x *operand) convertibleTo(check *Checker, T Type, reason *string) bool {
|
||||
// "x is assignable to T"
|
||||
if ok, _ := x.assignableTo(check, T, nil); ok {
|
||||
return true
|
||||
@ -139,7 +144,12 @@ func (x *operand) convertibleTo(check *Checker, T Type) bool {
|
||||
if p := asPointer(T); p != nil {
|
||||
if a := asArray(p.Elem()); a != nil {
|
||||
if check.identical(s.Elem(), a.Elem()) {
|
||||
return true
|
||||
if check == nil || check.allowVersion(check.pkg, 1, 17) {
|
||||
return true
|
||||
}
|
||||
if reason != nil {
|
||||
*reason = "conversion of slices to array pointers requires go1.17 or later"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -655,7 +655,7 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) {
|
||||
|
||||
if alias {
|
||||
// type alias declaration
|
||||
if !check.allowVersion(obj.pkg, 1, 9) {
|
||||
if !check.allowVersion(check.pkg, 1, 9) {
|
||||
check.errorf(atPos(tdecl.Assign), _BadDecl, "type aliases requires go1.9 or later")
|
||||
}
|
||||
|
||||
|
13
src/go/types/testdata/check/go1_16.src
vendored
Normal file
13
src/go/types/testdata/check/go1_16.src
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
// Check Go language version-specific errors.
|
||||
|
||||
package go1_16 // go1.16
|
||||
|
||||
type Slice []byte
|
||||
type Array [8]byte
|
||||
|
||||
var s Slice
|
||||
var p = (*Array)(s /* ERROR requires go1.17 or later */ )
|
Loading…
Reference in New Issue
Block a user