]> Cypherpunks.ru repositories - gostls13.git/commitdiff
go/types: document that predicates are undefined on generic types
authorRobert Findley <rfindley@google.com>
Fri, 4 Mar 2022 19:39:43 +0000 (14:39 -0500)
committerRobert Findley <rfindley@google.com>
Mon, 7 Mar 2022 20:22:24 +0000 (20:22 +0000)
Fixes #50887

Change-Id: I451d66b067badcfb7cf2e2756ea2b062366ac9d4
Reviewed-on: https://go-review.googlesource.com/c/go/+/390039
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/types2/api.go
src/go/types/api.go

index 6230c58401ad39938fbf902187ae171429a4516b..584f613a64282cccefe29ac68618f7c7c4e73060 100644 (file)
@@ -421,8 +421,11 @@ 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 if V is a generalized interface; i.e.,
-// an interface that may only be used as a type constraint in Go code.
+//
+// The behavior of AssertableTo is undefined in two cases:
+//  - 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
 func AssertableTo(V *Interface, T Type) bool {
        // Checker.newAssertableTo suppresses errors for invalid types, so we need special
        // handling here.
@@ -432,20 +435,31 @@ func AssertableTo(V *Interface, T Type) bool {
        return (*Checker)(nil).newAssertableTo(V, T) == nil
 }
 
-// AssignableTo reports whether a value of type V is assignable to a variable of type T.
+// 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.
 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
        return ok
 }
 
-// ConvertibleTo reports whether a value of type V is convertible to a value of type T.
+// 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.
 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
 }
 
 // Implements reports whether type V implements interface T.
+//
+// The behavior of Implements is undefined if V is an uninstantiated generic
+// type.
 func Implements(V Type, T *Interface) bool {
        if T.Empty() {
                // All types (even Typ[Invalid]) implement the empty interface.
index 828461477b91013ab230888b598311afdf980354..86a03eba31f7b14f6e9d1afa1dc919fd0994a9ba 100644 (file)
@@ -417,8 +417,11 @@ 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 if V is a generalized interface; i.e.,
-// an interface that may only be used as a type constraint in Go code.
+//
+// The behavior of AssertableTo is undefined in two cases:
+//  - 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
 func AssertableTo(V *Interface, T Type) bool {
        // Checker.newAssertableTo suppresses errors for invalid types, so we need special
        // handling here.
@@ -428,20 +431,31 @@ func AssertableTo(V *Interface, T Type) bool {
        return (*Checker)(nil).newAssertableTo(V, T) == nil
 }
 
-// AssignableTo reports whether a value of type V is assignable to a variable of type T.
+// 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.
 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
        return ok
 }
 
-// ConvertibleTo reports whether a value of type V is convertible to a value of type T.
+// 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.
 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
 }
 
 // Implements reports whether type V implements interface T.
+//
+// The behavior of Implements is undefined if V is an uninstantiated generic
+// type.
 func Implements(V Type, T *Interface) bool {
        if T.Empty() {
                // All types (even Typ[Invalid]) implement the empty interface.