p.doDecl(localpkg, name)
}
+ // SetConstraint can't be called if the constraint type is not yet complete.
+ // When type params are created in the 'P' case of (*importReader).obj(),
+ // the associated constraint type may not be complete due to recursion.
+ // Therefore, we defer calling SetConstraint there, and call it here instead
+ // after all types are complete.
+ for _, d := range p.later {
+ d.t.SetConstraint(d.constraint)
+ }
// record all referenced packages as imports
list := append(([]*types2.Package)(nil), pkgList[1:]...)
sort.Sort(byPath(list))
return localpkg, nil
}
+type setConstraintArgs struct {
+ t *types2.TypeParam
+ constraint types2.Type
+}
+
type iimporter struct {
exportVersion int64
ipath string
tparamIndex map[ident]*types2.TypeParam
interfaceList []*types2.Interface
+
+ // Arguments for calls to SetConstraint that are deferred due to recursive types
+ later []setConstraintArgs
}
func (p *iimporter) doDecl(pkg *types2.Package, name string) {
}
iface.MarkImplicit()
}
- t.SetConstraint(constraint)
+ // The constraint type may not be complete, if we
+ // are in the middle of a type recursion involving type
+ // constraints. So, we defer SetConstraint until we have
+ // completely set up all types in ImportData.
+ r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint})
case 'V':
typ := r.typ()
// declaration before recursing.
n := importtype(pos, sym)
t := n.Type()
+
+ // Because of recursion, we need to defer width calculations and
+ // instantiations on intermediate types until the top-level type is
+ // fully constructed. Note that we can have recursion via type
+ // constraints.
+ types.DeferCheckSize()
+ deferDoInst()
if tag == 'U' {
rparams := r.typeList()
t.SetRParams(rparams)
}
- // We also need to defer width calculations until
- // after the underlying type has been assigned.
- types.DeferCheckSize()
- deferDoInst()
underlying := r.typ()
t.SetUnderlying(underlying)
p.doDecl(localpkg, name)
}
+ // SetConstraint can't be called if the constraint type is not yet complete.
+ // When type params are created in the 'P' case of (*importReader).obj(),
+ // the associated constraint type may not be complete due to recursion.
+ // Therefore, we defer calling SetConstraint there, and call it here instead
+ // after all types are complete.
+ for _, d := range p.later {
+ d.t.SetConstraint(d.constraint)
+ }
+
for _, typ := range p.interfaceList {
typ.Complete()
}
return localpkg, nil
}
+type setConstraintArgs struct {
+ t *types.TypeParam
+ constraint types.Type
+}
+
type iimporter struct {
exportVersion int64
ipath string
fake fakeFileSet
interfaceList []*types.Interface
+
+ // Arguments for calls to SetConstraint that are deferred due to recursive types
+ later []setConstraintArgs
}
func (p *iimporter) doDecl(pkg *types.Package, name string) {
}
iface.MarkImplicit()
}
- t.SetConstraint(constraint)
+ // The constraint type may not be complete, if we
+ // are in the middle of a type recursion involving type
+ // constraints. So, we defer SetConstraint until we have
+ // completely set up all types in ImportData.
+ r.p.later = append(r.p.later, setConstraintArgs{t: t, constraint: constraint})
case 'V':
typ := r.typ()
--- /dev/null
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package a
+
+// Type I is the first basic test for the issue, which relates to a type that is recursive
+// via a type constraint. (In this test, I -> IConstraint -> MyStruct -> I.)
+type JsonRaw []byte
+
+type MyStruct struct {
+ x *I[JsonRaw]
+}
+
+type IConstraint interface {
+ JsonRaw | MyStruct
+}
+
+type I[T IConstraint] struct {
+}
+
+// The following types form an even more complex recursion (through two type
+// constraints), and model the actual types in the issue (#51219) more closely.
+// However, they don't reveal any new issue. But it seems useful to leave this
+// complex set of types in a test in case it might be broken by future changes.
+
+type Message struct {
+ Interaction *Interaction[JsonRaw] `json:"interaction,omitempty"`
+}
+
+type ResolvedDataConstraint interface {
+ User | Message
+}
+
+type Snowflake uint64
+
+type ResolvedData[T ResolvedDataConstraint] map[Snowflake]T
+
+type User struct {
+}
+
+type Resolved struct {
+ Users ResolvedData[User] `json:"users,omitempty"`
+}
+
+type resolvedInteractionWithOptions struct {
+ Resolved Resolved `json:"resolved,omitempty"`
+}
+
+type UserCommandInteractionData struct {
+ resolvedInteractionWithOptions
+}
+
+type InteractionDataConstraint interface {
+ JsonRaw | UserCommandInteractionData
+}
+
+type Interaction[DataT InteractionDataConstraint] struct {
+}
--- /dev/null
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package b
+
+import "a"
+
+type InteractionRequest[T a.InteractionDataConstraint] struct {
+ a.Interaction[T]
+}
--- /dev/null
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "a"
+ "b"
+ "fmt"
+)
+
+func main() {
+ var x a.I[a.JsonRaw]
+ var y b.InteractionRequest[a.JsonRaw]
+
+ fmt.Printf("%v %v\n", x, y)
+}
--- /dev/null
+// rundir -G=3
+
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package ignored