Skip to content

Commit

Permalink
Merge pull request #340 from xushiwei/ov
Browse files Browse the repository at this point in the history
pkg.Instantiate: support OverloadNamed
  • Loading branch information
xushiwei authored Jan 21, 2024
2 parents 1d1b45f + 8926e9f commit bab2f84
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
8 changes: 8 additions & 0 deletions builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ func getConf() *Config {
return &Config{Fset: fset, Importer: imp}
}

func TestSetTypeParams(t *testing.T) {
pkg := types.NewPackage("", "")
tn := types.NewTypeName(0, pkg, "foo__1", nil)
named := types.NewNamed(tn, TyByte, nil)

setTypeParams(nil, named, &ast.TypeSpec{}, nil)
}

func TestOverloadNameds(t *testing.T) {
pkg := types.NewPackage("", "")
tn := types.NewTypeName(0, pkg, "foo__1", nil)
Expand Down
4 changes: 3 additions & 1 deletion type_var_and_const.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ func (p *TypeDecl) InitType(pkg *Package, typ types.Type, tparams ...*TypeParam)
} else {
p.typ.SetUnderlying(typ)
}
setTypeParams(pkg, p.typ, spec, tparams)
if tparams != nil {
setTypeParams(pkg, p.typ, spec, tparams)
}
spec.Type = toType(pkg, typ)
return p.typ
}
Expand Down
23 changes: 19 additions & 4 deletions typeparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -445,14 +445,29 @@ func interfaceIsImplicit(t *types.Interface) bool {

func (p *Package) Instantiate(orig types.Type, targs []types.Type, src ...ast.Node) types.Type {
p.cb.ensureLoaded(orig)
for _, targ := range targs {
p.cb.ensureLoaded(targ)
}
ctxt := p.cb.ctxt
if on, ok := orig.(*TyOverloadNamed); ok {
var first error
for _, t := range on.Types {
ret, err := types.Instantiate(ctxt, t, targs, true)
if err == nil {
return ret
}
if first == nil {
first = err
}
}
p.cb.handleCodeError(getPos(src), first.Error())
return types.Typ[types.Invalid]
}
if !isGenericType(orig) {
p.cb.handleCodeErrorf(getPos(src), "%v is not a generic type", orig)
return types.Typ[types.Invalid]
}
for _, targ := range targs {
p.cb.ensureLoaded(targ)
}
ret, err := types.Instantiate(p.cb.ctxt, orig, targs, true)
ret, err := types.Instantiate(ctxt, orig, targs, true)
if err != nil {
p.cb.handleCodeError(getPos(src), err.Error())
}
Expand Down
29 changes: 29 additions & 0 deletions typeparams_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@ func TestOverloadNamed(t *testing.T) {
const GopPackage = true
type M = map[string]any
type basetype interface {
string | int | bool | float64
}
type Var__0[T basetype] struct {
val T
}
type Var__1[T map[string]any] struct {
val T
}
`
gt := newGoxTest()
_, err := gt.LoadGoPackage("foo", "foo.go", src)
Expand All @@ -56,6 +62,29 @@ type Var__0[T basetype] struct {
if on.Types[0].TypeParams() == nil {
t.Fatal("TestOverloadNamed: not generic")
}

tyInt := types.Typ[types.Int]
tyM := pkgRef.Ref("M").Type()
ty1 := pkg.Instantiate(on, []types.Type{tyInt})
ty2 := pkg.Instantiate(on, []types.Type{tyM})
pkg.NewTypeDefs().NewType("t1").InitType(pkg, ty1)
pkg.NewTypeDefs().NewType("t2").InitType(pkg, ty2)

domTest(t, pkg, `package main
import "foo"
type t1 foo.Var__0[int]
type t2 foo.Var__1[map[string]any]
`)

defer func() {
if e := recover(); e == nil {
t.Fatal("TestOverloadNamed failed: no error?")
}
}()
ty3 := pkg.Instantiate(on, []types.Type{gox.TyByte})
pkg.NewTypeDefs().NewType("t3").InitType(pkg, ty3)
}

func TestInstantiate(t *testing.T) {
Expand Down

0 comments on commit bab2f84

Please sign in to comment.