aboutsummaryrefslogtreecommitdiff
path: root/test/typeparam
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2022-01-08 10:33:35 -0800
committerDan Scales <danscales@google.com>2022-01-11 22:50:23 +0000
commit1ee70da3125cb6339c1bcb0c127cd97a9e1dbe90 (patch)
tree68477aaf042b7eb9f693c3474dc88c33a7cd2e86 /test/typeparam
parent13c912d19252b9225fa96b9a5557575bbaffb570 (diff)
downloadgo-1ee70da3125cb6339c1bcb0c127cd97a9e1dbe90.tar.xz
cmd/compile: fix the names of methods created during type substitution
The names given to methods of types created during type substitution were possible incorrect when the type parameters themselves were nested types. Fixes #50485 Change-Id: I7e0043ed22c26406a5f9d8d51d9e928770a678f6 Reviewed-on: https://go-review.googlesource.com/c/go/+/377494 Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'test/typeparam')
-rw-r--r--test/typeparam/issue50485.dir/a.go239
-rw-r--r--test/typeparam/issue50485.dir/main.go9
-rw-r--r--test/typeparam/issue50485.go7
3 files changed, 255 insertions, 0 deletions
diff --git a/test/typeparam/issue50485.dir/a.go b/test/typeparam/issue50485.dir/a.go
new file mode 100644
index 0000000000..3a7c71a711
--- /dev/null
+++ b/test/typeparam/issue50485.dir/a.go
@@ -0,0 +1,239 @@
+package a
+
+import "fmt"
+
+type ImplicitOrd interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 |
+ ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
+ ~float32 | ~float64 |
+ ~string
+}
+
+func LessGiven[T ImplicitOrd]() Ord[T] {
+ return LessFunc[T](func(a, b T) bool {
+ return a < b
+ })
+}
+
+type Eq[T any] interface {
+ Eqv(a T, b T) bool
+}
+
+type Ord[T any] interface {
+ Eq[T]
+ Less(a T, b T) bool
+}
+
+type LessFunc[T any] func(a, b T) bool
+
+func (r LessFunc[T]) Eqv(a, b T) bool {
+ return r(a, b) == false && r(b, a) == false
+}
+
+func (r LessFunc[T]) Less(a, b T) bool {
+ return r(a, b)
+}
+
+type Option[T any] struct {
+ v *T
+}
+
+func (r Option[T]) IsDefined() bool {
+ return r.v != nil
+}
+
+func (r Option[T]) IsEmpty() bool {
+ return !r.IsDefined()
+}
+
+func (r Option[T]) Get() T {
+ return *r.v
+}
+
+func (r Option[T]) String() string {
+ if r.IsDefined() {
+ return fmt.Sprintf("Some(%v)", r.v)
+ } else {
+ return "None"
+ }
+}
+
+func (r Option[T]) OrElse(t T) T {
+ if r.IsDefined() {
+ return *r.v
+ }
+ return t
+}
+
+func (r Option[T]) Recover(f func() T) Option[T] {
+ if r.IsDefined() {
+ return r
+ }
+ t := f()
+ return Option[T]{&t}
+}
+
+type Func1[A1, R any] func(a1 A1) R
+
+type Func2[A1, A2, R any] func(a1 A1, a2 A2) R
+
+func (r Func2[A1, A2, R]) Curried() Func1[A1, Func1[A2, R]] {
+ return func(a1 A1) Func1[A2, R] {
+ return Func1[A2, R](func(a2 A2) R {
+ return r(a1, a2)
+ })
+ }
+}
+
+type HList interface {
+ sealed()
+}
+
+// Header is constrains interface type, enforce Head type of Cons is HT
+type Header[HT any] interface {
+ HList
+ Head() HT
+}
+
+// Cons means H :: T
+// zero value of Cons[H,T] is not allowed.
+// so Cons defined as interface type
+type Cons[H any, T HList] interface {
+ HList
+ Head() H
+ Tail() T
+}
+
+type Nil struct {
+}
+
+func (r Nil) Head() Nil {
+ return r
+}
+
+func (r Nil) Tail() Nil {
+ return r
+}
+
+func (r Nil) String() string {
+ return "Nil"
+}
+
+func (r Nil) sealed() {
+
+}
+
+type hlistImpl[H any, T HList] struct {
+ head H
+ tail T
+}
+
+func (r hlistImpl[H, T]) Head() H {
+ return r.head
+}
+
+func (r hlistImpl[H, T]) Tail() T {
+ return r.tail
+}
+
+func (r hlistImpl[H, T]) String() string {
+ return fmt.Sprintf("%v :: %v", r.head, r.tail)
+}
+
+func (r hlistImpl[H, T]) sealed() {
+
+}
+
+func hlist[H any, T HList](h H, t T) Cons[H, T] {
+ return hlistImpl[H, T]{h, t}
+}
+
+func Concat[H any, T HList](h H, t T) Cons[H, T] {
+ return hlist(h, t)
+}
+
+func Empty() Nil {
+ return Nil{}
+}
+func Some[T any](v T) Option[T] {
+ return Option[T]{}.Recover(func() T {
+ return v
+ })
+}
+
+func None[T any]() Option[T] {
+ return Option[T]{}
+}
+
+func Ap[T, U any](t Option[Func1[T, U]], a Option[T]) Option[U] {
+ return FlatMap(t, func(f Func1[T, U]) Option[U] {
+ return Map(a, f)
+ })
+}
+
+func Map[T, U any](opt Option[T], f func(v T) U) Option[U] {
+ return FlatMap(opt, func(v T) Option[U] {
+ return Some(f(v))
+ })
+}
+
+func FlatMap[T, U any](opt Option[T], fn func(v T) Option[U]) Option[U] {
+ if opt.IsDefined() {
+ return fn(opt.Get())
+ }
+ return None[U]()
+}
+
+type ApplicativeFunctor1[H Header[HT], HT, A, R any] struct {
+ h Option[H]
+ fn Option[Func1[A, R]]
+}
+
+func (r ApplicativeFunctor1[H, HT, A, R]) ApOption(a Option[A]) Option[R] {
+ return Ap(r.fn, a)
+}
+
+func (r ApplicativeFunctor1[H, HT, A, R]) Ap(a A) Option[R] {
+ return r.ApOption(Some(a))
+}
+
+func Applicative1[A, R any](fn Func1[A, R]) ApplicativeFunctor1[Nil, Nil, A, R] {
+ return ApplicativeFunctor1[Nil, Nil, A, R]{Some(Empty()), Some(fn)}
+}
+
+type ApplicativeFunctor2[H Header[HT], HT, A1, A2, R any] struct {
+ h Option[H]
+ fn Option[Func1[A1, Func1[A2, R]]]
+}
+
+func (r ApplicativeFunctor2[H, HT, A1, A2, R]) ApOption(a Option[A1]) ApplicativeFunctor1[Cons[A1, H], A1, A2, R] {
+
+ nh := FlatMap(r.h, func(hv H) Option[Cons[A1, H]] {
+ return Map(a, func(av A1) Cons[A1, H] {
+ return Concat(av, hv)
+ })
+ })
+
+ return ApplicativeFunctor1[Cons[A1, H], A1, A2, R]{nh, Ap(r.fn, a)}
+}
+func (r ApplicativeFunctor2[H, HT, A1, A2, R]) Ap(a A1) ApplicativeFunctor1[Cons[A1, H], A1, A2, R] {
+
+ return r.ApOption(Some(a))
+
+}
+
+func Applicative2[A1, A2, R any](fn Func2[A1, A2, R]) ApplicativeFunctor2[Nil, Nil, A1, A2, R] {
+ return ApplicativeFunctor2[Nil, Nil, A1, A2, R]{Some(Empty()), Some(fn.Curried())}
+}
+func OrdOption[T any](m Ord[T]) Ord[Option[T]] {
+ return LessFunc[Option[T]](func(t1 Option[T], t2 Option[T]) bool {
+ if !t1.IsDefined() && !t2.IsDefined() {
+ return false
+ }
+ return Applicative2(m.Less).ApOption(t1).ApOption(t2).OrElse(!t1.IsDefined())
+ })
+}
+
+func Given[T ImplicitOrd]() Ord[T] {
+ return LessGiven[T]()
+}
diff --git a/test/typeparam/issue50485.dir/main.go b/test/typeparam/issue50485.dir/main.go
new file mode 100644
index 0000000000..88a765bfe9
--- /dev/null
+++ b/test/typeparam/issue50485.dir/main.go
@@ -0,0 +1,9 @@
+package main
+
+import (
+ "a"
+)
+
+func main() {
+ _ = a.OrdOption(a.Given[int]())
+}
diff --git a/test/typeparam/issue50485.go b/test/typeparam/issue50485.go
new file mode 100644
index 0000000000..87b4ff46c1
--- /dev/null
+++ b/test/typeparam/issue50485.go
@@ -0,0 +1,7 @@
+// compiledir -G=3
+
+// 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.
+
+package ignored