]> Cypherpunks.ru repositories - gostls13.git/blob - test/typeparam/issue50109.go
cmd/compile/internal/inline: score call sites exposed by inlines
[gostls13.git] / test / typeparam / issue50109.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 package main
8
9 import (
10         "fmt"
11 )
12
13 type AnyCacher[T any] interface {
14         // Get an item from the cache. Returns the item or nil, and a bool indicating
15         // whether the key was found.
16         Get(k string) (T, bool)
17         // Add an item to the cache, replacing any existing item.
18         Set(k string, x T)
19 }
20
21 // Item ...
22 type Item[T any] struct {
23         Object T
24 }
25
26 // AnyCache implements AnyCacher
27 type AnyCache[T any] struct {
28         *anyCache[T]
29 }
30
31 type anyCache[T any] struct {
32         items   map[string]Item[T]
33         janitor *janitor[T] // Needed for the failure in the issue
34 }
35
36 // Set adds an item to the cache, replacing any existing item.
37 func (c *anyCache[T]) Set(k string, x T) {
38         c.items[k] = Item[T]{
39                 Object: x,
40         }
41 }
42
43 // Get gets an item from the cache. Returns the item or nil, and a bool indicating
44 // whether the key was found.
45 func (c *anyCache[T]) Get(k string) (T, bool) {
46         // "Inlining" of get and Expired
47         item, found := c.items[k]
48         if !found {
49                 var ret T
50                 return ret, false
51         }
52
53         return item.Object, true
54 }
55
56 type janitor[T any] struct {
57         stop chan bool
58 }
59
60 func newAnyCache[T any](m map[string]Item[T]) *anyCache[T] {
61         c := &anyCache[T]{
62                 items: m,
63         }
64         return c
65 }
66
67 // NewAny[T any](...) returns a new AnyCache[T].
68 func NewAny[T any]() *AnyCache[T] {
69         items := make(map[string]Item[T])
70         return &AnyCache[T]{newAnyCache(items)}
71 }
72
73 // NewAnyCacher[T any](...) returns an AnyCacher[T] interface.
74 func NewAnyCacher[T any]() AnyCacher[T] {
75         return NewAny[T]()
76 }
77
78 type MyStruct struct {
79         Name string
80 }
81
82 func main() {
83         // Create a generic cache.
84         // All items are cached as interface{} so they need to be cast back to their
85         // original type when retrieved.
86         // Failure in issue doesn't happen with 'any' replaced by 'interface{}'
87         c := NewAnyCacher[any]()
88
89         myStruct := &MyStruct{"MySuperStruct"}
90
91         c.Set("MySuperStruct", myStruct)
92
93         myRawCachedStruct, found := c.Get("MySuperStruct")
94
95         if found {
96                 // Casting the retrieved object back to its original type
97                 myCachedStruct := myRawCachedStruct.(*MyStruct)
98                 fmt.Printf("%s", myCachedStruct.Name)
99         } else {
100                 fmt.Printf("Error: MySuperStruct not found in cache")
101         }
102
103         // Output:
104         // MySuperStruct
105 }