1
0
mirror of https://github.com/golang/go synced 2024-11-17 14:04:48 -07:00

go/types, types2: remove uses of "type list" and "operational type" (cleanup)

Fixes #49193.

Change-Id: Ief31ea6b3dddf9452efb94763c89b8639aa3ce9e
Reviewed-on: https://go-review.googlesource.com/c/go/+/394656
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Robert Griesemer 2022-03-22 12:49:09 -07:00
parent fd1b5904ae
commit 1e34c00b4c
8 changed files with 47 additions and 49 deletions

View File

@ -85,7 +85,7 @@ type Setter[B any] interface {
func FromStrings[T interface{}, PT Setter[T]](s []string) []T { func FromStrings[T interface{}, PT Setter[T]](s []string) []T {
result := make([]T, len(s)) result := make([]T, len(s))
for i, v := range s { for i, v := range s {
// The type of &result[i] is *T which is in the type list // The type of &result[i] is *T which is in the type set
// of Setter, so we can convert it to PT. // of Setter, so we can convert it to PT.
p := PT(&result[i]) p := PT(&result[i])
// PT has a Set method. // PT has a Set method.

View File

@ -51,9 +51,8 @@ func _() {
} }
// When a type parameter is used as an argument to instantiate a parameterized // When a type parameter is used as an argument to instantiate a parameterized
// type with a type list constraint, all of the type argument's types in its // type, the type argument's type set must be a subset of the instantiated type
// bound, but at least one (!), must be in the type list of the bound of the // parameter's type set.
// corresponding parameterized type's type parameter.
type T1[P interface{~uint}] struct{} type T1[P interface{~uint}] struct{}
func _[P any]() { func _[P any]() {
@ -150,7 +149,7 @@ type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }
// The implementation of conversions T(x) between integers and floating-point // The implementation of conversions T(x) between integers and floating-point
// numbers checks that both T and x have either integer or floating-point // numbers checks that both T and x have either integer or floating-point
// type. When the type of T or x is a type parameter, the respective simple // type. When the type of T or x is a type parameter, the respective simple
// predicate disjunction in the implementation was wrong because if a type list // predicate disjunction in the implementation was wrong because if a type set
// contains both an integer and a floating-point type, the type parameter is // contains both an integer and a floating-point type, the type parameter is
// neither an integer or a floating-point number. // neither an integer or a floating-point number.
func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 { func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
@ -183,14 +182,12 @@ func _[T interface{}, PT interface{~*T}] (x T) PT {
return &x return &x
} }
// Indexing of generic types containing type parameters in their type list: // Indexing of type parameters containing type parameters in their constraint terms:
func at[T interface{ ~[]E }, E interface{}](x T, i int) E { func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
return x[i] return x[i]
} }
// A generic type inside a function acts like a named type. Its underlying // Conversion of a local type to a type parameter.
// type is itself, its "operational type" is defined by the type list in
// the tybe bound, if any.
func _[T interface{~int}](x T) { func _[T interface{~int}](x T) {
type myint int type myint int
var _ int = int(x) var _ int = int(x)
@ -198,19 +195,19 @@ func _[T interface{~int}](x T) {
var _ T = T(myint(42)) var _ T = T(myint(42))
} }
// Indexing a generic type with an array type bound checks length. // Indexing a type parameter with an array type bound checks length.
// (Example by mdempsky@.) // (Example by mdempsky@.)
func _[T interface { ~[10]int }](x T) { func _[T interface { ~[10]int }](x T) {
_ = x[9] // ok _ = x[9] // ok
_ = x[20 /* ERROR out of bounds */ ] _ = x[20 /* ERROR out of bounds */ ]
} }
// Pointer indirection of a generic type. // Pointer indirection of a type parameter.
func _[T interface{ ~*int }](p T) int { func _[T interface{ ~*int }](p T) int {
return *p return *p
} }
// Channel sends and receives on generic types. // Channel sends and receives on type parameters.
func _[T interface{ ~chan int }](ch T) int { func _[T interface{ ~chan int }](ch T) int {
ch <- 0 ch <- 0
return <- ch return <- ch
@ -229,11 +226,11 @@ func _[T interface{ func()|F1|F2 }](f T) {
go f() go f()
} }
// We must compare against the underlying type of type list entries // We must compare against the (possibly underlying) types of term list
// when checking if a constraint is satisfied by a type. The under- // elements when checking if a constraint is satisfied by a type.
// lying type of each type list entry must be computed after the // The underlying type of each term must be computed after the
// interface has been instantiated as its typelist may contain a // interface has been instantiated as its constraint may contain
// type parameter that was substituted with a defined type. // a type parameter that was substituted with a defined type.
// Test case from an (originally) failing example. // Test case from an (originally) failing example.
type sliceOf[E any] interface{ ~[]E } type sliceOf[E any] interface{ ~[]E }

View File

@ -173,7 +173,9 @@ type _ interface {
} }
// Interface term lists can contain any type, incl. *Named types. // Interface term lists can contain any type, incl. *Named types.
// Verify that we use the underlying type to compute the operational type. // Verify that we use the underlying type(s) of the type(s) in the
// term list when determining if an operation is permitted.
type MyInt int type MyInt int
func add1[T interface{MyInt}](x T) T { func add1[T interface{MyInt}](x T) T {
return x + 1 return x + 1

View File

@ -22,7 +22,7 @@ type constraint interface {
func _[T constraint](x interface{}){ func _[T constraint](x interface{}){
switch x.(type) { switch x.(type) {
case T: // ok to use a type parameter even if type list contains int case T: // ok to use a type parameter even if type set contains int
case int: case int:
} }
} }

View File

@ -85,7 +85,7 @@ type Setter[B any] interface {
func FromStrings[T interface{}, PT Setter[T]](s []string) []T { func FromStrings[T interface{}, PT Setter[T]](s []string) []T {
result := make([]T, len(s)) result := make([]T, len(s))
for i, v := range s { for i, v := range s {
// The type of &result[i] is *T which is in the type list // The type of &result[i] is *T which is in the type set
// of Setter, so we can convert it to PT. // of Setter, so we can convert it to PT.
p := PT(&result[i]) p := PT(&result[i])
// PT has a Set method. // PT has a Set method.

View File

@ -51,9 +51,8 @@ func _() {
} }
// When a type parameter is used as an argument to instantiate a parameterized // When a type parameter is used as an argument to instantiate a parameterized
// type with a type set constraint, all of the type argument's types in its // type, the type argument's type set must be a subset of the instantiated type
// bound, but at least one (!), must be in the type set of the bound of the // parameter's type set.
// corresponding parameterized type's type parameter.
type T1[P interface{~uint}] struct{} type T1[P interface{~uint}] struct{}
func _[P any]() { func _[P any]() {
@ -150,7 +149,7 @@ type inf2[T any] struct{ inf2 /* ERROR illegal cycle */ [T] }
// The implementation of conversions T(x) between integers and floating-point // The implementation of conversions T(x) between integers and floating-point
// numbers checks that both T and x have either integer or floating-point // numbers checks that both T and x have either integer or floating-point
// type. When the type of T or x is a type parameter, the respective simple // type. When the type of T or x is a type parameter, the respective simple
// predicate disjunction in the implementation was wrong because if a term list // predicate disjunction in the implementation was wrong because if a type set
// contains both an integer and a floating-point type, the type parameter is // contains both an integer and a floating-point type, the type parameter is
// neither an integer or a floating-point number. // neither an integer or a floating-point number.
func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 { func convert[T1, T2 interface{~int | ~uint | ~float32}](v T1) T2 {
@ -183,14 +182,12 @@ func _[T interface{}, PT interface{~*T}] (x T) PT {
return &x return &x
} }
// Indexing of generic types containing type parameters in their term list: // Indexing of type parameters containing type parameters in their constraint terms:
func at[T interface{ ~[]E }, E interface{}](x T, i int) E { func at[T interface{ ~[]E }, E interface{}](x T, i int) E {
return x[i] return x[i]
} }
// A generic type inside a function acts like a named type. Its underlying // Conversion of a local type to a type parameter.
// type is itself, its "operational type" is defined by the term list in
// the tybe bound, if any.
func _[T interface{~int}](x T) { func _[T interface{~int}](x T) {
type myint int type myint int
var _ int = int(x) var _ int = int(x)
@ -198,19 +195,19 @@ func _[T interface{~int}](x T) {
var _ T = T(myint(42)) var _ T = T(myint(42))
} }
// Indexing a generic type with an array type bound checks length. // Indexing a type parameter with an array type bound checks length.
// (Example by mdempsky@.) // (Example by mdempsky@.)
func _[T interface { ~[10]int }](x T) { func _[T interface { ~[10]int }](x T) {
_ = x[9] // ok _ = x[9] // ok
_ = x[20 /* ERROR out of bounds */ ] _ = x[20 /* ERROR out of bounds */ ]
} }
// Pointer indirection of a generic type. // Pointer indirection of a type parameter.
func _[T interface{ ~*int }](p T) int { func _[T interface{ ~*int }](p T) int {
return *p return *p
} }
// Channel sends and receives on generic types. // Channel sends and receives on type parameters.
func _[T interface{ ~chan int }](ch T) int { func _[T interface{ ~chan int }](ch T) int {
ch <- 0 ch <- 0
return <- ch return <- ch
@ -229,11 +226,11 @@ func _[T interface{ func()|F1|F2 }](f T) {
go f() go f()
} }
// We must compare against the underlying type of term list entries // We must compare against the (possibly underlying) types of term list
// when checking if a constraint is satisfied by a type. The under- // elements when checking if a constraint is satisfied by a type.
// lying type of each term list entry must be computed after the // The underlying type of each term must be computed after the
// interface has been instantiated as its typelist may contain a // interface has been instantiated as its constraint may contain
// type parameter that was substituted with a defined type. // a type parameter that was substituted with a defined type.
// Test case from an (originally) failing example. // Test case from an (originally) failing example.
type sliceOf[E any] interface{ ~[]E } type sliceOf[E any] interface{ ~[]E }

View File

@ -173,7 +173,9 @@ type _ interface {
} }
// Interface term lists can contain any type, incl. *Named types. // Interface term lists can contain any type, incl. *Named types.
// Verify that we use the underlying type to compute the operational type. // Verify that we use the underlying type(s) of the type(s) in the
// term list when determining if an operation is permitted.
type MyInt int type MyInt int
func add1[T interface{MyInt}](x T) T { func add1[T interface{MyInt}](x T) T {
return x + 1 return x + 1

View File

@ -22,7 +22,7 @@ type constraint interface {
func _[T constraint](x interface{}){ func _[T constraint](x interface{}){
switch x.(type) { switch x.(type) {
case T: // ok to use a type parameter even if type list contains int case T: // ok to use a type parameter even if type set contains int
case int: case int:
} }
} }