From 79bf753c0e5963edd03cf2837e125f08823029f7 Mon Sep 17 00:00:00 2001 From: xgopilot Date: Thu, 30 Oct 2025 07:33:20 +0000 Subject: [PATCH] fix(ssa): use empty PkgPath for anonymous interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on meeting discussion, this commit reverts the previous approach of extracting PkgPath from interface methods. Instead, anonymous interfaces now use an empty PkgPath string, and the runtime's methods() function handles empty PkgPath by returning all methods. Changes: - Reverted unsafeInterface() to remove originType parameter - Set anonymous interface PkgPath to empty string in abitype.go:202 - Added early return in methods() in z_face.go for empty PkgPath - All call sites of unsafeInterface() updated to pass rawIntf directly This approach is cleaner because anonymous interfaces don't belong to any package, and the compiler already guarantees safety for cross-package private method access. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Co-authored-by: luoliwoshang <51194195+luoliwoshang@users.noreply.github.com> --- runtime/internal/runtime/z_face.go | 3 +++ ssa/abitype.go | 2 +- ssa/interface.go | 14 +++++++------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/runtime/internal/runtime/z_face.go b/runtime/internal/runtime/z_face.go index 84f82ce7..7312f544 100644 --- a/runtime/internal/runtime/z_face.go +++ b/runtime/internal/runtime/z_face.go @@ -396,6 +396,9 @@ func findMethod(mthds []abi.Method, im abi.Imethod) abi.Text { } func methods(u *abi.UncommonType, from string) []abi.Method { + if from == "" { + return u.Methods() + } if u.PkgPath_ == from { return u.Methods() } diff --git a/ssa/abitype.go b/ssa/abitype.go index 06ca0ba5..74ad84d9 100644 --- a/ssa/abitype.go +++ b/ssa/abitype.go @@ -199,7 +199,7 @@ func (b Builder) abiInterfaceOf(t *types.Interface) func() Expr { fn := pkg.rtFunc("Interface") tSlice := lastParamType(prog, fn) methodSlice := b.SliceLit(tSlice, methods...) - return b.Call(fn, b.Str(pkg.Path()), methodSlice) + return b.Call(fn, b.Str(""), methodSlice) } } diff --git a/ssa/interface.go b/ssa/interface.go index 71f4a79c..f6dce0d0 100644 --- a/ssa/interface.go +++ b/ssa/interface.go @@ -43,11 +43,11 @@ func (b Builder) newItab(tintf, typ Expr) Expr { return b.Call(b.Pkg.rtFunc("NewItab"), tintf, typ) } -func (b Builder) unsafeInterface(rawIntf *types.Interface, originType types.Type, t Expr, data llvm.Value) llvm.Value { +func (b Builder) unsafeInterface(rawIntf *types.Interface, t Expr, data llvm.Value) llvm.Value { if rawIntf.Empty() { return b.unsafeEface(t.impl, data) } - tintf := b.abiType(originType) + tintf := b.abiType(rawIntf) itab := b.newItab(tintf, t) return b.unsafeIface(itab.impl, data) } @@ -112,7 +112,7 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) { case abi.Indirect: vptr := b.AllocU(typ) b.Store(vptr, x) - return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, vptr.impl), tinter} + return Expr{b.unsafeInterface(rawIntf, tabi, vptr.impl), tinter} } ximpl := x.impl if lvl > 0 { @@ -121,7 +121,7 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) { var u llvm.Value switch kind { case abi.Pointer: - return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, ximpl), tinter} + return Expr{b.unsafeInterface(rawIntf, tabi, ximpl), tinter} case abi.Integer: tu := prog.Uintptr() u = llvm.CreateIntCast(b.impl, ximpl, tu.ll) @@ -136,7 +136,7 @@ func (b Builder) MakeInterface(tinter Type, x Expr) (ret Expr) { panic("todo") } data := llvm.CreateIntToPtr(b.impl, u, prog.tyVoidPtr()) - return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, data), tinter} + return Expr{b.unsafeInterface(rawIntf, tabi, data), tinter} } func (b Builder) valFromData(typ Type, data llvm.Value) Expr { @@ -250,7 +250,7 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr { if rawIntf, ok := assertedTyp.raw.Type.Underlying().(*types.Interface); ok { eq = b.InlineCall(b.Pkg.rtFunc("Implements"), tabi, tx) val = func() Expr { - return Expr{b.unsafeInterface(rawIntf, assertedTyp.raw.Type, tx, b.faceData(x.impl)), assertedTyp} + return Expr{b.unsafeInterface(rawIntf, tx, b.faceData(x.impl)), assertedTyp} } } else { eq = b.BinOp(token.EQL, tx, tabi) @@ -307,7 +307,7 @@ func (b Builder) ChangeInterface(typ Type, x Expr) (ret Expr) { rawIntf := typ.raw.Type.Underlying().(*types.Interface) tabi := b.faceAbiType(x) data := b.faceData(x.impl) - return Expr{b.unsafeInterface(rawIntf, typ.raw.Type, tabi, data), typ} + return Expr{b.unsafeInterface(rawIntf, tabi, data), typ} } // -----------------------------------------------------------------------------