// 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)) } }