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