From 39a8c8cf2e83de7e81d03ff1b1423411ed616cab Mon Sep 17 00:00:00 2001 From: Cuong Manh Le Date: Sun, 13 Mar 2022 00:04:46 +0700 Subject: [PATCH] [release-branch.go1.18] cmd/compile: fix wrong dict param when getting dict type CL 338129 added getDictionaryType to get the dictionary type from the specified dict param, but still using the one in info.dictParam, which is wrong. Fixes #51669 Change-Id: Ie13460c1e5751c4c5fc44479a44f6eed8b3b06e4 Reviewed-on: https://go-review.googlesource.com/c/go/+/391994 Trust: Cuong Manh Le Run-TryBot: Cuong Manh Le TryBot-Result: Gopher Robot Reviewed-by: Matthew Dempsky Trust: Matthew Dempsky Reviewed-by: Keith Randall Reviewed-on: https://go-review.googlesource.com/c/go/+/392614 --- src/cmd/compile/internal/noder/stencil.go | 2 +- test/typeparam/mdempsky/13b.go | 84 +++++++++++++++++++++++ 2 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 test/typeparam/mdempsky/13b.go diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index cd586cab78..c78a169d31 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -898,7 +898,7 @@ func getDictionaryType(info *instInfo, dictParam *ir.Name, pos src.XPos, i int) base.Fatalf(fmt.Sprintf("bad dict index %d", i)) } - r := getDictionaryEntry(pos, info.dictParam, i, info.dictInfo.startSubDict) + r := getDictionaryEntry(pos, dictParam, i, info.dictInfo.startSubDict) // change type of retrieved dictionary entry to *byte, which is the // standard typing of a *runtime._type in the compiler typed(types.Types[types.TUINT8].PtrTo(), r) diff --git a/test/typeparam/mdempsky/13b.go b/test/typeparam/mdempsky/13b.go new file mode 100644 index 0000000000..d152251d81 --- /dev/null +++ b/test/typeparam/mdempsky/13b.go @@ -0,0 +1,84 @@ +// run -gcflags="-G=3 -l" + +// 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 + +// Interface which will be used as a regular interface type and as a type bound. +type Mer interface{ + M() +} + +// Interface that is a superset of Mer. +type Mer2 interface { + M() + String() string +} + +func F[T Mer](t T) { + T.M(t) + t.M() +} + +type MyMer int + +func (MyMer) M() {} +func (MyMer) String() string { + return "aa" +} + +// Parameterized interface +type Abs[T any] interface { + Abs() T +} + +func G[T Abs[U], U any](t T) { + T.Abs(t) + t.Abs() +} + +type MyInt int +func (m MyInt) Abs() MyInt { + if m < 0 { + return -m + } + return m +} + +type Abs2 interface { + Abs() MyInt +} + + +func main() { + mm := MyMer(3) + ms := struct{ Mer }{Mer: mm } + + // Testing F with an interface type arg: Mer and Mer2 + F[Mer](mm) + F[Mer2](mm) + F[struct{ Mer }](ms) + F[*struct{ Mer }](&ms) + + ms2 := struct { MyMer }{MyMer: mm} + ms3 := struct { *MyMer }{MyMer: &mm} + + // Testing F with a concrete type arg + F[MyMer](mm) + F[*MyMer](&mm) + F[struct{ MyMer }](ms2) + F[struct{ *MyMer }](ms3) + F[*struct{ MyMer }](&ms2) + F[*struct{ *MyMer }](&ms3) + + // Testing G with a concrete type args + mi := MyInt(-3) + G[MyInt,MyInt](mi) + + // Interface Abs[MyInt] holding an mi. + intMi := Abs[MyInt](mi) + // First type arg here is Abs[MyInt], an interface type. + G[Abs[MyInt],MyInt](intMi) +} -- 2.50.0