// type itab struct {
// inter *interfacetype
// _type *_type
- // hash uint32
+ // hash uint32 // copy of _type.hash. Used for type switches.
// _ [4]byte
- // fun [1]uintptr // variable sized
+ // fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
// }
o := objw.SymPtr(lsym, 0, writeType(iface), 0)
o = objw.SymPtr(lsym, o, writeType(typ), 0)
o = objw.Uint32(lsym, o, types.TypeHash(typ)) // copy of type hash
o += 4 // skip unused field
+ if !completeItab {
+ // If typ doesn't implement iface, make method entries be zero.
+ o = objw.Uintptr(lsym, o, 0)
+ entries = entries[:0]
+ }
for _, fn := range entries {
- if !completeItab {
- // If typ doesn't implement iface, make method entries be zero.
- o = objw.Uintptr(lsym, o, 0)
- } else {
- o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
- }
+ o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
}
// Nothing writes static itabs, so they are read only.
objw.Global(lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
--- /dev/null
+// run -gcflags=-G=3
+
+// Copyright 2022 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[B any](b B) {
+ if b1, ok := any(b).(interface{ m1() }); ok {
+ panic(1)
+ _ = b1.(B)
+ }
+ if b2, ok := any(b).(interface{ m2() }); ok {
+ panic(2)
+ _ = b2.(B)
+ }
+}
+
+type S struct{}
+
+func (S) m3() {}
+
+func main() {
+ f(S{})
+}
--- /dev/null
+// run -gcflags=-G=3
+
+// Copyright 2022 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
+
+type SomeInterface interface {
+ Whatever()
+}
+
+func X[T any]() T {
+ var m T
+
+ // for this example, this block should never run
+ if _, ok := any(m).(SomeInterface); ok {
+ var dst SomeInterface
+ _, _ = dst.(T)
+ return dst.(T)
+ }
+
+ return m
+}
+
+type holder struct{}
+
+func main() {
+ X[holder]()
+}