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
7package main
8
9import (
10	"reflect"
11	"runtime"
12	"unsafe"
13)
14
15func k(c chan string, val string) string {
16	b := make([]byte, 1000)
17	runtime.SetFinalizer(&b[0], func(*byte) {
18		c <- val
19	})
20	var s string
21	h := (*reflect.StringHeader)(unsafe.Pointer(&s))
22	h.Data = uintptr(unsafe.Pointer(&b[0]))
23	h.Len = len(b)
24	return s
25}
26
27func main() {
28	{
29		c := make(chan string, 2)
30		m := make(map[string]int)
31		m[k(c, "first")] = 0
32		m[k(c, "second")] = 0
33		runtime.GC()
34		if s := <-c; s != "first" {
35			panic("map[string], second key did not retain.")
36		}
37		runtime.KeepAlive(m)
38	}
39
40	{
41		c := make(chan string, 2)
42		m := make(map[[2]string]int)
43		m[[2]string{k(c, "first")}] = 0
44		m[[2]string{k(c, "second")}] = 0
45		runtime.GC()
46		if s := <-c; s != "first" {
47			panic("map[[2]string], second key did not retain.")
48		}
49		runtime.KeepAlive(m)
50	}
51}
52