p.markType(n.Type())
}
-// markType recursively visits types reachable from t to identify
-// functions whose inline bodies may be needed.
+// markType recursively visits types reachable from t to identify functions whose
+// inline bodies may be needed. For instantiated generic types, it visits the base
+// generic type, which has the relevant methods.
func (p *crawler) markType(t *types.Type) {
- if t.IsInstantiatedGeneric() {
- // Re-instantiated types don't add anything new, so don't follow them.
- return
+ if t.OrigSym() != nil {
+ // Convert to the base generic type.
+ t = t.OrigSym().Def.Type()
}
if p.marked[t] {
return
p.markType(t.Elem())
case types.TSTRUCT:
+ if t.IsFuncArgStruct() {
+ break
+ }
for _, f := range t.FieldSlice() {
if types.IsExported(f.Sym.Name) || f.Embedded != 0 {
p.markType(f.Type)
t = t.Elem()
}
- if t.IsInstantiatedGeneric() {
- // Re-instantiated types don't add anything new, so don't follow them.
- return
+ if t.OrigSym() != nil {
+ // Convert to the base generic type.
+ t = t.OrigSym().Def.Type()
}
if p.embedded[t] {
var doFlood func(n ir.Node)
doFlood = func(n ir.Node) {
+ t := n.Type()
+ if t != nil && (t.HasTParam() || t.IsFullyInstantiated()) {
+ // Ensure that we call markType() on any base generic type
+ // that is written to the export file (even if not explicitly
+ // marked for export), so we will call markInlBody on its
+ // methods, and the methods will be available for
+ // instantiation if needed.
+ p.markType(t)
+ }
switch n.Op() {
case ir.OMETHEXPR, ir.ODOTMETH:
p.markInlBody(ir.MethodExprName(n))
case ir.PEXTERN:
Export(n)
}
- p.checkGenericType(n.Type())
- case ir.OTYPE:
- p.checkGenericType(n.Type())
case ir.OMETHVALUE:
// Okay, because we don't yet inline indirect
// calls to method values.
// because after inlining they might be callable.
ir.VisitList(fn.Inl.Body, doFlood)
}
-
-// checkGenerictype ensures that we call markType() on any base generic type that
-// is written to the export file (even if not explicitly marked
-// for export), so its methods will be available for inlining if needed.
-func (p *crawler) checkGenericType(t *types.Type) {
- if t != nil && t.HasTParam() {
- if t.OrigSym() != nil {
- // Convert to the base generic type.
- t = t.OrigSym().Def.Type()
- }
- p.markType(t)
- }
-}
--- /dev/null
+// 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 a
+
+import (
+ "fmt"
+ "sync"
+)
+
+type WrapperWithLock[T any] interface {
+ PrintWithLock()
+}
+
+func NewWrapperWithLock[T any](value T) WrapperWithLock[T] {
+ return &wrapperWithLock[T]{
+ Object: value,
+ }
+}
+
+type wrapperWithLock[T any] struct {
+ Lock sync.Mutex
+ Object T
+}
+
+func (w *wrapperWithLock[T]) PrintWithLock() {
+ w.Lock.Lock()
+ defer w.Lock.Unlock()
+
+ fmt.Println(w.Object)
+}