Compare commits

...

4 Commits

Author SHA1 Message Date
xgopilot
be766727c1 feat(demo): add go1.23 build tag to unique demo
Added //go:build go1.23 constraint to the unique demo.
This allows Go's build system to automatically skip this demo
on Go versions older than 1.23, avoiding compilation errors
where the unique package doesn't exist.

This approach is cleaner than version checking in test scripts
and leverages Go's native build tag system.

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: cpunion <cpunion@users.noreply.github.com>
2025-10-18 01:12:56 +00:00
xgopilot
806449b019 feat(demo): add unique package demo from issue #1358
Added _demo/go/unique with code demonstrating unique.Make usage.
This demo showcases the fix for the compilation panic issue.

Note: The unique package requires full runtime support (weak pointers, etc.)
which is still under development. The test_demo.sh script should be
updated separately to skip this demo on Go 1.23 or earlier.

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: cpunion <cpunion@users.noreply.github.com>
2025-10-17 23:57:25 +00:00
xgopilot
051fa6abdf fix(cl): revert dependency upgrades, keep code fixes only
Reverted go.mod and go.sum to main branch versions as requested.
The fix for generic type compilation remains in cl/compile.go.

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: cpunion <cpunion@users.noreply.github.com>
2025-10-17 22:28:25 +00:00
xgopilot
86d13a5add fix(cl): skip compiling methods for generic type definitions
Fixes #1358

The compiler was attempting to compile methods for non-instantiated generic
types (like unique.Handle[T]), which caused the SSA builder to panic with a
nil pointer dereference. This fix adds two checks:

1. In compileType: Skip generic type definitions (types with type parameters
   but no type arguments)
2. In compileMethods: Skip types containing type parameters and skip methods
   from external packages

The unique.Make demo now compiles without panicking, though it still requires
runtime support for the unique package to link successfully.

Generated with [codeagent](https://github.com/qbox/codeagent)
Co-authored-by: cpunion <cpunion@users.noreply.github.com>
2025-10-17 22:15:18 +00:00
2 changed files with 88 additions and 0 deletions

40
_demo/go/unique/main.go Normal file
View File

@@ -0,0 +1,40 @@
//go:build go1.23
package main
import "unique"
func main() {
var h1 = unique.Make(int(42))
var h2 = unique.Make(int(42))
if h1 != h2 {
panic("h1 and h2 should be equal")
}
var v1 = h1.Value()
var v2 = h2.Value()
if v1 != v2 || v1 != 42 {
panic("values should be equal to 42")
}
var h3 = unique.Make("hello")
var h4 = unique.Make("hello")
if h3 != h4 {
panic("h3 and h4 should be equal")
}
var s1 = h3.Value()
var s2 = h4.Value()
if s1 != s2 || s1 != "hello" {
panic("values should be equal to 'hello'")
}
var h5 = unique.Make(int(100))
var h6 = unique.Make(int(200))
if h5 == h6 {
panic("h5 and h6 should not be equal")
}
var n1 = h5.Value()
var n2 = h6.Value()
if n1 != 100 || n2 != 200 {
panic("values should be 100 and 200 respectively")
}
}

View File

@@ -149,16 +149,64 @@ func (p *context) compileType(pkg llssa.Package, t *ssa.Type) {
if debugInstr {
log.Println("==> NewType", name, typ)
}
if named, ok := typ.(*types.Named); ok {
if tp := named.TypeParams(); tp != nil && tp.Len() > 0 {
if ta := named.TypeArgs(); ta == nil || ta.Len() == 0 {
return
}
}
}
p.compileMethods(pkg, typ)
p.compileMethods(pkg, types.NewPointer(typ))
}
func hasGenericTypeParam(typ types.Type) bool {
switch t := typ.(type) {
case *types.TypeParam:
return true
case *types.Named:
if tp := t.TypeParams(); tp != nil && tp.Len() > 0 {
if ta := t.TypeArgs(); ta == nil || ta.Len() == 0 {
return true
}
}
if ta := t.TypeArgs(); ta != nil {
for i := 0; i < ta.Len(); i++ {
if hasGenericTypeParam(ta.At(i)) {
return true
}
}
}
return hasGenericTypeParam(t.Underlying())
case *types.Pointer:
return hasGenericTypeParam(t.Elem())
}
return false
}
func (p *context) compileMethods(pkg llssa.Package, typ types.Type) {
if hasGenericTypeParam(typ) {
return
}
var typPkg *types.Package
if named, ok := typ.(*types.Named); ok {
typPkg = named.Obj().Pkg()
} else if ptr, ok := typ.(*types.Pointer); ok {
if named, ok := ptr.Elem().(*types.Named); ok {
typPkg = named.Obj().Pkg()
}
}
if typPkg != nil && typPkg != p.goTyps {
return
}
prog := p.goProg
mthds := prog.MethodSets.MethodSet(typ)
for i, n := 0, mthds.Len(); i < n; i++ {
mthd := mthds.At(i)
if ssaMthd := prog.MethodValue(mthd); ssaMthd != nil {
if ssaMthd.TypeParams() != nil || ssaMthd.TypeArgs() != nil {
continue
}
p.compileFuncDecl(pkg, ssaMthd)
}
}