|  | // run | 
|  |  | 
|  | // Copyright 2022 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 main | 
|  |  | 
|  | import "fmt" | 
|  |  | 
|  | type I interface { | 
|  | M() | 
|  | } | 
|  |  | 
|  | type S struct { | 
|  | str string | 
|  | } | 
|  |  | 
|  | func (s *S) M() {} | 
|  |  | 
|  | var _ I = &S{} | 
|  |  | 
|  | type CloningMap[K comparable, V any] struct { | 
|  | inner map[K]V | 
|  | } | 
|  |  | 
|  | func (cm CloningMap[K, V]) With(key K, value V) CloningMap[K, V] { | 
|  | result := CloneBad(cm.inner) | 
|  | result[key] = value | 
|  | return CloningMap[K, V]{result} | 
|  | } | 
|  |  | 
|  | func CloneBad[M ~map[K]V, K comparable, V any](m M) M { | 
|  | r := make(M, len(m)) | 
|  | for k, v := range m { | 
|  | r[k] = v | 
|  | } | 
|  | return r | 
|  | } | 
|  |  | 
|  | func main() { | 
|  | s1 := &S{"one"} | 
|  | s2 := &S{"two"} | 
|  |  | 
|  | m := CloningMap[string, I]{inner: make(map[string]I)} | 
|  | m = m.With("a", s1) | 
|  | m = m.With("b", s2) | 
|  |  | 
|  | it, found := m.inner["a"] | 
|  | if !found { | 
|  | panic("a not found") | 
|  | } | 
|  | if _, ok := it.(*S); !ok { | 
|  | panic(fmt.Sprintf("got %T want *main.S", it)) | 
|  | } | 
|  | } |