Source file test/typeparam/dictionaryCapture.go

     1  // run
     2  
     3  // Copyright 2021 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // Test situations where functions/methods are not
     8  // immediately called and we need to capture the dictionary
     9  // required for later invocation.
    10  
    11  package main
    12  
    13  import (
    14  	"fmt"
    15  )
    16  
    17  func main() {
    18  	functions()
    19  	methodExpressions()
    20  	genMethodExpressions[int](7)
    21  	methodValues()
    22  	genMethodValues[int](7)
    23  	interfaceMethods()
    24  	globals()
    25  	recursive()
    26  }
    27  
    28  func g0[T any](x T) {
    29  }
    30  func g1[T any](x T) T {
    31  	return x
    32  }
    33  func g2[T any](x T) (T, T) {
    34  	return x, x
    35  }
    36  
    37  func functions() {
    38  	f0 := g0[int]
    39  	f0(7)
    40  	f1 := g1[int]
    41  	is7(f1(7))
    42  	f2 := g2[int]
    43  	is77(f2(7))
    44  }
    45  
    46  func is7(x int) {
    47  	if x != 7 {
    48  		println(x)
    49  		panic("assertion failed")
    50  	}
    51  }
    52  func is77(x, y int) {
    53  	if x != 7 || y != 7 {
    54  		println(x, y)
    55  		panic("assertion failed")
    56  	}
    57  }
    58  
    59  type s[T any] struct {
    60  	a T
    61  }
    62  
    63  func (x s[T]) g0() {
    64  }
    65  func (x s[T]) g1() T {
    66  	return x.a
    67  }
    68  func (x s[T]) g2() (T, T) {
    69  	return x.a, x.a
    70  }
    71  
    72  func methodExpressions() {
    73  	x := s[int]{a: 7}
    74  	f0 := s[int].g0
    75  	f0(x)
    76  	f0p := (*s[int]).g0
    77  	f0p(&x)
    78  	f1 := s[int].g1
    79  	is7(f1(x))
    80  	f1p := (*s[int]).g1
    81  	is7(f1p(&x))
    82  	f2 := s[int].g2
    83  	is77(f2(x))
    84  	f2p := (*s[int]).g2
    85  	is77(f2p(&x))
    86  }
    87  
    88  func genMethodExpressions[T comparable](want T) {
    89  	x := s[T]{a: want}
    90  	f0 := s[T].g0
    91  	f0(x)
    92  	f0p := (*s[T]).g0
    93  	f0p(&x)
    94  	f1 := s[T].g1
    95  	if got := f1(x); got != want {
    96  		panic(fmt.Sprintf("f1(x) == %d, want %d", got, want))
    97  	}
    98  	f1p := (*s[T]).g1
    99  	if got := f1p(&x); got != want {
   100  		panic(fmt.Sprintf("f1p(&x) == %d, want %d", got, want))
   101  	}
   102  	f2 := s[T].g2
   103  	if got1, got2 := f2(x); got1 != want || got2 != want {
   104  		panic(fmt.Sprintf("f2(x) == %d, %d, want %d, %d", got1, got2, want, want))
   105  	}
   106  }
   107  
   108  func methodValues() {
   109  	x := s[int]{a: 7}
   110  	f0 := x.g0
   111  	f0()
   112  	f1 := x.g1
   113  	is7(f1())
   114  	f2 := x.g2
   115  	is77(f2())
   116  }
   117  
   118  func genMethodValues[T comparable](want T) {
   119  	x := s[T]{a: want}
   120  	f0 := x.g0
   121  	f0()
   122  	f1 := x.g1
   123  	if got := f1(); got != want {
   124  		panic(fmt.Sprintf("f1() == %d, want %d", got, want))
   125  	}
   126  	f2 := x.g2
   127  	if got1, got2 := f2(); got1 != want || got2 != want {
   128  		panic(fmt.Sprintf("f2() == %d, %d, want %d, %d", got1, got2, want, want))
   129  	}
   130  }
   131  
   132  var x interface {
   133  	g0()
   134  	g1() int
   135  	g2() (int, int)
   136  } = s[int]{a: 7}
   137  var y interface{} = s[int]{a: 7}
   138  
   139  func interfaceMethods() {
   140  	x.g0()
   141  	is7(x.g1())
   142  	is77(x.g2())
   143  	y.(interface{ g0() }).g0()
   144  	is7(y.(interface{ g1() int }).g1())
   145  	is77(y.(interface{ g2() (int, int) }).g2())
   146  }
   147  
   148  // Also check for instantiations outside functions.
   149  var gg0 = g0[int]
   150  var gg1 = g1[int]
   151  var gg2 = g2[int]
   152  
   153  var hh0 = s[int].g0
   154  var hh1 = s[int].g1
   155  var hh2 = s[int].g2
   156  
   157  var xtop = s[int]{a: 7}
   158  var ii0 = x.g0
   159  var ii1 = x.g1
   160  var ii2 = x.g2
   161  
   162  func globals() {
   163  	gg0(7)
   164  	is7(gg1(7))
   165  	is77(gg2(7))
   166  	x := s[int]{a: 7}
   167  	hh0(x)
   168  	is7(hh1(x))
   169  	is77(hh2(x))
   170  	ii0()
   171  	is7(ii1())
   172  	is77(ii2())
   173  }
   174  
   175  func recursive() {
   176  	if got, want := recur1[int](5), 110; got != want {
   177  		panic(fmt.Sprintf("recur1[int](5) = %d, want = %d", got, want))
   178  	}
   179  }
   180  
   181  type Integer interface {
   182  	int | int32 | int64
   183  }
   184  
   185  func recur1[T Integer](n T) T {
   186  	if n == 0 || n == 1 {
   187  		return T(1)
   188  	} else {
   189  		return n * recur2(n-1)
   190  	}
   191  }
   192  
   193  func recur2[T Integer](n T) T {
   194  	list := make([]T, n)
   195  	for i, _ := range list {
   196  		list[i] = T(i + 1)
   197  	}
   198  	var sum T
   199  	for _, elt := range list {
   200  		sum += elt
   201  	}
   202  	return sum + recur1(n-1)
   203  }
   204  

View as plain text