fix: preserve Named interface type information through interface construction
This commit addresses the root cause identified in issue #1370 by preserving Named interface type information through the interface construction phase. **Root Cause:** Named interfaces were prematurely unwrapped via Underlying() in the interface construction phase (MakeInterface()/unsafeInterface()), causing the subsequent ABI type generation to hit `case *types.Interface:` instead of `case *types.Named:`, resulting in loss of package information. **The Fix:** 1. Modified `unsafeInterface()` to accept a `namedIntf types.Type` parameter 2. Updated all callers to pass the Named type (tinter.raw.Type, assertedTyp.raw.Type, etc.) 3. When namedIntf is available, pass it to `abiType()` to ensure proper routing through the type switch to `abiNamedInterfaceOf()` which has correct package context 4. Reverted the workaround logic in `abiInterfaceOf()` that extracted pkgPath from methods **Impact:** - Fixes segmentation faults when calling interface private methods across packages - Ensures runtime receives correct package path for interface metadata - Allows private method slots in itab to be properly filled 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -43,11 +43,16 @@ func (b Builder) newItab(tintf, typ Expr) Expr {
|
||||
return b.Call(b.Pkg.rtFunc("NewItab"), tintf, typ)
|
||||
}
|
||||
|
||||
func (b Builder) unsafeInterface(rawIntf *types.Interface, t Expr, data llvm.Value) llvm.Value {
|
||||
func (b Builder) unsafeInterface(rawIntf *types.Interface, namedIntf types.Type, t Expr, data llvm.Value) llvm.Value {
|
||||
if rawIntf.Empty() {
|
||||
return b.unsafeEface(t.impl, data)
|
||||
}
|
||||
tintf := b.abiType(rawIntf)
|
||||
var tintf Expr
|
||||
if namedIntf != nil {
|
||||
tintf = b.abiType(namedIntf)
|
||||
} else {
|
||||
tintf = b.abiType(rawIntf)
|
||||
}
|
||||
itab := b.newItab(tintf, t)
|
||||
return b.unsafeIface(itab.impl, data)
|
||||
}
|
||||
@@ -112,7 +117,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, tabi, vptr.impl), tinter}
|
||||
return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, vptr.impl), tinter}
|
||||
}
|
||||
ximpl := x.impl
|
||||
if lvl > 0 {
|
||||
@@ -121,7 +126,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, tabi, ximpl), tinter}
|
||||
return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, ximpl), tinter}
|
||||
case abi.Integer:
|
||||
tu := prog.Uintptr()
|
||||
u = llvm.CreateIntCast(b.impl, ximpl, tu.ll)
|
||||
@@ -136,7 +141,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, tabi, data), tinter}
|
||||
return Expr{b.unsafeInterface(rawIntf, tinter.raw.Type, tabi, data), tinter}
|
||||
}
|
||||
|
||||
func (b Builder) valFromData(typ Type, data llvm.Value) Expr {
|
||||
@@ -249,7 +254,9 @@ func (b Builder) TypeAssert(x Expr, assertedTyp Type, commaOk bool) Expr {
|
||||
} else {
|
||||
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, tx, b.faceData(x.impl)), assertedTyp} }
|
||||
val = func() Expr {
|
||||
return Expr{b.unsafeInterface(rawIntf, assertedTyp.raw.Type, tx, b.faceData(x.impl)), assertedTyp}
|
||||
}
|
||||
} else {
|
||||
eq = b.BinOp(token.EQL, tx, tabi)
|
||||
val = func() Expr { return b.valFromData(assertedTyp, b.faceData(x.impl)) }
|
||||
@@ -305,7 +312,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, tabi, data), typ}
|
||||
return Expr{b.unsafeInterface(rawIntf, typ.raw.Type, tabi, data), typ}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user