mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00:00
cmd/compile/internal/types2: disallow lone type parameter on RHS of type declaration
We may revisit this decision in a future release. By disallowing this for Go 1.18 we are ensuring that we don't lock in the generics design in a place that may need to change later. (Type declarations are the primary construct where it crucially matters what the underlying type of a type parameter is.) Comment out all tests that rely on this feature; add comments referring to issue so we can find all places easily should we change our minds. Fixes #45639. Change-Id: I730510e4da66d3716d455a9071c7778a1e4a1152 Reviewed-on: https://go-review.googlesource.com/c/go/+/359177 Trust: Robert Griesemer <gri@golang.org> Trust: Dan Scales <danscales@google.com> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
79ff663754
commit
a91d0b649c
@ -622,13 +622,6 @@ func TestDefsInfo(t *testing.T) {
|
|||||||
{`package p3; type x int`, `x`, `type p3.x int`},
|
{`package p3; type x int`, `x`, `type p3.x int`},
|
||||||
{`package p4; func f()`, `f`, `func p4.f()`},
|
{`package p4; func f()`, `f`, `func p4.f()`},
|
||||||
{`package p5; func f() int { x, _ := 1, 2; return x }`, `_`, `var _ int`},
|
{`package p5; func f() int { x, _ := 1, 2; return x }`, `_`, `var _ int`},
|
||||||
|
|
||||||
// generic types must be sanitized
|
|
||||||
// (need to use sufficiently nested types to provoke unexpanded types)
|
|
||||||
{genericPkg + `g0; type t[P any] P; const x = t[int](42)`, `x`, `const generic_g0.x generic_g0.t[int]`},
|
|
||||||
{genericPkg + `g1; type t[P any] P; var x = t[int](42)`, `x`, `var generic_g1.x generic_g1.t[int]`},
|
|
||||||
{genericPkg + `g2; type t[P any] P; type x struct{ f t[int] }`, `x`, `type generic_g2.x struct{f generic_g2.t[int]}`},
|
|
||||||
{genericPkg + `g3; type t[P any] P; func f(x struct{ f t[string] }); var g = f`, `g`, `var generic_g3.g func(x struct{f generic_g3.t[string]})`},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
@ -667,13 +660,6 @@ func TestUsesInfo(t *testing.T) {
|
|||||||
{`package p2; func _() { _ = x }; var x int`, `x`, `var p2.x int`},
|
{`package p2; func _() { _ = x }; var x int`, `x`, `var p2.x int`},
|
||||||
{`package p3; func _() { type _ x }; type x int`, `x`, `type p3.x int`},
|
{`package p3; func _() { type _ x }; type x int`, `x`, `type p3.x int`},
|
||||||
{`package p4; func _() { _ = f }; func f()`, `f`, `func p4.f()`},
|
{`package p4; func _() { _ = f }; func f()`, `f`, `func p4.f()`},
|
||||||
|
|
||||||
// generic types must be sanitized
|
|
||||||
// (need to use sufficiently nested types to provoke unexpanded types)
|
|
||||||
{genericPkg + `g0; func _() { _ = x }; type t[P any] P; const x = t[int](42)`, `x`, `const generic_g0.x generic_g0.t[int]`},
|
|
||||||
{genericPkg + `g1; func _() { _ = x }; type t[P any] P; var x = t[int](42)`, `x`, `var generic_g1.x generic_g1.t[int]`},
|
|
||||||
{genericPkg + `g2; func _() { type _ x }; type t[P any] P; type x struct{ f t[int] }`, `x`, `type generic_g2.x struct{f generic_g2.t[int]}`},
|
|
||||||
{genericPkg + `g3; func _() { _ = f }; type t[P any] P; func f(x struct{ f t[string] })`, `f`, `func generic_g3.f(x struct{f generic_g3.t[string]})`},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
@ -604,9 +604,12 @@ func (check *Checker) typeDecl(obj *TypeName, tdecl *syntax.TypeDecl, def *Named
|
|||||||
named.underlying = Typ[Invalid]
|
named.underlying = Typ[Invalid]
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the RHS is a type parameter, it must be from this type declaration.
|
// Disallow a lone type parameter as the RHS of a type declaration (issue #45639).
|
||||||
if tpar, _ := named.underlying.(*TypeParam); tpar != nil && tparamIndex(named.TypeParams().list(), tpar) < 0 {
|
// We can look directly at named.underlying because even if it is still a *Named
|
||||||
check.errorf(tdecl.Type, "cannot use function type parameter %s as RHS in type declaration", tpar)
|
// type (underlying not fully resolved yet) it cannot become a type parameter due
|
||||||
|
// to this very restriction.
|
||||||
|
if tpar, _ := named.underlying.(*TypeParam); tpar != nil {
|
||||||
|
check.error(tdecl.Type, "cannot use a type parameter as RHS in type declaration")
|
||||||
named.underlying = Typ[Invalid]
|
named.underlying = Typ[Invalid]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
package linalg
|
package linalg
|
||||||
|
|
||||||
import "math"
|
|
||||||
|
|
||||||
// Numeric is type bound that matches any numeric type.
|
// Numeric is type bound that matches any numeric type.
|
||||||
// It would likely be in a constraints package in the standard library.
|
// It would likely be in a constraints package in the standard library.
|
||||||
type Numeric interface {
|
type Numeric interface {
|
||||||
@ -52,32 +50,33 @@ type Complex interface {
|
|||||||
~complex64 | ~complex128
|
~complex64 | ~complex128
|
||||||
}
|
}
|
||||||
|
|
||||||
// OrderedAbs is a helper type that defines an Abs method for
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
// ordered numeric types.
|
// // OrderedAbs is a helper type that defines an Abs method for
|
||||||
type OrderedAbs[T OrderedNumeric] T
|
// // ordered numeric types.
|
||||||
|
// type OrderedAbs[T OrderedNumeric] T
|
||||||
func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
|
//
|
||||||
if a < 0 {
|
// func (a OrderedAbs[T]) Abs() OrderedAbs[T] {
|
||||||
return -a
|
// if a < 0 {
|
||||||
}
|
// return -a
|
||||||
return a
|
// }
|
||||||
}
|
// return a
|
||||||
|
// }
|
||||||
// ComplexAbs is a helper type that defines an Abs method for
|
//
|
||||||
// complex types.
|
// // ComplexAbs is a helper type that defines an Abs method for
|
||||||
type ComplexAbs[T Complex] T
|
// // complex types.
|
||||||
|
// type ComplexAbs[T Complex] T
|
||||||
func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
|
//
|
||||||
r := float64(real(a))
|
// func (a ComplexAbs[T]) Abs() ComplexAbs[T] {
|
||||||
i := float64(imag(a))
|
// r := float64(real(a))
|
||||||
d := math.Sqrt(r * r + i * i)
|
// i := float64(imag(a))
|
||||||
return ComplexAbs[T](complex(d, 0))
|
// d := math.Sqrt(r * r + i * i)
|
||||||
}
|
// return ComplexAbs[T](complex(d, 0))
|
||||||
|
// }
|
||||||
func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
|
//
|
||||||
return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
|
// func OrderedAbsDifference[T OrderedNumeric](a, b T) T {
|
||||||
}
|
// return T(AbsDifference(OrderedAbs[T](a), OrderedAbs[T](b)))
|
||||||
|
// }
|
||||||
func ComplexAbsDifference[T Complex](a, b T) T {
|
//
|
||||||
return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
|
// func ComplexAbsDifference[T Complex](a, b T) T {
|
||||||
}
|
// return T(AbsDifference(ComplexAbs[T](a), ComplexAbs[T](b)))
|
||||||
|
// }
|
||||||
|
@ -8,7 +8,8 @@ type myInt int
|
|||||||
|
|
||||||
// Parameterized type declarations
|
// Parameterized type declarations
|
||||||
|
|
||||||
type T1[P any] P
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
type T1[P any] P // ERROR cannot use a type parameter as RHS in type declaration
|
||||||
|
|
||||||
type T2[P any] struct {
|
type T2[P any] struct {
|
||||||
f P
|
f P
|
||||||
@ -19,7 +20,7 @@ type List[P any] []P
|
|||||||
|
|
||||||
// Alias type declarations cannot have type parameters.
|
// Alias type declarations cannot have type parameters.
|
||||||
// Issue #46477 proposses to change that.
|
// Issue #46477 proposses to change that.
|
||||||
type A1[P any] = /* ERROR cannot be alias */ P
|
type A1[P any] = /* ERROR cannot be alias */ struct{}
|
||||||
|
|
||||||
// Pending clarification of #46477 we disallow aliases
|
// Pending clarification of #46477 we disallow aliases
|
||||||
// of generic types.
|
// of generic types.
|
||||||
|
@ -87,25 +87,27 @@ type NumericAbs[T any] interface {
|
|||||||
|
|
||||||
func AbsDifference[T NumericAbs[T]](x T) { panic(0) }
|
func AbsDifference[T NumericAbs[T]](x T) { panic(0) }
|
||||||
|
|
||||||
type OrderedAbs[T any] T
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
// type OrderedAbs[T any] T
|
||||||
func (a OrderedAbs[T]) Abs() OrderedAbs[T]
|
//
|
||||||
|
// func (a OrderedAbs[T]) Abs() OrderedAbs[T]
|
||||||
func OrderedAbsDifference[T any](x T) {
|
//
|
||||||
AbsDifference(OrderedAbs[T](x))
|
// func OrderedAbsDifference[T any](x T) {
|
||||||
}
|
// AbsDifference(OrderedAbs[T](x))
|
||||||
|
// }
|
||||||
|
|
||||||
// same code, reduced to essence
|
// same code, reduced to essence
|
||||||
|
|
||||||
func g[P interface{ m() P }](x P) { panic(0) }
|
func g[P interface{ m() P }](x P) { panic(0) }
|
||||||
|
|
||||||
type T4[P any] P
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
// type T4[P any] P
|
||||||
func (_ T4[P]) m() T4[P]
|
//
|
||||||
|
// func (_ T4[P]) m() T4[P]
|
||||||
func _[Q any](x Q) {
|
//
|
||||||
g(T4[Q](x))
|
// func _[Q any](x Q) {
|
||||||
}
|
// g(T4[Q](x))
|
||||||
|
// }
|
||||||
|
|
||||||
// Another test case that caused problems in the past
|
// Another test case that caused problems in the past
|
||||||
|
|
||||||
|
@ -353,15 +353,16 @@ func _() {
|
|||||||
|
|
||||||
// the previous example was extracted from
|
// the previous example was extracted from
|
||||||
|
|
||||||
func f12[T interface{m() T}]() {}
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
// func f12[T interface{m() T}]() {}
|
||||||
type A[T any] T
|
//
|
||||||
|
// type A[T any] T
|
||||||
func (a A[T]) m() A[T]
|
//
|
||||||
|
// func (a A[T]) m() A[T]
|
||||||
func _[T any]() {
|
//
|
||||||
f12[A[T]]()
|
// func _[T any]() {
|
||||||
}
|
// f12[A[T]]()
|
||||||
|
// }
|
||||||
|
|
||||||
// method expressions
|
// method expressions
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
package p
|
package p
|
||||||
|
|
||||||
import "unsafe"
|
|
||||||
|
|
||||||
// Parameterized types may have methods.
|
// Parameterized types may have methods.
|
||||||
type T1[A any] struct{ a A }
|
type T1[A any] struct{ a A }
|
||||||
|
|
||||||
@ -97,17 +95,18 @@ type T0 struct{}
|
|||||||
func (T0) _() {}
|
func (T0) _() {}
|
||||||
func (T1[A]) _() {}
|
func (T1[A]) _() {}
|
||||||
|
|
||||||
// A generic receiver type may constrain its type parameter such
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
// that it must be a pointer type. Such receiver types are not
|
// // A generic receiver type may constrain its type parameter such
|
||||||
// permitted.
|
// // that it must be a pointer type. Such receiver types are not
|
||||||
type T3a[P interface{ ~int | ~string | ~float64 }] P
|
// // permitted.
|
||||||
|
// type T3a[P interface{ ~int | ~string | ~float64 }] P
|
||||||
func (T3a[_]) m() {} // this is ok
|
//
|
||||||
|
// func (T3a[_]) m() {} // this is ok
|
||||||
type T3b[P interface{ ~unsafe.Pointer }] P
|
//
|
||||||
|
// type T3b[P interface{ ~unsafe.Pointer }] P
|
||||||
func (T3b /* ERROR invalid receiver */ [_]) m() {}
|
//
|
||||||
|
// func (T3b /* ERROR invalid receiver */ [_]) m() {}
|
||||||
type T3c[P interface{ *int | *string }] P
|
//
|
||||||
|
// type T3c[P interface{ *int | *string }] P
|
||||||
func (T3c /* ERROR invalid receiver */ [_]) m() {}
|
//
|
||||||
|
// func (T3c /* ERROR invalid receiver */ [_]) m() {}
|
||||||
|
@ -185,12 +185,13 @@ type _ struct {
|
|||||||
// _ = y < 0
|
// _ = y < 0
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// It is not permitted to declare a local type whose underlying
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
// type is a type parameter not declared by that type declaration.
|
// // It is not permitted to declare a local type whose underlying
|
||||||
func _[T any]() {
|
// // type is a type parameter not declared by that type declaration.
|
||||||
type _ T // ERROR cannot use function type parameter T as RHS in type declaration
|
// func _[T any]() {
|
||||||
type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
|
// type _ T // ERROR cannot use function type parameter T as RHS in type declaration
|
||||||
}
|
// type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
|
||||||
|
// }
|
||||||
|
|
||||||
// As a special case, an explicit type argument may be omitted
|
// As a special case, an explicit type argument may be omitted
|
||||||
// from a type parameter bound if the type bound expects exactly
|
// from a type parameter bound if the type bound expects exactly
|
||||||
|
@ -74,9 +74,10 @@ func F20[t Z20]() { F20(t /* ERROR invalid composite literal type */ {}) }
|
|||||||
type Z21 /* ERROR illegal cycle */ interface{ Z21 }
|
type Z21 /* ERROR illegal cycle */ interface{ Z21 }
|
||||||
func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) }
|
func F21[T Z21]() { ( /* ERROR not used */ F21[Z21]) }
|
||||||
|
|
||||||
// crash 24
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
type T24[P any] P
|
// // crash 24
|
||||||
func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
|
// type T24[P any] P
|
||||||
|
// func (r T24[P]) m() { T24 /* ERROR without instantiation */ .m() }
|
||||||
|
|
||||||
// crash 25
|
// crash 25
|
||||||
type T25[A any] int
|
type T25[A any] int
|
||||||
|
@ -4,14 +4,15 @@
|
|||||||
|
|
||||||
package p
|
package p
|
||||||
|
|
||||||
type T[P any] P
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
type A = T // ERROR cannot use generic type
|
// type T[P any] P
|
||||||
var x A[int]
|
// type A = T // ERROR cannot use generic type
|
||||||
var _ A
|
// var x A[int]
|
||||||
|
// var _ A
|
||||||
type B = T[int]
|
//
|
||||||
var y B = x
|
// type B = T[int]
|
||||||
var _ B /* ERROR not a generic type */ [int]
|
// var y B = x
|
||||||
|
// var _ B /* ERROR not a generic type */ [int]
|
||||||
|
|
||||||
// test case from issue
|
// test case from issue
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
package p
|
package p
|
||||||
|
|
||||||
type E0[P any] P
|
type E0[P any] []P
|
||||||
type E1[P any] *P
|
type E1[P any] *P
|
||||||
type E2[P any] struct{ _ P }
|
type E2[P any] struct{ _ P }
|
||||||
type E3[P any] struct{ _ *P }
|
type E3[P any] struct{ _ *P }
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
package P
|
package P
|
||||||
|
|
||||||
// It is not permitted to declare a local type whose underlying
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
// type is a type parameters not declared by that type declaration.
|
// // It is not permitted to declare a local type whose underlying
|
||||||
func _[T any]() {
|
// // type is a type parameters not declared by that type declaration.
|
||||||
type _ T // ERROR cannot use function type parameter T as RHS in type declaration
|
// func _[T any]() {
|
||||||
type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
|
// type _ T // ERROR cannot use function type parameter T as RHS in type declaration
|
||||||
}
|
// type _ [_ any] T // ERROR cannot use function type parameter T as RHS in type declaration
|
||||||
|
// }
|
||||||
|
@ -4,15 +4,16 @@
|
|||||||
|
|
||||||
package p
|
package p
|
||||||
|
|
||||||
type T1[P any] P
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
// type T1[P any] P
|
||||||
func (T1[_]) m() {}
|
//
|
||||||
|
// func (T1[_]) m() {}
|
||||||
func _[P any](x *T1[P]) {
|
//
|
||||||
// x.m exists because x is of type *T1 where T1 is a defined type
|
// func _[P any](x *T1[P]) {
|
||||||
// (even though under(T1) is a type parameter)
|
// // x.m exists because x is of type *T1 where T1 is a defined type
|
||||||
x.m()
|
// // (even though under(T1) is a type parameter)
|
||||||
}
|
// x.m()
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
func _[P interface{ m() }](x P) {
|
func _[P interface{ m() }](x P) {
|
||||||
@ -40,29 +41,31 @@ type Barer[t any] interface {
|
|||||||
Bar(t)
|
Bar(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Foo1[t any] t
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
type Bar[t any] t
|
// type Foo1[t any] t
|
||||||
|
// type Bar[t any] t
|
||||||
func (l Foo1[t]) Foo(v Barer[t]) { v.Bar(t(l)) }
|
//
|
||||||
func (b *Bar[t]) Bar(l t) { *b = Bar[t](l) }
|
// func (l Foo1[t]) Foo(v Barer[t]) { v.Bar(t(l)) }
|
||||||
|
// func (b *Bar[t]) Bar(l t) { *b = Bar[t](l) }
|
||||||
func _[t any](f Fooer1[t]) t {
|
//
|
||||||
var b Bar[t]
|
// func _[t any](f Fooer1[t]) t {
|
||||||
f.Foo(&b)
|
// var b Bar[t]
|
||||||
return t(b)
|
// f.Foo(&b)
|
||||||
}
|
// return t(b)
|
||||||
|
// }
|
||||||
|
|
||||||
// Test case 2 from issue
|
// Test case 2 from issue
|
||||||
|
|
||||||
type Fooer2[t any] interface {
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
Foo()
|
// type Fooer2[t any] interface {
|
||||||
}
|
// Foo()
|
||||||
|
// }
|
||||||
type Foo2[t any] t
|
//
|
||||||
|
// type Foo2[t any] t
|
||||||
func (f *Foo2[t]) Foo() {}
|
//
|
||||||
|
// func (f *Foo2[t]) Foo() {}
|
||||||
func _[t any](v t) {
|
//
|
||||||
var f = Foo2[t](v)
|
// func _[t any](v t) {
|
||||||
_ = Fooer2[t](&f)
|
// var f = Foo2[t](v)
|
||||||
}
|
// _ = Fooer2[t](&f)
|
||||||
|
// }
|
||||||
|
@ -6,11 +6,6 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"math"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Numeric interface {
|
type Numeric interface {
|
||||||
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
||||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
||||||
@ -43,55 +38,57 @@ type Complex interface {
|
|||||||
~complex64 | ~complex128
|
~complex64 | ~complex128
|
||||||
}
|
}
|
||||||
|
|
||||||
// orderedAbs is a helper type that defines an Abs method for
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
// ordered numeric types.
|
// // orderedAbs is a helper type that defines an Abs method for
|
||||||
type orderedAbs[T orderedNumeric] T
|
// // ordered numeric types.
|
||||||
|
// type orderedAbs[T orderedNumeric] T
|
||||||
func (a orderedAbs[T]) Abs() orderedAbs[T] {
|
//
|
||||||
if a < 0 {
|
// func (a orderedAbs[T]) Abs() orderedAbs[T] {
|
||||||
return -a
|
// if a < 0 {
|
||||||
}
|
// return -a
|
||||||
return a
|
// }
|
||||||
}
|
// return a
|
||||||
|
// }
|
||||||
// complexAbs is a helper type that defines an Abs method for
|
//
|
||||||
// complex types.
|
// // complexAbs is a helper type that defines an Abs method for
|
||||||
type complexAbs[T Complex] T
|
// // complex types.
|
||||||
|
// type complexAbs[T Complex] T
|
||||||
func (a complexAbs[T]) Abs() complexAbs[T] {
|
//
|
||||||
r := float64(real(a))
|
// func (a complexAbs[T]) Abs() complexAbs[T] {
|
||||||
i := float64(imag(a))
|
// r := float64(real(a))
|
||||||
d := math.Sqrt(r*r + i*i)
|
// i := float64(imag(a))
|
||||||
return complexAbs[T](complex(d, 0))
|
// d := math.Sqrt(r*r + i*i)
|
||||||
}
|
// return complexAbs[T](complex(d, 0))
|
||||||
|
// }
|
||||||
// OrderedAbsDifference returns the absolute value of the difference
|
//
|
||||||
// between a and b, where a and b are of an ordered type.
|
// // OrderedAbsDifference returns the absolute value of the difference
|
||||||
func orderedAbsDifference[T orderedNumeric](a, b T) T {
|
// // between a and b, where a and b are of an ordered type.
|
||||||
return T(absDifference(orderedAbs[T](a), orderedAbs[T](b)))
|
// func orderedAbsDifference[T orderedNumeric](a, b T) T {
|
||||||
}
|
// return T(absDifference(orderedAbs[T](a), orderedAbs[T](b)))
|
||||||
|
// }
|
||||||
// ComplexAbsDifference returns the absolute value of the difference
|
//
|
||||||
// between a and b, where a and b are of a complex type.
|
// // ComplexAbsDifference returns the absolute value of the difference
|
||||||
func complexAbsDifference[T Complex](a, b T) T {
|
// // between a and b, where a and b are of a complex type.
|
||||||
return T(absDifference(complexAbs[T](a), complexAbs[T](b)))
|
// func complexAbsDifference[T Complex](a, b T) T {
|
||||||
}
|
// return T(absDifference(complexAbs[T](a), complexAbs[T](b)))
|
||||||
|
// }
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if got, want := orderedAbsDifference(1.0, -2.0), 3.0; got != want {
|
// // For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := orderedAbsDifference(1.0, -2.0), 3.0; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
if got, want := orderedAbsDifference(-1.0, 2.0), 3.0; got != want {
|
// }
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := orderedAbsDifference(-1.0, 2.0), 3.0; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
if got, want := orderedAbsDifference(-20, 15), 35; got != want {
|
// }
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := orderedAbsDifference(-20, 15), 35; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
|
// }
|
||||||
if got, want := complexAbsDifference(5.0+2.0i, 2.0-2.0i), 5+0i; got != want {
|
//
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := complexAbsDifference(5.0+2.0i, 2.0-2.0i), 5+0i; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
if got, want := complexAbsDifference(2.0-2.0i, 5.0+2.0i), 5+0i; got != want {
|
// }
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := complexAbsDifference(2.0-2.0i, 5.0+2.0i), 5+0i; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,6 @@
|
|||||||
|
|
||||||
package a
|
package a
|
||||||
|
|
||||||
import (
|
|
||||||
"math"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Numeric interface {
|
type Numeric interface {
|
||||||
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
~int | ~int8 | ~int16 | ~int32 | ~int64 |
|
||||||
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
|
||||||
@ -40,36 +36,37 @@ type Complex interface {
|
|||||||
~complex64 | ~complex128
|
~complex64 | ~complex128
|
||||||
}
|
}
|
||||||
|
|
||||||
// orderedAbs is a helper type that defines an Abs method for
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
// ordered numeric types.
|
// // orderedAbs is a helper type that defines an Abs method for
|
||||||
type orderedAbs[T orderedNumeric] T
|
// // ordered numeric types.
|
||||||
|
// type orderedAbs[T orderedNumeric] T
|
||||||
func (a orderedAbs[T]) Abs() orderedAbs[T] {
|
//
|
||||||
if a < 0 {
|
// func (a orderedAbs[T]) Abs() orderedAbs[T] {
|
||||||
return -a
|
// if a < 0 {
|
||||||
}
|
// return -a
|
||||||
return a
|
// }
|
||||||
}
|
// return a
|
||||||
|
// }
|
||||||
// complexAbs is a helper type that defines an Abs method for
|
//
|
||||||
// complex types.
|
// // complexAbs is a helper type that defines an Abs method for
|
||||||
type complexAbs[T Complex] T
|
// // complex types.
|
||||||
|
// type complexAbs[T Complex] T
|
||||||
func (a complexAbs[T]) Abs() complexAbs[T] {
|
//
|
||||||
r := float64(real(a))
|
// func (a complexAbs[T]) Abs() complexAbs[T] {
|
||||||
i := float64(imag(a))
|
// r := float64(real(a))
|
||||||
d := math.Sqrt(r*r + i*i)
|
// i := float64(imag(a))
|
||||||
return complexAbs[T](complex(d, 0))
|
// d := math.Sqrt(r*r + i*i)
|
||||||
}
|
// return complexAbs[T](complex(d, 0))
|
||||||
|
// }
|
||||||
// OrderedAbsDifference returns the absolute value of the difference
|
//
|
||||||
// between a and b, where a and b are of an ordered type.
|
// // OrderedAbsDifference returns the absolute value of the difference
|
||||||
func OrderedAbsDifference[T orderedNumeric](a, b T) T {
|
// // between a and b, where a and b are of an ordered type.
|
||||||
return T(absDifference(orderedAbs[T](a), orderedAbs[T](b)))
|
// func OrderedAbsDifference[T orderedNumeric](a, b T) T {
|
||||||
}
|
// return T(absDifference(orderedAbs[T](a), orderedAbs[T](b)))
|
||||||
|
// }
|
||||||
// ComplexAbsDifference returns the absolute value of the difference
|
//
|
||||||
// between a and b, where a and b are of a complex type.
|
// // ComplexAbsDifference returns the absolute value of the difference
|
||||||
func ComplexAbsDifference[T Complex](a, b T) T {
|
// // between a and b, where a and b are of a complex type.
|
||||||
return T(absDifference(complexAbs[T](a), complexAbs[T](b)))
|
// func ComplexAbsDifference[T Complex](a, b T) T {
|
||||||
}
|
// return T(absDifference(complexAbs[T](a), complexAbs[T](b)))
|
||||||
|
// }
|
||||||
|
@ -4,26 +4,22 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"a"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if got, want := a.OrderedAbsDifference(1.0, -2.0), 3.0; got != want {
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := a.OrderedAbsDifference(1.0, -2.0), 3.0; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
if got, want := a.OrderedAbsDifference(-1.0, 2.0), 3.0; got != want {
|
// }
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := a.OrderedAbsDifference(-1.0, 2.0), 3.0; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
if got, want := a.OrderedAbsDifference(-20, 15), 35; got != want {
|
// }
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := a.OrderedAbsDifference(-20, 15), 35; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
|
// }
|
||||||
if got, want := a.ComplexAbsDifference(5.0+2.0i, 2.0-2.0i), 5+0i; got != want {
|
//
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := a.ComplexAbsDifference(5.0+2.0i, 2.0-2.0i), 5+0i; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
if got, want := a.ComplexAbsDifference(2.0-2.0i, 5.0+2.0i), 5+0i; got != want {
|
// }
|
||||||
panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
// if got, want := a.ComplexAbsDifference(2.0-2.0i, 5.0+2.0i), 5+0i; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got = %v, want = %v", got, want))
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -59,12 +59,13 @@ type Ints interface {
|
|||||||
~int32 | ~int
|
~int32 | ~int
|
||||||
}
|
}
|
||||||
|
|
||||||
type StringInt[T Ints] T
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
// type StringInt[T Ints] T
|
||||||
//go:noinline
|
//
|
||||||
func (m StringInt[T]) String() string {
|
// //go:noinline
|
||||||
return strconv.Itoa(int(m))
|
// func (m StringInt[T]) String() string {
|
||||||
}
|
// return strconv.Itoa(int(m))
|
||||||
|
// }
|
||||||
|
|
||||||
type StringStruct[T Ints] struct {
|
type StringStruct[T Ints] struct {
|
||||||
f T
|
f T
|
||||||
@ -84,22 +85,23 @@ func main() {
|
|||||||
panic(fmt.Sprintf("got %s, want %s", got, want))
|
panic(fmt.Sprintf("got %s, want %s", got, want))
|
||||||
}
|
}
|
||||||
|
|
||||||
x2 := []StringInt[myint]{StringInt[myint](5), StringInt[myint](7), StringInt[myint](6)}
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
// x2 := []StringInt[myint]{StringInt[myint](5), StringInt[myint](7), StringInt[myint](6)}
|
||||||
// stringify on an instantiated type, whose bound method is associated with
|
//
|
||||||
// the generic type StringInt[T], which maps directly to T.
|
// // stringify on an instantiated type, whose bound method is associated with
|
||||||
got2 := stringify(x2)
|
// // the generic type StringInt[T], which maps directly to T.
|
||||||
want2 := []string{ "5", "7", "6" }
|
// got2 := stringify(x2)
|
||||||
if !reflect.DeepEqual(got2, want2) {
|
// want2 := []string{"5", "7", "6"}
|
||||||
panic(fmt.Sprintf("got %s, want %s", got2, want2))
|
// if !reflect.DeepEqual(got2, want2) {
|
||||||
}
|
// panic(fmt.Sprintf("got %s, want %s", got2, want2))
|
||||||
|
// }
|
||||||
|
|
||||||
// stringify on an instantiated type, whose bound method is associated with
|
// stringify on an instantiated type, whose bound method is associated with
|
||||||
// the generic type StringStruct[T], which maps to a struct containing T.
|
// the generic type StringStruct[T], which maps to a struct containing T.
|
||||||
x3 := []StringStruct[myint]{StringStruct[myint]{f: 11}, StringStruct[myint]{f: 10}, StringStruct[myint]{f: 9}}
|
x3 := []StringStruct[myint]{StringStruct[myint]{f: 11}, StringStruct[myint]{f: 10}, StringStruct[myint]{f: 9}}
|
||||||
|
|
||||||
got3 := stringify(x3)
|
got3 := stringify(x3)
|
||||||
want3 := []string{ "11", "10", "9" }
|
want3 := []string{"11", "10", "9"}
|
||||||
if !reflect.DeepEqual(got3, want3) {
|
if !reflect.DeepEqual(got3, want3) {
|
||||||
panic(fmt.Sprintf("got %s, want %s", got3, want3))
|
panic(fmt.Sprintf("got %s, want %s", got3, want3))
|
||||||
}
|
}
|
||||||
|
@ -6,35 +6,32 @@
|
|||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FooType[T any] interface {
|
type FooType[T any] interface {
|
||||||
Foo(BarType[T])string
|
Foo(BarType[T]) string
|
||||||
}
|
}
|
||||||
type BarType[T any] interface {
|
type BarType[T any] interface {
|
||||||
Bar(FooType[T])string
|
Bar(FooType[T]) string
|
||||||
}
|
|
||||||
|
|
||||||
type Baz[T any] T
|
|
||||||
func (l Baz[T]) Foo(v BarType[T]) string {
|
|
||||||
return v.Bar(l)
|
|
||||||
}
|
|
||||||
type Bob[T any] T
|
|
||||||
func (l Bob[T]) Bar(v FooType[T]) string {
|
|
||||||
if v,ok := v.(Baz[T]);ok{
|
|
||||||
return fmt.Sprintf("%v%v",v,l)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
// type Baz[T any] T
|
||||||
|
// func (l Baz[T]) Foo(v BarType[T]) string {
|
||||||
|
// return v.Bar(l)
|
||||||
|
// }
|
||||||
|
// type Bob[T any] T
|
||||||
|
// func (l Bob[T]) Bar(v FooType[T]) string {
|
||||||
|
// if v,ok := v.(Baz[T]);ok{
|
||||||
|
// return fmt.Sprintf("%v%v",v,l)
|
||||||
|
// }
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
var baz Baz[int] = 123
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
var bob Bob[int] = 456
|
// var baz Baz[int] = 123
|
||||||
|
// var bob Bob[int] = 456
|
||||||
if got, want := baz.Foo(bob), "123456"; got != want {
|
//
|
||||||
panic(fmt.Sprintf("got %s want %s", got, want))
|
// if got, want := baz.Foo(bob), "123456"; got != want {
|
||||||
}
|
// panic(fmt.Sprintf("got %s want %s", got, want))
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,11 @@ type Exp[Ty any] interface {
|
|||||||
Eval() Ty
|
Eval() Ty
|
||||||
}
|
}
|
||||||
|
|
||||||
type Lit[Ty any] Ty
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
|
// type Lit[Ty any] Ty
|
||||||
func (lit Lit[Ty]) Eval() Ty { return Ty(lit) }
|
//
|
||||||
func (lit Lit[Ty]) String() string { return fmt.Sprintf("(lit %v)", Ty(lit)) }
|
// func (lit Lit[Ty]) Eval() Ty { return Ty(lit) }
|
||||||
|
// func (lit Lit[Ty]) String() string { return fmt.Sprintf("(lit %v)", Ty(lit)) }
|
||||||
|
|
||||||
type Eq[Ty any] struct {
|
type Eq[Ty any] struct {
|
||||||
a Exp[Ty]
|
a Exp[Ty]
|
||||||
@ -26,12 +27,14 @@ func (e Eq[Ty]) String() string {
|
|||||||
return fmt.Sprintf("(eq %v %v)", e.a, e.b)
|
return fmt.Sprintf("(eq %v %v)", e.a, e.b)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
e0 = Eq[int]{Lit[int](128), Lit[int](64)}
|
// var (
|
||||||
e1 = Eq[bool]{Lit[bool](true), Lit[bool](true)}
|
// e0 = Eq[int]{Lit[int](128), Lit[int](64)}
|
||||||
)
|
// e1 = Eq[bool]{Lit[bool](true), Lit[bool](true)}
|
||||||
|
// )
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
fmt.Printf("%v\n", e0)
|
// For now, a lone type parameter is not permitted as RHS in a type declaration (issue #45639).
|
||||||
fmt.Printf("%v\n", e1)
|
// fmt.Printf("%v\n", e0)
|
||||||
|
// fmt.Printf("%v\n", e1)
|
||||||
}
|
}
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
(eq (lit 128) (lit 64))
|
|
||||||
(eq (lit true) (lit true))
|
|
Loading…
x
Reference in New Issue
Block a user