From b27c7e30dc5d222766057e62c16cb765b636d244 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Sat, 24 Jul 2021 14:11:27 -0700 Subject: [PATCH] [dev.typeparams] cmd/compile: fix HasShape, add dottype test HasShape needs a TINTER case. Add a test for x.(T) in various situations. Needs the fix above. Also remove ONEW unshapify case. It is ok for ONEW to have a shape type, as it will just be passed to mallocgc, or possibly used as a stack object type, both of which are ok. Change-Id: Ibddf8f5c8c254d32cb5ebcaca7dc94b4c00ab893 Reviewed-on: https://go-review.googlesource.com/c/go/+/337231 Trust: Keith Randall Trust: Dan Scales Run-TryBot: Keith Randall TryBot-Result: Go Bot Reviewed-by: Dan Scales --- src/cmd/compile/internal/noder/stencil.go | 6 -- src/cmd/compile/internal/types/type.go | 8 ++- test/typeparam/dottype.go | 81 +++++++++++++++++++++++ test/typeparam/dottype.out | 8 +++ 4 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 test/typeparam/dottype.go create mode 100644 test/typeparam/dottype.out diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index f1de1152c5..575b879762 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -1376,12 +1376,6 @@ func (subst *subster) node(n ir.Node) ir.Node { case ir.ODOTTYPE, ir.ODOTTYPE2: m.SetType(subst.unshapifyTyp(m.Type())) - case ir.ONEW: - // New needs to pass a concrete type to the runtime. - // Or maybe it doesn't? We could use a shape type. - // TODO: need to modify m.X? I don't think any downstream passes use it. - m.SetType(subst.unshapifyTyp(m.Type())) - case ir.OMETHEXPR: se := m.(*ir.SelectorExpr) se.X = ir.TypeNodeAt(se.X.Pos(), subst.unshapifyTyp(se.X.Type())) diff --git a/src/cmd/compile/internal/types/type.go b/src/cmd/compile/internal/types/type.go index e6ae0e7bc1..58ac4db95a 100644 --- a/src/cmd/compile/internal/types/type.go +++ b/src/cmd/compile/internal/types/type.go @@ -2189,7 +2189,13 @@ func (t *Type) HasShape1(visited map[*Type]bool) bool { } } } - // TODO: TINTER - check methods? + case TINTER: + for _, f := range t.Methods().Slice() { + if f.Type.HasShape1(visited) { + return true + } + } + return false } return false } diff --git a/test/typeparam/dottype.go b/test/typeparam/dottype.go new file mode 100644 index 0000000000..0131f64202 --- /dev/null +++ b/test/typeparam/dottype.go @@ -0,0 +1,81 @@ +// 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 + +func f[T any](x interface{}) T { + return x.(T) +} +func f2[T any](x interface{}) (T, bool) { + t, ok := x.(T) + return t, ok +} + +type I interface { + foo() +} + +type myint int + +func (myint) foo() { +} + +type myfloat float64 + +func (myfloat) foo() { +} + +func g[T I](x I) T { + return x.(T) +} +func g2[T I](x I) (T, bool) { + t, ok := x.(T) + return t, ok +} + +func h[T any](x interface{}) struct{a, b T} { + return x.(struct{a, b T}) +} + +func k[T any](x interface{}) interface { bar() T } { + return x.(interface{bar() T }) +} + +type mybar int +func (x mybar) bar() int { + return int(x) +} + + +func main() { + var i interface{} = int(3) + var j I = myint(3) + var x interface{} = float64(3) + var y I = myfloat(3) + + println(f[int](i)) + shouldpanic(func() { f[int](x) }) + println(f2[int](i)) + println(f2[int](x)) + + println(g[myint](j)) + shouldpanic(func() { g[myint](y) }) + println(g2[myint](j)) + println(g2[myint](y)) + + println(h[int](struct{a, b int}{3, 5}).a) + + println(k[int](mybar(3)).bar()) +} +func shouldpanic(x func()) { + defer func() { + e := recover() + if e == nil { + panic("didn't panic") + } + }() + x() +} diff --git a/test/typeparam/dottype.out b/test/typeparam/dottype.out new file mode 100644 index 0000000000..058c923a5c --- /dev/null +++ b/test/typeparam/dottype.out @@ -0,0 +1,8 @@ +3 +3 true +0 false +3 +3 true +0 false +3 +3 -- 2.48.1