diff --git a/go/ssa/func.go b/go/ssa/func.go index 03eb86929e0..8fc089e5d18 100644 --- a/go/ssa/func.go +++ b/go/ssa/func.go @@ -414,7 +414,7 @@ func (f *Function) RelString(from *types.Package) string { // Package-level function? // Prefix with package name for cross-package references only. - if p := f.pkg(); p != nil && p != from { + if p := f.relPkg(); p != nil && p != from { return fmt.Sprintf("%s.%s", p.Path(), f.name) } @@ -442,9 +442,26 @@ func writeSignature(buf *bytes.Buffer, from *types.Package, name string, sig *ty types.WriteSignature(buf, sig, types.RelativeTo(from)) } -func (f *Function) pkg() *types.Package { - if f.Pkg != nil { - return f.Pkg.Pkg +// declaredPackage returns the package fn is declared in or nil if the +// function is not declared in a package. +func (fn *Function) declaredPackage() *Package { + switch { + case fn.Pkg != nil: + return fn.Pkg // non-generic function + // generics: + // case fn.Origin != nil: + // return fn.Origin.pkg // instance of a named generic function + case fn.parent != nil: + return fn.parent.declaredPackage() // instance of an anonymous [generic] function + default: + return nil // function is not declared in a package, e.g. a wrapper. + } +} + +// relPkg returns types.Package fn is printed in relationship to. +func (fn *Function) relPkg() *types.Package { + if p := fn.declaredPackage(); p != nil { + return p.Pkg } return nil } @@ -479,7 +496,7 @@ func WriteFunction(buf *bytes.Buffer, f *Function) { fmt.Fprintf(buf, "# Recover: %s\n", f.Recover) } - from := f.pkg() + from := f.relPkg() if f.FreeVars != nil { buf.WriteString("# Free variables:\n") diff --git a/go/ssa/print.go b/go/ssa/print.go index 5995f83af70..d0f3bbf7e11 100644 --- a/go/ssa/print.go +++ b/go/ssa/print.go @@ -28,7 +28,7 @@ import ( func relName(v Value, i Instruction) string { var from *types.Package if i != nil { - from = i.Parent().pkg() + from = i.Parent().relPkg() } switch v := v.(type) { case Member: // *Function or *Global @@ -66,12 +66,12 @@ func relString(m Member, from *types.Package) string { // It never appears in disassembly, which uses Value.Name(). func (v *Parameter) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("parameter %s : %s", v.Name(), relType(v.Type(), from)) } func (v *FreeVar) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("freevar %s : %s", v.Name(), relType(v.Type(), from)) } @@ -86,7 +86,7 @@ func (v *Alloc) String() string { if v.Heap { op = "new" } - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("%s %s (%s)", op, relType(deref(v.Type()), from), v.Comment) } @@ -160,7 +160,7 @@ func (v *UnOp) String() string { } func printConv(prefix string, v, x Value) string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("%s %s <- %s (%s)", prefix, relType(v.Type(), from), @@ -191,7 +191,7 @@ func (v *MakeClosure) String() string { } func (v *MakeSlice) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("make %s %s %s", relType(v.Type(), from), relName(v.Len, v), @@ -223,12 +223,12 @@ func (v *MakeMap) String() string { if v.Reserve != nil { res = relName(v.Reserve, v) } - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("make %s %s", relType(v.Type(), from), res) } func (v *MakeChan) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("make %s %s", relType(v.Type(), from), relName(v.Size, v)) } @@ -273,7 +273,7 @@ func (v *Next) String() string { } func (v *TypeAssert) String() string { - from := v.Parent().pkg() + from := v.Parent().relPkg() return fmt.Sprintf("typeassert%s %s.(%s)", commaOk(v.CommaOk), relName(v.X, v), relType(v.AssertedType, from)) } diff --git a/go/ssa/sanity.go b/go/ssa/sanity.go index 1d4e20f6a2d..6e65d760d78 100644 --- a/go/ssa/sanity.go +++ b/go/ssa/sanity.go @@ -409,8 +409,8 @@ func (s *sanity) checkFunction(fn *Function) bool { s.errorf("nil Prog") } - _ = fn.String() // must not crash - _ = fn.RelString(fn.pkg()) // must not crash + _ = fn.String() // must not crash + _ = fn.RelString(fn.relPkg()) // must not crash // All functions have a package, except delegates (which are // shared across packages, or duplicated as weak symbols in a