From c847a2c9f024f47eee25c132f2d80e7037adea36 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Thu, 30 Jun 2022 16:41:31 -0700 Subject: [PATCH] go/types, types2: document that exported predicates are unspecified for invalid type arguments Per discussion on the issue. For #53595. Change-Id: Iefd161e5c7e792d454652cbe831a0c2d769f748e Reviewed-on: https://go-review.googlesource.com/c/go/+/415574 Reviewed-by: Robert Findley Reviewed-by: Robert Griesemer Reviewed-by: Ian Lance Taylor --- src/cmd/compile/internal/types2/api.go | 15 ++++++++------- src/go/types/api.go | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/cmd/compile/internal/types2/api.go b/src/cmd/compile/internal/types2/api.go index a22ea5d12fc..94c290b9ee7 100644 --- a/src/cmd/compile/internal/types2/api.go +++ b/src/cmd/compile/internal/types2/api.go @@ -418,7 +418,8 @@ func (conf *Config) Check(path string, files []*syntax.File, info *Info) (*Packa // AssertableTo reports whether a value of type V can be asserted to have type T. // -// The behavior of AssertableTo is undefined in two cases: +// The behavior of AssertableTo is unspecified in three cases: +// - if T is Typ[Invalid] // - if V is a generalized interface; i.e., an interface that may only be used // as a type constraint in Go code // - if T is an uninstantiated generic type @@ -434,8 +435,8 @@ func AssertableTo(V *Interface, T Type) bool { // AssignableTo reports whether a value of type V is assignable to a variable // of type T. // -// The behavior of AssignableTo is undefined if V or T is an uninstantiated -// generic type. +// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an +// uninstantiated generic type. func AssignableTo(V, T Type) bool { x := operand{mode: value, typ: V} ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x @@ -445,8 +446,8 @@ func AssignableTo(V, T Type) bool { // ConvertibleTo reports whether a value of type V is convertible to a value of // type T. // -// The behavior of ConvertibleTo is undefined if V or T is an uninstantiated -// generic type. +// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an +// uninstantiated generic type. func ConvertibleTo(V, T Type) bool { x := operand{mode: value, typ: V} return x.convertibleTo(nil, T, nil) // check not needed for non-constant x @@ -454,8 +455,8 @@ func ConvertibleTo(V, T Type) bool { // Implements reports whether type V implements interface T. // -// The behavior of Implements is undefined if V is an uninstantiated generic -// type. +// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated +// generic type. func Implements(V Type, T *Interface) bool { if T.Empty() { // All types (even Typ[Invalid]) implement the empty interface. diff --git a/src/go/types/api.go b/src/go/types/api.go index 0915d6a6eee..5e7be29b3ca 100644 --- a/src/go/types/api.go +++ b/src/go/types/api.go @@ -413,7 +413,8 @@ func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, i // AssertableTo reports whether a value of type V can be asserted to have type T. // -// The behavior of AssertableTo is undefined in two cases: +// The behavior of AssertableTo is unspecified in three cases: +// - if T is Typ[Invalid] // - if V is a generalized interface; i.e., an interface that may only be used // as a type constraint in Go code // - if T is an uninstantiated generic type @@ -429,8 +430,8 @@ func AssertableTo(V *Interface, T Type) bool { // AssignableTo reports whether a value of type V is assignable to a variable // of type T. // -// The behavior of AssignableTo is undefined if V or T is an uninstantiated -// generic type. +// The behavior of AssignableTo is unspecified if V or T is Typ[Invalid] or an +// uninstantiated generic type. func AssignableTo(V, T Type) bool { x := operand{mode: value, typ: V} ok, _ := x.assignableTo(nil, T, nil) // check not needed for non-constant x @@ -440,8 +441,8 @@ func AssignableTo(V, T Type) bool { // ConvertibleTo reports whether a value of type V is convertible to a value of // type T. // -// The behavior of ConvertibleTo is undefined if V or T is an uninstantiated -// generic type. +// The behavior of ConvertibleTo is unspecified if V or T is Typ[Invalid] or an +// uninstantiated generic type. func ConvertibleTo(V, T Type) bool { x := operand{mode: value, typ: V} return x.convertibleTo(nil, T, nil) // check not needed for non-constant x @@ -449,8 +450,8 @@ func ConvertibleTo(V, T Type) bool { // Implements reports whether type V implements interface T. // -// The behavior of Implements is undefined if V is an uninstantiated generic -// type. +// The behavior of Implements is unspecified if V is Typ[Invalid] or an uninstantiated +// generic type. func Implements(V Type, T *Interface) bool { if T.Empty() { // All types (even Typ[Invalid]) implement the empty interface.