From b6dddaccd7e8c9c6768943918d03f455385294b9 Mon Sep 17 00:00:00 2001 From: Dan Scales Date: Sun, 19 Sep 2021 17:17:31 -0700 Subject: cmd/compile: fix transform.AssignOp to deal with tricky case When going to dictionary formats derived from the function instantiations, I had broken out noder.Assignop() to deal specially with shape types, but didn't quite get the tricky case right. We still need to allow conversion between shape types, but if the destination is an interface, we need to use CONVIFACE rather than CONVNOP. Fixes #48453. Change-Id: I8c4b39c2e628172ac34f493f1dd682cbac1e55ae Reviewed-on: https://go-review.googlesource.com/c/go/+/350949 Trust: Dan Scales Run-TryBot: Dan Scales Reviewed-by: Keith Randall --- src/cmd/compile/internal/noder/transform.go | 15 ++++++++++++--- test/typeparam/issue48453.go | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 test/typeparam/issue48453.go diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go index a117e310ea..3e5cfacb97 100644 --- a/src/cmd/compile/internal/noder/transform.go +++ b/src/cmd/compile/internal/noder/transform.go @@ -431,9 +431,18 @@ func Assignop(src, dst *types.Type) (ir.Op, string) { return ir.OXXX, "" } - // 1. src type is identical to dst. - if types.IdenticalStrict(src, dst) { - return ir.OCONVNOP, "" + // 1. src type is identical to dst (taking shapes into account) + if types.Identical(src, dst) { + // We already know from assignconvfn above that IdenticalStrict(src, + // dst) is false, so the types are not exactly the same and one of + // src or dst is a shape. If dst is an interface (which means src is + // an interface too), we need a real OCONVIFACE op; otherwise we need a + // OCONVNOP. See issue #48453. + if dst.IsInterface() { + return ir.OCONVIFACE, "" + } else { + return ir.OCONVNOP, "" + } } return typecheck.Assignop1(src, dst) } diff --git a/test/typeparam/issue48453.go b/test/typeparam/issue48453.go new file mode 100644 index 0000000000..0f751d38ed --- /dev/null +++ b/test/typeparam/issue48453.go @@ -0,0 +1,21 @@ +// run -gcflags=-G=3 + +// Copyright 2021 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 + +//go:noinline +func CopyMap[M interface{ ~map[K]V }, K comparable, V any](m M) M { + out := make(M, len(m)) + for k, v := range m { + out[k] = v + } + return out +} + +func main() { + var m map[*string]int + CopyMap(m) +} -- cgit v1.2.3-54-g00ecf